docker full: install missing package for SDL2 mixer
[nit.git] / lib / json / serialization_write.nit
index e26236c..eeb30ff 100644 (file)
@@ -69,6 +69,8 @@ class JsonSerializer
        # Used only when `plain_json == true`.
        private var first_attribute = false
 
+       redef var current_object = null
+
        redef fun serialize(object)
        do
                if object == null then
@@ -88,8 +90,11 @@ class JsonSerializer
                        end
 
                        first_attribute = true
+                       var last_object = current_object
+                       current_object = object
                        object.accept_json_serializer self
                        first_attribute = false
+                       current_object = last_object
 
                        if plain_json then open_objects.pop
                end
@@ -99,8 +104,8 @@ class JsonSerializer
        do
                if not plain_json or not first_attribute then
                        stream.write ","
-                       first_attribute = false
                end
+               first_attribute = false
 
                new_line_and_indent
                stream.write "\""
@@ -144,26 +149,49 @@ redef class Text
        redef fun accept_json_serializer(v)
        do
                v.stream.write "\""
+
+               var start_i = 0
+               var escaped = null
                for i in [0 .. self.length[ do
                        var char = self[i]
                        if char == '\\' then
-                               v.stream.write "\\\\"
+                               escaped = "\\\\"
                        else if char == '\"' then
-                               v.stream.write "\\\""
+                               escaped = "\\\""
                        else if char < ' ' then
                                if char == '\n' then
-                                       v.stream.write "\\n"
+                                       escaped = "\\n"
                                else if char == '\r' then
-                                       v.stream.write "\\r"
+                                       escaped = "\\r"
                                else if char == '\t' then
-                                       v.stream.write "\\t"
+                                       escaped = "\\t"
                                else
-                                       v.stream.write char.escape_to_utf16
+                                       escaped = char.escape_to_utf16
                                end
+                       end
+
+                       if escaped != null then
+                               # Write open non-escaped string
+                               if start_i <= i then
+                                       v.stream.write substring(start_i, i-start_i)
+                               end
+
+                               # Write escaped character
+                               v.stream.write escaped
+                               escaped = null
+                               start_i = i+1
+                       end
+               end
+
+               # Write remaining non-escaped string
+               if start_i < length then
+                       if start_i == 0 then
+                               v.stream.write self
                        else
-                               v.stream.write char.to_s
+                               v.stream.write substring(start_i, length-start_i)
                        end
                end
+
                v.stream.write "\""
        end
 end
@@ -225,7 +253,7 @@ redef class Serializable
                        v.stream.write class_name
                        v.stream.write "\""
                end
-               core_serialize_to(v)
+               v.serialize_core(self)
 
                v.indent_level -= 1
                v.new_line_and_indent
@@ -258,7 +286,7 @@ redef class Char
        end
 end
 
-redef class NativeString
+redef class CString
        redef fun accept_json_serializer(v) do to_s.accept_json_serializer(v)
 end
 
@@ -279,6 +307,7 @@ redef class Collection[E]
                        if not v.try_to_serialize(e) then
                                assert e != null # null would have been serialized
                                v.warn("element of type {e.class_name} is not serializable.")
+                               v.stream.write "null"
                        end
                end
                v.stream.write "]"
@@ -301,12 +330,12 @@ redef class SimpleCollection[E]
                        v.stream.write """","""
                        v.new_line_and_indent
                        v.stream.write """"__items": """
-
+                       serialize_to_pure_json v
                        core_serialize_to v
+               else
+                       serialize_to_pure_json v
                end
 
-               serialize_to_pure_json v
-
                if not v.plain_json then
                        v.indent_level -= 1
                        v.new_line_and_indent