Fix a libcds bug:
[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 uint32_t xml_tree::subtree_elements(xml_tree::node_t x,
40                                            xml_tree::tag_t *atts) const
41 {
42
43   int32_t size = bp_subtree_size(par, x) - 1;
44   if (size <= 0) return 0;
45   size -= subtree_tags(x, xml_tree::PCDATA_OPEN_TAG_ID);
46   if (size < 3) return (uint32_t) size;
47   for(; *atts != xml_tree::NIL_TAG_ID; atts++)
48     size -= subtree_tags(x, *atts);
49   return (uint32_t) size;
50
51 }
52
53 inline bool xml_tree::is_leaf(xml_tree::node_t x) const
54 {
55   return !bp_inspect(this->par, x+1);
56 }
57
58 inline bool xml_tree::is_open(xml_tree::node_t x) const
59 {
60   return bp_inspect(this->par, x);
61 }
62
63 inline bool xml_tree::is_ancestor(xml_tree::node_t x,
64                                   xml_tree::node_t y) const
65 {
66   return bp_is_ancestor(this->par, x, y);
67 }
68
69 inline bool
70 xml_tree::is_right_descendant(xml_tree::node_t x,
71                               xml_tree::node_t y) const
72 {
73   return
74     (x > root())
75     && (y <= bp_parent_close(this->par, x))
76     && (y >= bp_find_close(this->par, x));
77 }
78
79 inline bool xml_tree::is_first_child(xml_tree::node_t x) const
80 {
81   return (x <= this->root()) || (bp_inspect(this->par, x - 1));
82 }
83
84 inline bool xml_tree::is_nil(xml_tree::node_t x) const
85 {
86   return (x == xml_tree::NIL);
87 }
88
89 inline xml_tree::tag_t xml_tree::tag(xml_tree::node_t x) const
90 {
91   if (bits_per_tag == 8)
92     return  (xml_tree::tag_t) (((unsigned char*) tag_seq)[x]);
93   else
94     return get_field(tag_seq, bits_per_tag, x);
95 }
96
97 inline xml_tree::node_t xml_tree::root() const
98 {
99   return xml_tree::ROOT;
100 }
101
102
103 inline xml_tree::node_t xml_tree::parent(xml_tree::node_t x) const
104 {
105   return bp_parent(this->par, x);
106 }
107
108 inline xml_tree::node_t xml_tree::first_child(node_t x) const
109 {
110   xml_tree::node_t result = bp_first_child(this->par, x);
111   return result;
112 }
113
114 inline xml_tree::node_t xml_tree::last_child(xml_tree::node_t x) const
115 {
116   if (is_leaf(x))
117     return  xml_tree::NIL;
118   else
119     return bp_find_open(this->par, bp_find_close(this->par, x) - 1);
120 }
121
122 inline xml_tree::node_t xml_tree::next_sibling(xml_tree::node_t x) const
123 {
124   xml_tree::node_t result = bp_next_sibling(this->par, x);
125   return result;
126 }
127
128 inline xml_tree::node_t xml_tree::prev_sibling(xml_tree::node_t x) const
129 {
130   return bp_prev_sibling(this->par, x);
131 }
132
133 inline xml_tree::node_t xml_tree::first_element(xml_tree::node_t x) const
134 {
135   xml_tree::node_t n = first_child(x);
136   if (is_nil(n)) return xml_tree::NIL;
137   switch (tag(n)) {
138   case xml_tree::ATTRIBUTE_OPEN_TAG_ID:
139     n = next_sibling(n);
140     if (is_nil(n) || tag(n) != xml_tree::PCDATA_OPEN_TAG_ID) return n;
141     //Fallthrough
142   case PCDATA_OPEN_TAG_ID:
143     n = n + 2;
144     return bp_inspect(this->par, n) ? n : xml_tree::NIL;
145   default:
146     return n;
147   };
148 }
149
150 inline xml_tree::node_t xml_tree::next_element(xml_tree::node_t x) const
151 {
152   x = next_sibling(x);
153   if (is_nil(x)) return x;
154   if (tag(x) == xml_tree::PCDATA_OPEN_TAG_ID){
155     xml_tree::node_t y = x + 2;
156     return bp_inspect(this->par, y) ? y : xml_tree::NIL;
157   } else
158     return x;
159 }
160
161 inline xml_tree::node_t xml_tree::tagged_next(node_t x, tag_t tag) const
162 {
163   return this->tags->select_next(tag, x);
164 }
165
166 inline xml_tree::node_t
167 xml_tree::tagged_descendant(xml_tree::node_t x,
168                             xml_tree::tag_t tag) const
169 {
170   xml_tree::node_t y = tagged_next(x, tag);
171   return is_nil(y) || !is_ancestor(x, y) ? xml_tree::NIL : y;
172 }
173
174 inline xml_tree::node_t
175 xml_tree::tagged_following_before(xml_tree::node_t x,
176                                   xml_tree::tag_t tag,
177                                   xml_tree::node_t limit) const
178 {
179   xml_tree::node_t close = bp_find_close(this->par, x);
180   xml_tree::node_t s = tagged_next(close, tag);
181   return (s < limit) ? s : xml_tree::NIL;
182 }
183
184
185 inline xml_tree::node_t xml_tree::tagged_child(xml_tree::node_t x,
186                                                xml_tree::tag_t t) const
187 {
188   xml_tree::node_t c = first_child(x);
189   xml_tree::node_t result;
190   if (is_nil(c) || tag(c) == t)
191     return c;
192   else
193     return tagged_sibling(c, t);
194 }
195
196 inline xml_tree::node_t xml_tree::tagged_sibling(xml_tree::node_t x,
197                                                  xml_tree::tag_t t) const
198 {
199   xml_tree::node_t sibling = next_sibling(x);
200   xml_tree::tag_t stag;
201   while (sibling  != xml_tree::NIL) {
202     stag = tag(sibling);
203     if (stag == t)
204       return  sibling;
205     sibling = next_sibling(sibling);
206   };
207   return sibling;
208 }
209
210 xml_tree::node_t xml_tree::closing(xml_tree::node_t x) const
211 {
212   return bp_find_close(this->par, x);
213 }
214
215
216 inline SXSI::TextCollection *xml_tree::get_text_collection() const
217 {
218   return text_collection;
219 }
220
221 inline xml_tree::node_t xml_tree::parent_node(int32_t d) const
222 {
223   xml_tree::node_t res = text_positions->select1(d+1);
224   return (xml_tree::node_t) res;
225 }
226
227 inline SXSI::TextCollection::document_result
228 xml_tree::prefix(uchar const *s) const
229 {
230   return text_collection->Prefix(s);
231 }
232
233 inline SXSI::TextCollection::document_result
234 xml_tree::suffix(uchar const *s) const
235 {
236   return text_collection->Suffix(s);
237 }
238
239 inline SXSI::TextCollection::document_result
240 xml_tree::equals(uchar const *s) const
241 {
242   return text_collection->Equal(s);
243 }
244
245 inline SXSI::TextCollection::document_result
246 xml_tree::contains(uchar const *s) const
247 {
248   return text_collection->Contains(s);
249 }
250
251 inline SXSI::TextCollection::document_result
252 xml_tree::less_than(uchar const *s) const
253 {
254   return text_collection->LessThan(s);
255 }
256
257
258 #endif //XML_TREE_INC_HPP_