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