lib/core: Fix RopeBytes::[]
authorLucas Bajolet <r4pass@hotmail.com>
Tue, 3 May 2016 19:53:06 +0000 (15:53 -0400)
committerLucas Bajolet <r4pass@hotmail.com>
Tue, 3 May 2016 19:53:06 +0000 (15:53 -0400)
Signed-off-by: Lucas Bajolet <r4pass@hotmail.com>

lib/core/text/ropes.nit
tests/sav/test_rope_bytes.res [new file with mode: 0644]
tests/test_rope_bytes.nit [new file with mode: 0644]

index 10c1acf..f370e49 100644 (file)
@@ -670,7 +670,7 @@ private class RopeByteIterator
        var ns: NativeString is noautoinit
        # Substrings of the Rope
        var subs: IndexedIterator[FlatString] is noautoinit
-       # Maximum position to iterate on (e.g. Rope.length)
+       # Maximum position to iterate on (e.g. Rope.bytelen)
        var max: Int is noautoinit
        # Position (char) in the Rope (0-indexed)
        var pos: Int is noautoinit
@@ -680,7 +680,7 @@ private class RopeByteIterator
                pns = pos - subs.index
                self.pos = pos
                ns = subs.item._items
-               max = root.length - 1
+               max = root.bytelen - 1
        end
 
        redef fun item do return ns[pns]
@@ -984,18 +984,45 @@ private class RopeBytes
 
        redef type SELFTYPE: Concat
 
+       var cache: FlatString is noinit
+
+       var cache_start: Int = -1
+
+       var cache_end: Int = -1
+
        redef fun [](i) do
-               var nod: String = target
+               assert i >= 0 and i < target._bytelen
+               var flps = _cache_start
+               if i >= flps and i <= _cache_end then
+                       return _cache.bytes[i - flps]
+               end
+               var lf = get_leaf_at(i)
+               return lf.bytes[i - _cache_start]
+       end
+
+       fun get_leaf_at(pos: Int): FlatString do
+               var flps = _cache_start
+               if pos >= flps and pos <= _cache_end then
+                       return _cache
+               end
+               var s: String = target
+               var st = pos
                loop
-                       if nod isa FlatString then return nod._items[i]
-                       if not nod isa Concat then abort
-                       var lft = nod._left
-                       if lft.bytelen >= i then
-                               nod = nod._right
+                       if s isa FlatString then break
+                       s = s.as(Concat)
+                       var lft = s._left
+                       var llen = lft.bytelen
+                       if pos >= llen then
+                               s = s._right
+                               pos -= llen
                        else
-                               nod = lft
+                               s = lft
                        end
                end
+               _cache_start = st - pos
+               _cache_end = st - pos + s.bytelen - 1
+               _cache = s
+               return s
        end
 
        redef fun iterator_from(i) do return new RopeByteIterator.from(target, i)
diff --git a/tests/sav/test_rope_bytes.res b/tests/sav/test_rope_bytes.res
new file mode 100644 (file)
index 0000000..a61d3e4
--- /dev/null
@@ -0,0 +1,2 @@
+à1111111111111111111111111111111111111111éć2222222222222222222222222222222222222222ç
+0xc3 0xa0 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0x31 0xc3 0xa9 0xc4 0x87 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0xc3 0xa7
diff --git a/tests/test_rope_bytes.nit b/tests/test_rope_bytes.nit
new file mode 100644 (file)
index 0000000..4685f18
--- /dev/null
@@ -0,0 +1,29 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+intrude import core::text::ropes
+import core
+
+var lft = "à" + "1" * 40 + "é"
+var rht = "ć" + "2" * 40 + "ç"
+
+var rp = new Concat(lft, rht)
+
+print rp
+
+var bts = rp.bytes.to_a
+
+assert bts.length == 88
+
+print bts.join(" ")