lib/string: escape_to_c transforms `"\t"` to `"\\t"`
[nit.git] / lib / standard / string.nit
index b99fc99..db43964 100644 (file)
@@ -538,6 +538,8 @@ abstract class Text
                        var c = chars[i]
                        if c == '\n' then
                                b.append("\\n")
+                       else if c == '\t' then
+                               b.append("\\t")
                        else if c == '\0' then
                                b.append("\\0")
                        else if c == '"' then
@@ -1180,10 +1182,14 @@ class FlatString
        #              String Specific Methods           #
        ##################################################
 
-       private init with_infos(items: NativeString, len: Int, from: Int, to: Int)
+       # Low-level creation of a new string with given data.
+       #
+       # `items` will be used as is, without copy, to retrieve the characters of the string.
+       # Aliasing issues is the responsibility of the caller.
+       private init with_infos(items: NativeString, length: Int, from: Int, to: Int)
        do
                self.items = items
-               length = len
+               self.length = length
                index_from = from
                index_to = to
        end
@@ -1627,6 +1633,20 @@ class FlatBuffer
        # Create a new empty string.
        init do end
 
+       # Low-level creation a new buffer with given data.
+       #
+       # `items` will be used as is, without copy, to store the characters of the buffer.
+       # Aliasing issues is the responsibility of the caller.
+       #
+       # If `items` is shared, `written` should be set to true after the creation
+       # so that a modification will do a copy-on-write.
+       private init with_infos(items: NativeString, capacity, length: Int)
+       do
+               self.items = items
+               self.length = length
+               self.capacity = capacity
+       end
+
        # Create a new string copied from `s`.
        init from(s: Text)
        do
@@ -1651,7 +1671,6 @@ class FlatBuffer
        init with_capacity(cap: Int)
        do
                assert cap >= 0
-               # _items = new NativeString.calloc(cap)
                items = new NativeString(cap+1)
                capacity = cap
                length = 0
@@ -1695,11 +1714,10 @@ class FlatBuffer
                if from < 0 then from = 0
                if count > length then count = length
                if from < count then
-                       var r = new FlatBuffer.with_capacity(count - from)
-                       while from < count do
-                               r.chars.push(items[from])
-                               from += 1
-                       end
+                       var len = count - from
+                       var r_items = new NativeString(len)
+                       items.copy_to(r_items, len, from, 0)
+                       var r = new FlatBuffer.with_infos(r_items, len, len)
                        return r
                else
                        return new FlatBuffer
@@ -1937,6 +1955,10 @@ redef class Int
        #     assert 1.to_s            == "1"
        #     assert (-123).to_s       == "-123"
        redef fun to_s do
+               # Fast case for common numbers
+               if self == 0 then return "0"
+               if self == 1 then return "1"
+
                var nslen = int_to_s_len
                var ns = new NativeString(nslen + 1)
                ns[nslen] = '\0'
@@ -2164,6 +2186,48 @@ redef class Array[E]
        end
 end
 
+redef class NativeArray[E]
+       # Join all the elements using `to_s`
+       #
+       # REQUIRE: `self isa NativeArray[String]`
+       # REQUIRE: all elements are initialized
+       fun native_to_s: String
+       do
+               assert self isa NativeArray[String]
+               var l = length
+               var na = self
+               var i = 0
+               var sl = 0
+               var mypos = 0
+               while i < l do
+                       sl += na[i].length
+                       i += 1
+                       mypos += 1
+               end
+               var ns = new NativeString(sl + 1)
+               ns[sl] = '\0'
+               i = 0
+               var off = 0
+               while i < mypos do
+                       var tmp = na[i]
+                       var tpl = tmp.length
+                       if tmp isa FlatString then
+                               tmp.items.copy_to(ns, tpl, tmp.index_from, off)
+                               off += tpl
+                       else
+                               for j in tmp.substrings do
+                                       var s = j.as(FlatString)
+                                       var slen = s.length
+                                       s.items.copy_to(ns, slen, s.index_from, off)
+                                       off += slen
+                               end
+                       end
+                       i += 1
+               end
+               return ns.to_s_with_length(sl)
+       end
+end
+
 redef class Map[K,V]
        # Concatenate couple of 'key value'.
        # key and value are separated by `couple_sep`.