d5a921f3c9494d98783b0e337c8e96490008ea63
[SXSI/XMLTree.git] / xml-tree-inc.hpp
1 #ifndef XML_TREE_INTERNAL__
2 #error "xml-tree-inc.hpp should not be included directly"
3 #endif
4
5 #ifndef XML_TREE_INC_HPP_
6 #define XML_TREE_INC_HPP_
7
8 #include <cstdio>
9
10 inline uint32_t xml_tree::size() const
11 {
12   return tag_seq_len / 2;
13 }
14
15 inline uint32_t xml_tree::num_tags() const
16 {
17   return tag_names->size();
18 }
19
20 inline uint32_t xml_tree::subtree_size(xml_tree::node_t x) const
21 {
22   return bp_subtree_size(this->par, x);
23 }
24
25 inline uint32_t
26 xml_tree::subtree_tags(xml_tree::node_t x, xml_tree::tag_t label) const
27 {
28   xml_tree::node_t y = bp_find_close(this->par, x);
29   if (y - x < 10) {
30     uint32_t count = 0;
31     for(xml_tree::node_t i = x; i < y; i++)
32       count += (tag(i) == label);
33     return count;
34   } else {
35     return tags->rank(label, y) - tags->rank(label, x);
36   };
37 }
38
39 inline bool xml_tree::is_leaf(xml_tree::node_t x) const
40 {
41   return !bp_inspect(this->par, x+1);
42 }
43
44 inline bool xml_tree::is_open(xml_tree::node_t x) const
45 {
46   return bp_inspect(this->par, x);
47 }
48
49 inline bool xml_tree::is_ancestor(xml_tree::node_t x,
50                                   xml_tree::node_t y) const
51 {
52   return bp_is_ancestor(this->par, x, y);
53 }
54
55 inline bool
56 xml_tree::is_right_descendant(xml_tree::node_t x,
57                               xml_tree::node_t y) const
58 {
59   return
60     (x > root())
61     && (y <= bp_parent_close(this->par, x))
62     && (y >= bp_find_close(this->par, x));
63 }
64
65 inline bool xml_tree::is_first_child(xml_tree::node_t x) const
66 {
67   return (x <= this->root()) || (bp_inspect(this->par, x - 1));
68 }
69
70 inline bool xml_tree::is_nil(xml_tree::node_t x) const
71 {
72   return (x == xml_tree::NIL);
73 }
74
75 inline xml_tree::tag_t xml_tree::tag(xml_tree::node_t x) const
76 {
77   if (bits_per_tag == 8)
78     return  (xml_tree::tag_t) (((unsigned char*) tag_seq)[x]);
79   else
80     return get_field(tag_seq, bits_per_tag, x);
81 }
82
83 inline xml_tree::node_t xml_tree::root() const
84 {
85   return xml_tree::ROOT;
86 }
87
88
89 inline xml_tree::node_t xml_tree::parent(xml_tree::node_t x) const
90 {
91   return bp_parent(this->par, x);
92 }
93
94 inline xml_tree::node_t xml_tree::first_child(node_t x) const
95 {
96   xml_tree::node_t result = bp_first_child(this->par, x);
97   return result;
98 }
99
100 inline xml_tree::node_t xml_tree::last_child(xml_tree::node_t x) const
101 {
102   if (is_leaf(x))
103     return  xml_tree::NIL;
104   else
105     return bp_find_open(this->par, bp_find_close(this->par, x) - 1);
106 }
107
108 inline xml_tree::node_t xml_tree::next_sibling(xml_tree::node_t x) const
109 {
110   xml_tree::node_t result = bp_next_sibling(this->par, x);
111   return result;
112 }
113
114 inline xml_tree::node_t xml_tree::prev_sibling(xml_tree::node_t x) const
115 {
116   return bp_prev_sibling(this->par, x);
117 }
118
119 inline xml_tree::node_t xml_tree::first_element(xml_tree::node_t x) const
120 {
121   xml_tree::node_t n = first_child(x);
122   if (is_nil(n)) return xml_tree::NIL;
123   switch (tag(n)) {
124   case xml_tree::ATTRIBUTE_OPEN_TAG_ID:
125     n = next_sibling(n);
126     if (is_nil(n) || tag(n) != xml_tree::PCDATA_OPEN_TAG_ID) return n;
127     //Fallthrough
128   case PCDATA_OPEN_TAG_ID:
129     n = n + 2;
130     return bp_inspect(this->par, n) ? n : xml_tree::NIL;
131   default:
132     return n;
133   };
134 }
135
136 inline xml_tree::node_t xml_tree::next_element(xml_tree::node_t x) const
137 {
138   x = next_sibling(x);
139   if (is_nil(x)) return x;
140   if (tag(x) == xml_tree::PCDATA_OPEN_TAG_ID){
141     xml_tree::node_t y = x + 2;
142     return bp_inspect(this->par, y) ? y : xml_tree::NIL;
143   } else
144     return x;
145 }
146
147 inline xml_tree::node_t xml_tree::tagged_next(node_t x, tag_t tag) const
148 {
149   return this->tags->select_next(tag, x);
150 }
151
152 inline xml_tree::node_t
153 xml_tree::tagged_descendant(xml_tree::node_t x,
154                             xml_tree::tag_t tag) const
155 {
156   xml_tree::node_t y = tagged_next(x, tag);
157   return is_nil(y) || !is_ancestor(x, y) ? xml_tree::NIL : y;
158 }
159
160 inline xml_tree::node_t
161 xml_tree::tagged_following_before(xml_tree::node_t x,
162                                   xml_tree::tag_t tag,
163                                   xml_tree::node_t limit) const
164 {
165   xml_tree::node_t close = bp_find_close(this->par, x);
166   xml_tree::node_t s = tagged_next(close, tag);
167   return (s < limit) ? s : xml_tree::NIL;
168 }
169
170
171 inline xml_tree::node_t xml_tree::tagged_child(xml_tree::node_t x,
172                                                xml_tree::tag_t t) const
173 {
174   xml_tree::node_t c = first_child(x);
175   xml_tree::node_t result;
176   if (is_nil(c) || tag(c) == t)
177     return c;
178   else
179     return tagged_sibling(c, t);
180 }
181
182 inline xml_tree::node_t xml_tree::tagged_sibling(xml_tree::node_t x,
183                                                  xml_tree::tag_t t) const
184 {
185   xml_tree::node_t sibling = next_sibling(x);
186   xml_tree::tag_t stag;
187   while (sibling  != xml_tree::NIL) {
188     stag = tag(sibling);
189     if (stag == t)
190       return  sibling;
191     sibling = next_sibling(sibling);
192   };
193   return sibling;
194 }
195
196 xml_tree::node_t xml_tree::closing(xml_tree::node_t x) const
197 {
198   return bp_find_close(this->par, x);
199 }
200
201
202 inline SXSI::TextCollection *xml_tree::get_text_collection() const
203 {
204   return text_collection;
205 }
206
207 inline xml_tree::node_t xml_tree::parent_node(int32_t d) const
208 {
209   return (xml_tree::node_t) text_positions->select1(d + 1);
210 }
211
212 inline SXSI::TextCollection::document_result
213 xml_tree::prefix(uchar const *s) const
214 {
215   return text_collection->Prefix(s);
216 }
217
218 inline SXSI::TextCollection::document_result
219 xml_tree::suffix(uchar const *s) const
220 {
221   return text_collection->Suffix(s);
222 }
223
224 inline SXSI::TextCollection::document_result
225 xml_tree::equals(uchar const *s) const
226 {
227   return text_collection->Equal(s);
228 }
229
230 inline SXSI::TextCollection::document_result
231 xml_tree::contains(uchar const *s) const
232 {
233   return text_collection->Contains(s);
234 }
235
236 inline SXSI::TextCollection::document_result
237 xml_tree::less_than(uchar const *s) const
238 {
239   return text_collection->LessThan(s);
240 }
241
242
243 #endif //XML_TREE_INC_HPP_