lib/standard/ropes: Added an iterator on the substrings of a Rope.
authorLucas Bajolet <r4pass@hotmail.com>
Thu, 5 Jun 2014 14:29:42 +0000 (10:29 -0400)
committerLucas Bajolet <r4pass@hotmail.com>
Thu, 5 Jun 2014 18:17:07 +0000 (14:17 -0400)
Signed-off-by: Lucas Bajolet <r4pass@hotmail.com>

lib/standard/ropes.nit

index b76784f..9da5d60 100644 (file)
@@ -117,6 +117,12 @@ abstract class Rope
        # Iterator on the leaves of the rope, forward order
        private fun leaves(from: Int): LeavesIterator do return new LeavesIterator(self, from)
 
+       # Iterator on the substrings from 0, in forward order
+       fun substrings: IndexedIterator[Text] do return new SubstringsIterator(self, 0)
+
+       # Iterator on the substrings, starting at position `from`, in forward order
+       fun substrings_from(from: Int): IndexedIterator[Text] do return new SubstringsIterator(self, from)
+
        # Path to the Leaf for `position`
        private fun node_at(position: Int): Path
        do
@@ -420,3 +426,54 @@ class LeavesIterator
        end
 end
 
+# Uses the leaves and calculates a new substring on each iteration
+class SubstringsIterator
+       super IndexedIterator[Text]
+
+       private var nodes: IndexedIterator[Leaf]
+
+       # Current position in Rope
+       var pos: Int
+
+       # Current substring, computed from the current Leaf and indexes
+       var substring: Text
+
+       init(tgt: Rope, pos: Int)
+       do
+               nodes = tgt.leaves(pos)
+               self.pos = pos
+               if pos < 0 or pos >= tgt.length then return
+               make_substring
+       end
+
+       # Compute the bounds of the current substring and makes the substring
+       private fun make_substring
+       do
+               substring = nodes.item.str
+               var min = 0
+               var length = substring.length
+               if nodes.index < pos then
+                       min = pos - nodes.index
+               end
+               substring = substring.substring(min, length)
+       end
+
+       redef fun is_ok do return nodes.is_ok
+
+       redef fun item
+       do
+               assert is_ok
+               return substring
+       end
+
+       redef fun index do return pos
+
+       redef fun next
+       do
+               pos += substring.length
+               nodes.next
+               if nodes.is_ok then make_substring
+       end
+
+end
+