1 #ifndef XML_TREE_INTERNAL__
2 #error "xml-tree-inc.hpp should not be included directly"
5 #ifndef XML_TREE_INC_HPP_
6 #define XML_TREE_INC_HPP_
11 #define ASSERT_NODE(orig, res) do { \
12 if (res < -1 || res >= par->n|| (res != -1 && res < orig)) \
14 "Assertion failure: original node %i, result %i, line %i\n", \
15 orig, res, __LINE__); \
18 #define ASSERT_NODE(orig, res)
21 inline uint32_t xml_tree::size() const
23 return tag_seq_len / 2;
26 inline uint32_t xml_tree::num_tags() const
28 return tag_names->size();
31 inline uint32_t xml_tree::subtree_size(xml_tree::node_t x) const
33 return bp_subtree_size(this->par, x);
37 xml_tree::subtree_tags(xml_tree::node_t x, xml_tree::tag_t label) const
39 xml_tree::node_t y = bp_find_close(this->par, x);
42 for(xml_tree::node_t i = x; i < y; i++)
43 count += (tag(i) == label);
46 return tags->rank(label, y) - tags->rank(label, x);
50 inline bool xml_tree::is_leaf(xml_tree::node_t x) const
52 return !bp_inspect(this->par, x+1);
55 inline bool xml_tree::is_ancestor(xml_tree::node_t x,
56 xml_tree::node_t y) const
58 return bp_is_ancestor(this->par, x, y);
62 xml_tree::is_right_descendant(xml_tree::node_t x,
63 xml_tree::node_t y) const
67 && (y <= bp_parent_close(this->par, x))
68 && (y >= bp_find_close(this->par, x));
71 inline bool xml_tree::is_first_child(xml_tree::node_t x) const
73 return (x <= this->root()) || (bp_inspect(this->par, x - 1));
76 inline bool xml_tree::is_nil(xml_tree::node_t x) const
78 return (x == xml_tree::NIL);
81 inline xml_tree::tag_t xml_tree::tag(xml_tree::node_t x) const
83 if (bits_per_tag == 8)
84 return (xml_tree::tag_t) (((unsigned char*) tag_seq)[x]);
86 return get_field(tag_seq, bits_per_tag, x);
89 inline xml_tree::node_t xml_tree::root() const
91 return xml_tree::ROOT;
95 inline xml_tree::node_t xml_tree::parent(xml_tree::node_t x) const
97 return bp_parent(this->par, x);
100 inline xml_tree::node_t xml_tree::first_child(node_t x) const
102 xml_tree::node_t result = bp_first_child(this->par, x);
103 ASSERT_NODE(x, result);
107 inline xml_tree::node_t xml_tree::last_child(xml_tree::node_t x) const
110 return xml_tree::NIL;
112 return bp_find_open(this->par, bp_find_close(this->par, x) - 1);
115 inline xml_tree::node_t xml_tree::next_sibling(xml_tree::node_t x) const
117 xml_tree::node_t result = bp_next_sibling(this->par, x);
118 ASSERT_NODE(x, result);
122 inline xml_tree::node_t xml_tree::prev_sibling(xml_tree::node_t x) const
124 return bp_prev_sibling(this->par, x);
127 inline xml_tree::node_t xml_tree::first_element(xml_tree::node_t x) const
129 xml_tree::node_t n = first_child(x);
130 if (is_nil(n)) return xml_tree::NIL;
132 case xml_tree::ATTRIBUTE_OPEN_TAG_ID:
134 if (is_nil(n) || tag(n) != xml_tree::PCDATA_OPEN_TAG_ID) return n;
136 case PCDATA_OPEN_TAG_ID:
138 return bp_inspect(this->par, n) ? n : xml_tree::NIL;
144 inline xml_tree::node_t xml_tree::next_element(xml_tree::node_t x) const
147 if (is_nil(x)) return x;
148 if (tag(x) == xml_tree::PCDATA_OPEN_TAG_ID){
149 xml_tree::node_t y = x + 2;
150 return bp_inspect(this->par, y) ? y : xml_tree::NIL;
155 inline xml_tree::node_t xml_tree::tagged_next(node_t x, tag_t tag) const
157 return this->tags->select_next(tag, x);
160 inline xml_tree::node_t
161 xml_tree::tagged_descendant(xml_tree::node_t x,
162 xml_tree::tag_t tag) const
164 xml_tree::node_t y = tagged_next(x, tag);
165 return is_nil(y) || !is_ancestor(x, y) ? xml_tree::NIL : y;
168 inline xml_tree::node_t
169 xml_tree::tagged_following_before(xml_tree::node_t x,
171 xml_tree::node_t limit) const
173 xml_tree::node_t close = bp_find_close(this->par, x);
174 xml_tree::node_t s = tagged_next(close, tag);
175 return (s < limit) ? s : xml_tree::NIL;
179 inline xml_tree::node_t xml_tree::tagged_child(xml_tree::node_t x,
180 xml_tree::tag_t t) const
182 xml_tree::node_t c = first_child(x);
183 xml_tree::node_t result;
184 if (is_nil(c) || tag(c) == t)
187 return tagged_sibling(c, t);
188 /* ASSERT_NODE(x, result);
192 inline xml_tree::node_t xml_tree::tagged_sibling(xml_tree::node_t x,
193 xml_tree::tag_t t) const
195 xml_tree::node_t sibling = next_sibling(x);
196 xml_tree::tag_t stag;
197 while (sibling != xml_tree::NIL) {
200 ASSERT_NODE(x, sibling);
203 sibling = next_sibling(sibling);
205 ASSERT_NODE(x, sibling);
209 xml_tree::node_t xml_tree::closing(xml_tree::node_t x) const
211 return bp_find_close(this->par, x);
215 inline SXSI::TextCollection *xml_tree::get_text_collection() const
217 return text_collection;
220 inline xml_tree::node_t xml_tree::parent_node(int32_t d) const
222 return (xml_tree::node_t) text_positions->select1(d + 1);
225 inline SXSI::TextCollection::document_result
226 xml_tree::prefix(uchar const *s) const
228 return text_collection->Prefix(s);
231 inline SXSI::TextCollection::document_result
232 xml_tree::suffix(uchar const *s) const
234 return text_collection->Suffix(s);
237 inline SXSI::TextCollection::document_result
238 xml_tree::equals(uchar const *s) const
240 return text_collection->Equal(s);
243 inline SXSI::TextCollection::document_result
244 xml_tree::contains(uchar const *s) const
246 return text_collection->Contains(s);
249 inline SXSI::TextCollection::document_result
250 xml_tree::less_than(uchar const *s) const
252 return text_collection->LessThan(s);
256 #endif //XML_TREE_INC_HPP_