X-Git-Url: http://nitlanguage.org diff --git a/lib/core/text/ropes.nit b/lib/core/text/ropes.nit index 10c1acf..f57b33d 100644 --- a/lib/core/text/ropes.nit +++ b/lib/core/text/ropes.nit @@ -221,23 +221,16 @@ private class Concat end redef fun copy_to_native(dest, n, src_offset, dest_offset) do - 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 + var l = _left + if src_offset < l.bytelen then + var lcopy = l.bytelen - src_offset + lcopy = if lcopy > n then n else lcopy + l.copy_to_native(dest, lcopy, src_offset, dest_offset) + dest_offset += lcopy + n -= lcopy + src_offset = 0 end + _right.copy_to_native(dest, n, src_offset, dest_offset) end # Returns a balanced version of `self` @@ -670,7 +663,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 +673,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] @@ -828,7 +821,7 @@ private class ReverseRopeSubstrings redef fun next do if pos < 0 then return var curr = iter.prev - var currit = curr.node + var currit = curr.as(not null).node while curr != null do currit = curr.node if not currit isa Concat then @@ -935,14 +928,14 @@ private class RopeSubstrings redef fun next do pos += str.length if pos > max then return - var it = iter.prev + var it = iter.prev.as(not null) var rnod = it.node loop if not rnod isa Concat then it.ldone = true it.rdone = true str = rnod.as(FlatString) - iter = it.as(not null) + iter = it break end if not it.ldone then @@ -954,7 +947,7 @@ private class RopeSubstrings rnod = rnod._right it = new RopeCharIteratorPiece(rnod, false, false, it) else - it = it.prev + it = it.prev.as(not null) rnod = it.node continue end @@ -984,18 +977,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)