Implement CachedText
[SXSI/xpathcomp.git] / tree.ml
diff --git a/tree.ml b/tree.ml
index 2218c28..16b32a3 100644 (file)
--- a/tree.ml
+++ b/tree.ml
@@ -39,6 +39,12 @@ sig
   val contains_old : t -> string -> bool
   val dump : t -> unit
   val get_string : t -> string_content -> string
+  val has_tagged_desc : t -> Tag.t -> bool
+  val has_tagged_foll : t -> Tag.t -> bool
+  val tagged_desc : t -> Tag.t -> t
+  val tagged_foll : t -> Tag.t -> t
+  val tagged_next : t -> Tag.t -> t
+  val subtree_tags : t -> Tag.t -> int
 end
 
 module XML = 
@@ -71,14 +77,21 @@ struct
     let nil = nullt ()
     external get_text : t -> [`Text] node -> string = "caml_text_collection_get_text"
 
-    let get_text t n = 
+(*    let get_text t n = 
       if equal nil n then "" 
       else  get_text t n
+*)
                
     external is_empty : t -> [`Text ] node -> bool = "caml_text_collection_empty_text"
     let is_empty t n =
       (equal nil n) || is_empty t n
 
+    external get_cached_text : t -> [`Text ] node -> string = "caml_text_collection_get_cached_text"
+      
+    let get_text t n =
+      if (equal nil n) || is_empty t n then ""
+      else get_cached_text t n
+
     external is_contains : t -> string -> bool = "caml_text_collection_is_contains"
     external count_contains : t -> string -> int = "caml_text_collection_count_contains"
     external contains : t -> string -> [`Text ] node array = "caml_text_collection_contains"
@@ -122,6 +135,10 @@ struct
     external text_xml_id : t -> [`Text ] node -> int = "caml_xml_tree_text_xml_id"
     external node_xml_id : t -> [`Tree ] node -> int = "caml_xml_tree_node_xml_id"
     external is_ancestor : t -> [`Tree ] node -> [`Tree ] node -> bool = "caml_xml_tree_is_ancestor"
+    external tagged_desc : t -> [`Tree ] node -> Tag.t -> [`Tree ] node = "caml_xml_tree_tagged_desc"
+    external tagged_foll : t -> [`Tree ] node -> Tag.t -> [`Tree ] node = "caml_xml_tree_tagged_foll"
+    external tagged_next : t -> [`Tree ] node -> Tag.t -> [`Tree ] node = "caml_xml_tree_tagged_next"
+    external subtree_tags : t -> [`Tree ] node -> Tag.t -> int = "caml_xml_tree_subtree_tags"
 
     let print_skel t =
       let rec aux id = 
@@ -189,6 +206,7 @@ struct
                        
     end
     let is_node = function { node=Node(_) } -> true | _ -> false
+      
     let get_string t (i:string_content) = Text.get_text t.doc i
     open Tree                 
     let node_of_t t = { doc= t; 
@@ -317,7 +335,47 @@ struct
          | Node(SC(i,_)) -> Text.equal i id
          | _ -> false
 
-             
+
+    let tagged_foll t tag =
+      if tag = Tag.attribute || tag = Tag.pcdata then failwith "tagged_foll"
+      else match t with
+       | { doc=d; node=Node(NC n) } -> { t with node = norm (tagged_foll d n tag) }
+       | { doc=d; node=Node(SC (_,n)) } when is_nil n -> { t with node= Nil } 
+       | { doc=d; node=Node(SC (_,n)) } ->
+           let nnode = 
+             if tag_id d n == tag then n
+             else 
+               let n' = tagged_desc d n tag in
+                 if is_nil n' then tagged_foll d n tag
+                 else n'
+           in {t with node= norm nnode}
+       | _ -> { t with node=Nil }
+           
+
+    let tagged_desc t tag =
+      if tag = Tag.attribute || tag = Tag.pcdata then failwith "tagged_desc"
+      else match t with
+       | { doc=d; node=Node(NC n) } -> { t with node = norm (tagged_desc d n tag) }
+       | _ -> { t with node=Nil }
+
+
+    let tagged_next t tag =
+      if tag = Tag.attribute || tag = Tag.pcdata then failwith "tagged_next"
+      else match t with
+       | { doc=d; node=Node(NC n) } -> { t with node = norm (tagged_next d n tag) }
+       | { doc=d; node=Node(SC (_,n)) } -> { t with node = norm (tagged_next d n tag) }
+       | _ -> { t with node=Nil }
+
+    let subtree_tags t tag =
+      match t with 
+         { doc = d; node = Node(NC n) } -> subtree_tags d n tag
+       | _ -> 0
+
+
+
+    let has_tagged_foll t tag = is_node (tagged_foll t tag)
+    let has_tagged_desc t tag = is_node (tagged_desc t tag)
+
     let contains t s = 
       Array.fold_left (fun a i -> DocIdSet.add i a) DocIdSet.empty (Text.contains t.doc s)