diff --git a/basis/json/reader/reader-tests.factor b/basis/json/reader/reader-tests.factor index 430be777bcb..dcd45f18766 100644 --- a/basis/json/reader/reader-tests.factor +++ b/basis/json/reader/reader-tests.factor @@ -64,3 +64,10 @@ IN: json.reader.tests ! empty objects are allowed as values in objects { H{ { "foo" H{ } } } } [ "{ \"foo\" : {}}" json> ] unit-test + +{ + "\0\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\e\x1c\x1d\x1e\x1f" +} [ + "\"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f\"" + json> +] unit-test diff --git a/basis/json/reader/reader.factor b/basis/json/reader/reader.factor index 4990bc16abc..84e1359a79c 100644 --- a/basis/json/reader/reader.factor +++ b/basis/json/reader/reader.factor @@ -11,15 +11,18 @@ IN: json.reader number ] dip ; DEFER: j-string% : j-escape% ( stream -- ) dup stream-read1 { - { CHAR: b [ 8 ] } - { CHAR: f [ 12 ] } + { CHAR: " [ CHAR: " ] } + { CHAR: \\ [ CHAR: \\ ] } + { CHAR: / [ CHAR: / ] } + { CHAR: b [ CHAR: \b ] } + { CHAR: f [ CHAR: \f ] } { CHAR: n [ CHAR: \n ] } { CHAR: r [ CHAR: \r ] } { CHAR: t [ CHAR: \t ] } diff --git a/basis/json/writer/writer-tests.factor b/basis/json/writer/writer-tests.factor index 0ddf77474a9..6a3c2a6dfeb 100644 --- a/basis/json/writer/writer-tests.factor +++ b/basis/json/writer/writer-tests.factor @@ -11,7 +11,7 @@ IN: json.writer.tests { "102.5" } [ 102.5 >json ] unit-test { "[1,\"two\",3.0]" } [ { 1 "two" 3.0 } >json ] unit-test -{ """{"US$":1.0,"EU€":1.5}""" } [ H{ { "US$" 1.0 } { "EU€" 1.5 } } >json ] unit-test +{ """{"US$":1.0,"EU\\u20ac\":1.5}""" } [ H{ { "US$" 1.0 } { "EU€" 1.5 } } >json ] unit-test ! Random symbols are written simply as strings SYMBOL: testSymbol @@ -61,3 +61,10 @@ TUPLE: person name age a-a ; { """{"NaN":1}""" } [ H{ { NAN: 333 1 } } >json ] unit-test + +{ + "\"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f\"" +} [ + "\0\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\e\x1c\x1d\x1e\x1f" + >json +] unit-test diff --git a/basis/json/writer/writer.factor b/basis/json/writer/writer.factor index 7218cca1b80..10ba9f3c653 100644 --- a/basis/json/writer/writer.factor +++ b/basis/json/writer/writer.factor @@ -1,8 +1,8 @@ ! Copyright (C) 2006 Chris Double. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel io.streams.string io strings splitting -sequences math math.parser assocs classes words namespaces make -prettyprint hashtables mirrors tr json fry combinators ; +USING: accessors ascii assocs combinators fry hashtables io +io.streams.string json kernel math math.parser mirrors +namespaces sequences strings tr words ; IN: json.writer #! Writes the object out to a stream in JSON format @@ -28,9 +28,23 @@ M: string stream-json-print CHAR: " over stream-write1 swap [ { { CHAR: " [ "\\\"" over stream-write ] } - { CHAR: \r [ ] } - { CHAR: \n [ "\\r\\n" over stream-write ] } - [ over stream-write1 ] + { CHAR: \\ [ "\\\\" over stream-write ] } + { CHAR: / [ "\\/" over stream-write ] } + { CHAR: \b [ "\\b" over stream-write ] } + { CHAR: \f [ "\\f" over stream-write ] } + { CHAR: \n [ "\\n" over stream-write ] } + { CHAR: \r [ "\\r" over stream-write ] } + { CHAR: \s [ "\\s" over stream-write ] } + { CHAR: \t [ "\\t" over stream-write ] } + [ + dup printable? + [ over stream-write1 ] + [ + "\\u" pick stream-write + >hex 4 CHAR: 0 pad-head + over stream-write + ] if + ] } case ] each CHAR: " swap stream-write1 ; @@ -46,7 +60,7 @@ M: integer stream-json-print } cond ; M: float stream-json-print - [ float>json ] dip stream-write ; + [ float>json ] [ stream-write ] bi* ; M: real stream-json-print [ >float number>string ] [ stream-write ] bi* ;