Huge refactoring to remove diego' C/C++ chimera code.
[SXSI/XMLTree.git] / xml-tree-inc.hpp
diff --git a/xml-tree-inc.hpp b/xml-tree-inc.hpp
new file mode 100644 (file)
index 0000000..6ce1724
--- /dev/null
@@ -0,0 +1,225 @@
+#ifndef XML_TREE_INTERNAL__
+#error "xml-tree-inc.hpp should not be included directly"
+#endif
+
+#ifndef XML_TREE_INC_HPP_
+#define XML_TREE_INC_HPP_
+
+inline uint32_t xml_tree::size() const
+{
+  return tag_seq_len / 2;
+}
+
+inline uint32_t xml_tree::num_tags() const
+{
+  return tag_names->size();
+}
+
+inline uint32_t xml_tree::subtree_size(xml_tree::node_t x) const
+{
+  return bp_subtree_size(this->par, x);
+}
+
+inline uint32_t
+xml_tree::subtree_tags(xml_tree::node_t x, xml_tree::tag_t label) const
+{
+  xml_tree::node_t y = bp_find_close(this->par, x);
+  if (y - x < 10) {
+    uint32_t count = 0;
+    for(xml_tree::node_t i = x; i < y; i++)
+      count += (tag(i) == label);
+    return count;
+  } else {
+    return tags->rank(label, y) - tags->rank(label, x);
+  };
+}
+
+inline bool xml_tree::is_leaf(xml_tree::node_t x) const
+{
+  return !bp_inspect(this->par, x+1);
+}
+
+inline bool xml_tree::is_ancestor(xml_tree::node_t x,
+                                  xml_tree::node_t y) const
+{
+  return bp_is_ancestor(this->par, x, y);
+}
+
+inline bool
+xml_tree::is_right_descendant(xml_tree::node_t x,
+                              xml_tree::node_t y) const
+{
+  return
+    (x > root())
+    && (y <= bp_parent_close(this->par, x))
+    && (y >= bp_find_close(this->par, x));
+}
+
+inline bool xml_tree::is_first_child(xml_tree::node_t x) const
+{
+  return (x <= this->root()) || (bp_inspect(this->par, x - 1));
+}
+
+inline bool xml_tree::is_nil(xml_tree::node_t x) const
+{
+  return (x == xml_tree::NIL);
+}
+
+inline xml_tree::tag_t xml_tree::tag(xml_tree::node_t x) const
+{
+  if (bits_per_tag == 8)
+    return  (xml_tree::tag_t) (((unsigned char*) tag_seq)[x]);
+  else
+    return get_field(tag_seq, bits_per_tag, x);
+}
+
+inline xml_tree::node_t xml_tree::root() const
+{
+  return xml_tree::ROOT;
+}
+
+
+inline xml_tree::node_t xml_tree::parent(xml_tree::node_t x) const
+{
+  return bp_parent(this->par, x);
+}
+
+inline xml_tree::node_t xml_tree::first_child(node_t x) const
+{
+  return bp_first_child(this->par, x);
+}
+
+inline xml_tree::node_t xml_tree::last_child(xml_tree::node_t x) const
+{
+  if (is_leaf(x))
+    return  xml_tree::NIL;
+  else
+    return bp_find_open(this->par, bp_find_close(this->par, x) - 1);
+}
+
+inline xml_tree::node_t xml_tree::next_sibling(xml_tree::node_t x) const
+{
+  return bp_next_sibling(this->par, x);
+}
+
+inline xml_tree::node_t xml_tree::prev_sibling(xml_tree::node_t x) const
+{
+  return bp_prev_sibling(this->par, x);
+}
+
+inline xml_tree::node_t xml_tree::first_element(xml_tree::node_t x) const
+{
+  xml_tree::node_t n = first_child(x);
+  if (is_nil(n)) return xml_tree::NIL;
+  switch (tag(n)) {
+  case xml_tree::ATTRIBUTE_OPEN_TAG_ID:
+    n = next_sibling(n);
+    if (is_nil(n) || tag(n) != xml_tree::PCDATA_OPEN_TAG_ID) return n;
+    //Fallthrough
+  case PCDATA_OPEN_TAG_ID:
+    n = n + 2;
+    return bp_inspect(this->par, n) ? n : xml_tree::NIL;
+  };
+}
+
+inline xml_tree::node_t xml_tree::next_element(xml_tree::node_t x) const
+{
+  x = next_sibling(x);
+  if (is_nil(x)) return x;
+  if (tag(x) == xml_tree::PCDATA_OPEN_TAG_ID){
+    xml_tree::node_t y = x + 2;
+    return bp_inspect(this->par, y) ? y : xml_tree::NIL;
+  } else
+    return x;
+}
+
+inline xml_tree::node_t xml_tree::tagged_next(node_t x, tag_t tag) const
+{
+  return this->tags->select_next(tag, x);
+}
+
+inline xml_tree::node_t
+xml_tree::tagged_descendant(xml_tree::node_t x,
+                            xml_tree::tag_t tag) const
+{
+  xml_tree::node_t y = tagged_next(x, tag);
+  return is_nil(y) || !is_ancestor(x, y) ? xml_tree::NIL : y;
+}
+
+inline xml_tree::node_t
+xml_tree::tagged_following_before(xml_tree::node_t x,
+                                  xml_tree::tag_t tag,
+                                  xml_tree::node_t limit) const
+{
+  xml_tree::node_t close = bp_find_close(this->par, x);
+  xml_tree::node_t s = tagged_next(close, tag);
+  return (s < limit) ? s : xml_tree::NIL;
+}
+
+
+inline xml_tree::node_t xml_tree::tagged_child(xml_tree::node_t x,
+                                               xml_tree::tag_t t) const
+{
+  xml_tree::node_t c = first_child(x);
+  if (is_nil(c) || tag(c) == t)
+    return c;
+  else
+    tagged_sibling(c, t);
+}
+
+inline xml_tree::node_t xml_tree::tagged_sibling(xml_tree::node_t x,
+                                                 xml_tree::tag_t t) const
+{
+  xml_tree::node_t sibling = next_sibling(x);
+  while(!is_nil(sibling) && tag(sibling) != t) sibling = next_sibling(sibling);
+  return sibling;
+}
+
+xml_tree::node_t xml_tree::closing(xml_tree::node_t x) const
+{
+  return bp_find_close(this->par, x);
+}
+
+
+inline SXSI::TextCollection *xml_tree::get_text_collection() const
+{
+  return text_collection;
+}
+
+inline xml_tree::node_t xml_tree::parent_node(int32_t d) const
+{
+  return (xml_tree::node_t) text_positions->select1(d + 1);
+}
+
+inline SXSI::TextCollection::document_result
+xml_tree::prefix(uchar const *s) const
+{
+  return text_collection->Prefix(s);
+}
+
+inline SXSI::TextCollection::document_result
+xml_tree::suffix(uchar const *s) const
+{
+  return text_collection->Suffix(s);
+}
+
+inline SXSI::TextCollection::document_result
+xml_tree::equals(uchar const *s) const
+{
+  return text_collection->Equal(s);
+}
+
+inline SXSI::TextCollection::document_result
+xml_tree::contains(uchar const *s) const
+{
+  return text_collection->Contains(s);
+}
+
+inline SXSI::TextCollection::document_result
+xml_tree::less_than(uchar const *s) const
+{
+  return text_collection->LessThan(s);
+}
+
+
+#endif //XML_TREE_INC_HPP_