inline TaggedChild/TaggedFollowingSibling
[SXSI/XMLTree.git] / XMLTree.h
index 93999a6..95ec450 100644 (file)
--- a/XMLTree.h
+++ b/XMLTree.h
@@ -109,6 +109,10 @@ static inline int fast_inspect(bp* Par,treeNode i)
   return (Par->B[j] >> (D-1-l)) & 1;\r
 }\r
 \r
+static bool fast_isleaf(bp* Par,treeNode x){\r
+  return (fast_inspect(Par, x+1) == CP);\r
+}\r
+\r
 static treeNode fast_first_child(bp *Par, treeNode x)\r
 {\r
   x = x+1;\r
@@ -228,6 +232,11 @@ public:
           return TagName->size();\r
    }\r
 \r
+   int TagsBinaryLength(){ return tags_blen; };\r
+   unsigned int TagStructLength(){ return uint_len(tags_blen,tags_len); };\r
+   unsigned int * TagStruct() { return tags_fix; };\r
+\r
+\r
    /** SubtreeSize(x): the number of nodes (and attributes) in the subtree of \r
     * node x. */\r
    int SubtreeSize(treeNode x);\r
@@ -311,13 +320,12 @@ public:
     * NULLT if there is none. Because of the balanced-parentheses representation \r
     * of the tree, this operation is not supported efficiently, just iterating \r
     * among the children of node x until finding the desired child. */\r
-   treeNode TaggedChild(treeNode x, TagType tag);\r
+\r
    \r
    treeNode SelectChild(treeNode x, TagIdSet * tags);\r
 \r
    /** TaggedFollowingSibling(x,tag): returns the first sibling of node x tagged tag, or \r
     *  NULLT if there is none. */\r
-   treeNode TaggedFollowingSibling(treeNode x, TagType tag);\r
    \r
    treeNode SelectFollowingSibling(treeNode x, TagIdSet * tags);\r
 \r
@@ -340,7 +348,7 @@ public:
 \r
    treeNode SelectFollowingBelow(treeNode x, TagIdSet * tags, treeNode ancestor);\r
 \r
-   treeNode TaggedFollowingBefore(treeNode x, TagType tag,treeNode closing);\r
+   //   treeNode TaggedFollowingBefore(treeNode x, TagType tag,treeNode closing);\r
 \r
    treeNode SelectFollowingBefore(treeNode x, TagIdSet * tags, treeNode closing);\r
 \r
@@ -530,7 +538,10 @@ public:
    inline TagType Tag(treeNode x) const throw () {\r
          if (tags_blen == 8)\r
                  return  (TagType) (((uchar*)tags_fix)[(int) x]);\r
-         else { \r
+         else \r
+                 return get_field(tags_fix, tags_blen, x);\r
+                 /*\r
+                 { \r
          size_t idxlen = x * tags_blen;\r
          size_t j = idxlen % W;\r
          size_t i = idxlen / W; \r
@@ -540,7 +551,7 @@ public:
          return (offset2 >= 0)\r
                  ? ( w << offset2 ) >> offset\r
                  : ( w >> j) | (tags_fix[i+1] << (W+offset2)) >> offset;\r
-         }; \r
+                 }; */\r
 \r
   }\r
 \r
@@ -615,7 +626,7 @@ public:
          return (fast_is_ancestor(Par,x,y) ? y : NULLT);\r
   };\r
   \r
-  inline treeNode TaggedFollowingBelow(treeNode x, TagType tag,treeNode ancestor)\r
+  inline treeNode TaggedFollowingBelow(treeNode x, TagType tag, treeNode ancestor)\r
   {\r
          treeNode close = fast_find_close(Par, x);\r
          treeNode s = tagpos2node(Tags->select_next(tag, close));\r
@@ -623,11 +634,45 @@ public:
          if (ancestor == Root() || s == NULLT || s < fast_find_close(Par,ancestor)) return s;\r
          else return NULLT;\r
   };\r
+\r
+  inline treeNode TaggedFollowingBefore(treeNode x, TagType tag, treeNode ancestor_closing)\r
+  {\r
+         treeNode close = fast_find_close(Par, x);\r
+         treeNode s = tagpos2node(Tags->select_next(tag, close));\r
+         \r
+         if (ancestor_closing == Root() || s == NULLT || s < ancestor_closing) return s;\r
+         else return NULLT;\r
+  };\r
     \r
+// TaggedSibling(x,tag): returns the first sibling of node x tagged tag, or NULLT if there is none.\r
+treeNode TaggedFollowingSibling(treeNode x, TagType tag)\r
+{\r
+  NULLT_IF(x==NULLT);\r
+  treeNode sibling = x;\r
+  TagType ctag;\r
+  while ((sibling = fast_next_sibling(Par, sibling)) != NULLT) {\r
+    ctag = Tag(sibling);\r
+    if (ctag == tag) return sibling; \r
+  }\r
+  return NULLT; \r
 };\r
 \r
+treeNode TaggedChild(treeNode x, TagType tag) \r
+{\r
+   \r
+   NULLT_IF(x==NULLT || fast_isleaf(Par,x));\r
+   treeNode child;   \r
+   child = fast_first_child(Par, x);\r
+\r
+   if (Tag(child) == tag)\r
+     return child;\r
+   else\r
+     return TaggedFollowingSibling(child, tag);\r
+};\r
 \r
 \r
+};\r
+\r
 \r
 #endif\r
 \r