5b42cd83b539 — Chris Cannam 7 years ago
Unicode-escape control chars on serialise
1 files changed, 23 insertions(+), 10 deletions(-)

M json.sml
M json.sml +23 -10
@@ 261,7 261,7 @@ structure Json :> JSON = struct
               | chkPos (c :: rest) = isDigit c andalso chkPosAfterFirst rest
                     
             fun chkNumber (#"-" :: rest) = chkPos rest
-              | chkNumber digits = chkPos digits
+              | chkNumber cc = chkPos cc
         in
             if chkNumber digits
             then case Real.fromString (implode digits) of

          
@@ 328,15 328,28 @@ structure Json :> JSON = struct
     fun stringEscape s =
         let fun esc x = [x, #"\\"]
             fun escape' acc [] = rev acc
-              | escape' acc (x :: xs) = escape' (case x of
-                                                     #"\"" => esc x @ acc
-                                                   | #"\\" => esc x @ acc
-                                                   | #"\b" => esc #"b" @ acc
-                                                   | #"\f" => esc #"f" @ acc
-                                                   | #"\n" => esc #"n" @ acc
-                                                   | #"\r" => esc #"r" @ acc
-                                                   | #"\t" => esc #"t" @ acc
-                                                   | _ => x :: acc) xs
+              | escape' acc (x :: xs) =
+                escape' (case x of
+                             #"\"" => esc x @ acc
+                           | #"\\" => esc x @ acc
+                           | #"\b" => esc #"b" @ acc
+                           | #"\f" => esc #"f" @ acc
+                           | #"\n" => esc #"n" @ acc
+                           | #"\r" => esc #"r" @ acc
+                           | #"\t" => esc #"t" @ acc
+                           | _ =>
+                             let val c = Char.ord x
+                             in
+                                 if c < 0x20
+                                 then let val hex = Word.toString (Word.fromInt c)
+                                      in (rev o explode) (if c < 0x10
+                                                          then ("\\u000" ^ hex)
+                                                          else ("\\u00" ^ hex))
+                                      end @ acc
+                                 else 
+                                     x :: acc
+                             end)
+                        xs
         in
             implode (escape' [] (explode s))
         end