+ var b = new Buffer
+ for c in escape_to_c do
+ if chars.has(c) then
+ b.add('\\')
+ end
+ b.add(c)
+ end
+ return b.to_s
+ end
+
+ # Escape to c plus braces
+ #
+ # assert "\n\"'\\\{\}".escape_to_nit == "\\n\\\"\\'\\\\\\\{\\\}"
+ fun escape_to_nit: String do return escape_more_to_c("\{\}")
+
+ # Return a string where Nit escape sequences are transformed.
+ #
+ # Example:
+ # var s = "\\n"
+ # assert s.length == 2
+ # var u = s.unescape_nit
+ # assert u.length == 1
+ # assert u[0].ascii == 10 # (the ASCII value of the "new line" character)
+ fun unescape_nit: String
+ do
+ var res = new Buffer.with_capacity(self.length)
+ var was_slash = false
+ for c in self do
+ if not was_slash then
+ if c == '\\' then
+ was_slash = true
+ else
+ res.add(c)
+ end
+ continue
+ end
+ was_slash = false
+ if c == 'n' then
+ res.add('\n')
+ else if c == 'r' then
+ res.add('\r')
+ else if c == 't' then
+ res.add('\t')
+ else if c == '0' then
+ res.add('\0')
+ else
+ res.add(c)
+ end
+ end
+ return res.to_s
+ end
+end
+
+# Abstract class for the SequenceRead compatible
+# views on String and Buffer objects
+abstract class StringCharView
+ super SequenceRead[Char]
+
+ type SELFTYPE: AbstractString
+
+ private var target: SELFTYPE
+
+ private init(tgt: SELFTYPE)
+ do
+ target = tgt
+ end
+
+ redef fun is_empty do return target.is_empty
+
+ redef fun length do return target.length
+
+ redef fun iterator: IndexedIterator[Char] do return self.iterator_from(0)
+
+ fun iterator_from(pos: Int): IndexedIterator[Char] is abstract
+
+ redef fun has(c: Char): Bool
+ do
+ for i in self do
+ if i == c then return true
+ end
+ return false
+ end
+
+end
+
+# View on Buffer objects, extends Sequence
+# for mutation operations
+abstract class BufferCharView
+ super StringCharView
+ super Sequence[Char]
+
+ redef type SELFTYPE: Buffer
+
+end
+
+# Immutable strings of characters.
+class String
+ super Comparable
+ super AbstractString
+ super StringCapable
+
+ redef type OTHER: String
+
+ # Index in _items of the start of the string
+ readable var _index_from: Int
+
+ # Indes in _items of the last item of the string
+ readable var _index_to: Int
+
+ redef var chars: StringCharView = new FlatStringCharView(self)
+
+ ################################################
+ # AbstractString specific methods #
+ ################################################
+
+ redef fun [](index) do
+ assert index >= 0
+ # Check that the index (+ index_from) is not larger than indexTo
+ # In other terms, if the index is valid
+ assert (index + _index_from) <= _index_to
+ return _items[index + _index_from]
+ end
+
+ redef fun substring(from: Int, count: Int): String
+ do
+ assert count >= 0
+
+ if from < 0 then
+ count += from
+ if count < 0 then count = 0
+ from = 0
+ end
+
+ var realFrom = _index_from + from
+
+ if (realFrom + count) > _index_to then return new String.with_infos(_items, _index_to - realFrom + 1, realFrom, _index_to)
+
+ if count == 0 then return ""
+
+ var to = realFrom + count - 1
+
+ return new String.with_infos(_items, to - realFrom + 1, realFrom, to)
+ end
+
+ redef fun substring_from(from: Int): String
+ do
+ if from > _length then return ""
+ if from < 0 then from = 0
+ return substring(from, _length)
+ end
+
+ redef fun has_substring(str: String, pos: Int): Bool
+ do
+ var itsindex = str._length - 1
+