Merge: Copy to native
authorJean Privat <jean@pryen.org>
Thu, 14 May 2015 12:52:38 +0000 (08:52 -0400)
committerJean Privat <jean@pryen.org>
Thu, 14 May 2015 12:52:38 +0000 (08:52 -0400)
Added copy_to_native method in Text, also its optimized versions for subclasses

As a bonus (and because it simplified my task here), substrings now return FlatTexts only instead of simple Text.

The latter will permit the implementation of StringReader as BufferedReader later in an optimized way

Pull-Request: #1335
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
Reviewed-by: Jean Privat <jean@pryen.org>

lib/buffered_ropes.nit
lib/standard/ropes.nit
lib/standard/string.nit

index bbed4ea..1114264 100644 (file)
@@ -66,10 +66,10 @@ end
 #
 # Basically just returns `self` encapsulated in a `FlatString`.
 private class LeafSubstrings
-       super IndexedIterator[Text]
+       super IndexedIterator[FlatText]
 
        var leaf: Leaf
-       var str: String is noinit
+       var str: FlatString is noinit
        var avail = true
 
        init do
index 644e3dc..5ac6ee2 100644 (file)
@@ -157,6 +157,27 @@ private class Concat
                        return new Concat(left, r + s)
                end
        end
+
+       redef fun copy_to_native(dest, n, src_offset, dest_offset) do
+               var remlen = n
+               var subs = new RopeSubstrings.from(self, src_offset)
+               var st = src_offset - subs.pos
+               var off = dest_offset
+               while n > 0 do
+                       var it = subs.item
+                       if n > it.length then
+                               var cplen = it.length - st
+                               it.items.copy_to(dest, cplen, st, off)
+                               off += cplen
+                               n -= cplen
+                       else
+                               it.items.copy_to(dest, n, st, off)
+                               n = 0
+                       end
+                       subs.next
+                       st = 0
+               end
+       end
 end
 
 # Mutable `Rope`, optimized for concatenation operations
@@ -204,7 +225,7 @@ class RopeBuffer
        # mutable native string (`ns`)
        private var buf_size: Int is noinit
 
-       redef fun substrings: Iterator[String] do return new RopeBufSubstringIterator(self)
+       redef fun substrings do return new RopeBufSubstringIterator(self)
 
        # Builds an empty `RopeBuffer`
        init do
@@ -648,12 +669,12 @@ private class ReverseRopeSubstrings
 end
 
 private class RopeBufSubstringIterator
-       super Iterator[String]
+       super Iterator[FlatText]
 
        # Iterator on the substrings of the building string
-       var iter: Iterator[String]
+       var iter: Iterator[FlatText]
        # Makes a String out of the buffered part of the Ropebuffer
-       var nsstr: String
+       var nsstr: FlatString
        # Did we attain the buffered part ?
        var nsstr_done = false
 
@@ -682,7 +703,7 @@ end
 
 # Substrings of a Rope (i.e. Postfix iterator on leaves)
 private class RopeSubstrings
-       super IndexedIterator[String]
+       super IndexedIterator[FlatString]
 
        # Visit Stack
        var iter: RopeIterPiece is noinit
@@ -692,7 +713,7 @@ private class RopeSubstrings
        var max: Int is noinit
 
        # Current leaf
-       var str: String is noinit
+       var str: FlatString is noinit
 
        init(root: RopeString) is old_style_init do
                var r = new RopeIterPiece(root, true, false, null)
@@ -704,7 +725,7 @@ private class RopeSubstrings
                                rnod = rnod.left
                                r = new RopeIterPiece(rnod, true, false, r)
                        else
-                               str = rnod
+                               str = rnod.as(FlatString)
                                r.rdone = true
                                iter = r
                                break
@@ -729,7 +750,7 @@ private class RopeSubstrings
                                        r = new RopeIterPiece(rnod, true, false, r)
                                end
                        else
-                               str = rnod
+                               str = rnod.as(FlatString)
                                r.rdone = true
                                iter = r
                                self.pos = pos - off
@@ -753,7 +774,7 @@ private class RopeSubstrings
                        if not rnod isa Concat then
                                it.ldone = true
                                it.rdone = true
-                               str = rnod
+                               str = rnod.as(FlatString)
                                iter = it.as(not null)
                                break
                        end
index 5c9b2ef..5e57fa4 100644 (file)
@@ -60,7 +60,7 @@ abstract class Text
        fun substring(from: Int, count: Int): SELFTYPE is abstract
 
        # Iterates on the substrings of self if any
-       fun substrings: Iterator[Text] is abstract
+       fun substrings: Iterator[FlatText] is abstract
 
        # Is the current Text empty (== "")
        #
@@ -882,6 +882,27 @@ abstract class Text
                return s.to_s
        end
 
+       # Copies `n` bytes from `self` at `src_offset` into `dest` starting at `dest_offset`
+       #
+       # Basically a high-level synonym of NativeString::copy_to
+       #
+       # REQUIRE: `n` must be large enough to contain `len` bytes
+       #
+       #       var ns = new NativeString(8)
+       #       "Text is String".copy_to_native(ns, 8, 2, 0)
+       #       assert ns.to_s_with_length(8) == "xt is St"
+       #
+       fun copy_to_native(dest: NativeString, n, src_offset, dest_offset: Int) do
+               var mypos = src_offset
+               var itspos = dest_offset
+               while n > 0 do
+                       dest[itspos] = self.chars[mypos]
+                       itspos += 1
+                       mypos += 1
+                       n -= 1
+               end
+       end
+
 end
 
 # All kinds of array-based text representations.
@@ -926,6 +947,10 @@ abstract class FlatText
        end
 
        redef fun flatten do return self
+
+       redef fun copy_to_native(dest, n, src_offset, dest_offset) do
+               items.copy_to(dest, n, src_offset, dest_offset)
+       end
 end
 
 # Abstract class for the SequenceRead compatible
@@ -986,7 +1011,7 @@ abstract class String
        #     assert "helloworld".insert_at(" ", 5)     == "hello world"
        fun insert_at(s: String, pos: Int): SELFTYPE is abstract
 
-       redef fun substrings: Iterator[String] is abstract
+       redef fun substrings is abstract
 
        # Returns a reversed version of self
        #