Merge: Stringify Bytes
[nit.git] / lib / core / bytes.nit
index 439a621..af5b61b 100644 (file)
@@ -288,6 +288,21 @@ class Bytes
                length += 1
        end
 
+       # Adds the UTF-8 representation of `c` to `self`
+       #
+       #     var b = new Bytes.empty
+       #     b.add_char('A')
+       #     b.add_char('キ')
+       #     assert b.hexdigest == "41E382AD"
+       fun add_char(c: Char) do
+               if persisted then regen
+               var cln = c.u8char_len
+               var ln = length
+               enlarge(ln + cln)
+               items.set_char_at(length, c)
+               length += cln
+       end
+
        #     var b = new Bytes.empty
        #     b.append([104u8, 101u8, 108u8, 108u8, 111u8])
        #     assert b.to_s == "hello"
@@ -596,6 +611,57 @@ redef class Text
                end
                return new FlatString.with_infos(outns, ln * 2, 0, ln * 2 - 1)
        end
+
+       # Return a `Bytes` instance where Nit escape sequences are transformed.
+       #
+       #     assert "B\\n\\x41\\u0103D3".unescape_to_bytes.hexdigest == "420A41F0908F93"
+       fun unescape_to_bytes: Bytes do
+               var res = new Bytes.with_capacity(self.bytelen)
+               var was_slash = false
+               var i = 0
+               while i < length do
+                       var c = chars[i]
+                       if not was_slash then
+                               if c == '\\' then
+                                       was_slash = true
+                               else
+                                       res.add_char(c)
+                               end
+                               i += 1
+                               continue
+                       end
+                       was_slash = false
+                       if c == 'n' then
+                               res.add_char('\n')
+                       else if c == 'r' then
+                               res.add_char('\r')
+                       else if c == 't' then
+                               res.add_char('\t')
+                       else if c == '0' then
+                               res.add_char('\0')
+                       else if c == 'x' or c == 'X' then
+                               var hx = substring(i + 1, 2)
+                               if hx.is_hex then
+                                       res.add(hx.to_hex.to_b)
+                               else
+                                       res.add_char(c)
+                               end
+                               i += 2
+                       else if c == 'u' or c == 'U' then
+                               var hx = substring(i + 1, 6)
+                               if hx.is_hex then
+                                       res.add_char(hx.to_hex.code_point)
+                               else
+                                       res.add_char(c)
+                               end
+                               i += 6
+                       else
+                               res.add_char(c)
+                       end
+                       i += 1
+               end
+               return res
+       end
 end
 
 redef class FlatText
@@ -606,11 +672,23 @@ redef class FlatText
 end
 
 redef class NativeString
-       # Creates a new `Bytes` object from `self` with `strlen` as length
-       fun to_bytes: Bytes do
-               var len = cstring_length
+       # Creates a new `Bytes` object from `self` with `len` as length
+       #
+       # If `len` is null, strlen will determine the length of the Bytes
+       fun to_bytes(len: nullable Int): Bytes do
+               if len == null then len = cstring_length
                return new Bytes(self, len, len)
        end
+
+       # Creates a new `Bytes` object from a copy of `self` with `len` as length
+       #
+       # If `len` is null, strlen will determine the length of the Bytes
+       fun to_bytes_with_copy(len: nullable Int): Bytes do
+               if len == null then len = cstring_length
+               var nns = new NativeString(len)
+               copy_to(nns, len, 0, 0)
+               return new Bytes(nns, len, len)
+       end
 end
 
 # Joins an array of bytes `arr` separated by `sep`