redef fun +(o) do
var s = o.to_s
- var mlen = length
var slen = s.length
if s isa Concat then
return new Concat(self, s)
str = ""
length = 0
rpos = 0
+ dumped = 0
+ if written then
+ ns = new NativeString(buf_size)
+ written = false
+ end
end
redef fun substring(from, count) do
var slen = s.length
length += slen
var rp = rpos
- if s isa Rope then
- if rp > 0 and dumped != rp then
- str += new FlatString.with_infos(ns, rp - dumped, dumped, rp - 1)
- dumped = rp
- end
- str = str + s
- return
- end
- if slen > maxlen then
+ if s isa Rope or slen > maxlen then
if rp > 0 and dumped != rp then
str += new FlatString.with_infos(ns, rp - dumped, dumped, rp - 1)
dumped = rp
return
end
if slen <= remsp then
- sits.copy_to(ns, slen, begin, rp)
- if rp == buf_size then
- rpos = buf_size
+ if remsp <= 0 then
dump_buffer
rpos = 0
else
+ sits.copy_to(ns, slen, begin, rp)
rpos += slen
end
else
redef fun add(c) do
var rp = rpos
- length += 1
- ns[rp] = c
- rp += 1
- if rp == buf_size then
- rpos = rp
+ if rp >= buf_size then
dump_buffer
rp = 0
end
+ ns[rp] = c
+ rp += 1
+ length += 1
rpos = rp
end
end
redef fun reverse do
- str = str.reversed
- var nns = new NativeString(buf_size)
- var j = rpos
- var mits = ns
- for i in [0 .. rpos[ do
- nns[i] = mits[j]
- j -= 1
+ # Flush the buffer in order to only have to reverse `str`.
+ if rpos > 0 and dumped != rpos then
+ str += new FlatString.with_infos(ns, rpos - dumped, dumped, rpos - 1)
+ dumped = rpos
end
- ns = nns
+ str = str.reversed
end
redef fun upper do
redef fun next do
if pos < 0 then return
- var curr: nullable RopeIterPiece = iter.prev
+ var curr = iter.prev
var currit = curr.node
while curr != null do
currit = curr.node
pos += str.length
if pos > max then return
var it = iter.prev
- var rnod: String = it.node
+ var rnod = it.node
loop
if not rnod isa Concat then
it.ldone = true
end
+# An Iterator over a RopeBuffer.
class RopeBufferIter
super IndexedIterator[Char]
+ # Subiterator.
var sit: IndexedIterator[Char]
+ # Native string iterated over.
var ns: NativeString
+ # Current position in `ns`.
var pns: Int
+ # Maximum position iterable.
var maxpos: Int
redef var index: Int
+ # Init the iterator from a RopeBuffer.
init(t: RopeBuffer) is old_style_init do
ns = t.ns
maxpos = t.rpos
index = 0
end
+ # Init the iterator from a RopeBuffer starting from `pos`.
init from(t: RopeBuffer, pos: Int) do
ns = t.ns
maxpos = t.length
end
end
+# Reverse iterator over a RopeBuffer.
class RopeBufferReviter
super IndexedIterator[Char]
+ # Subiterator.
var sit: IndexedIterator[Char]
+ # Native string iterated over.
var ns: NativeString
+ # Current position in `ns`.
var pns: Int
redef var index: Int
+ # Init the iterator from a RopeBuffer.
init(tgt: RopeBuffer) is old_style_init do
sit = tgt.str.chars.reverse_iterator
pns = tgt.rpos - 1
ns = tgt.ns
end
+ # Init the iterator from a RopeBuffer starting from `pos`.
init from(tgt: RopeBuffer, pos: Int) do
sit = tgt.str.chars.reverse_iterator_from(pos - tgt.rpos - tgt.dumped)
pns = pos - tgt.str.length