simplified api, end_json now signifies you can cease parsing, no need to continue and check tail

This commit is contained in:
alisdair sullivan 2010-08-02 20:42:12 -07:00
parent 5975048ee4
commit db91b3fb74
35 changed files with 234 additions and 70 deletions

View file

@ -63,7 +63,7 @@ start(<<?solidus/?encoding, Rest/binary>>, Stack, ?comments_enabled(Opts)) ->
maybe_comment(Rest, fun(Resume) -> start(Resume, Stack, Opts) end);
start(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> start(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> start(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -85,7 +85,7 @@ maybe_done(Rest, [], Opts) ->
done(Rest, Opts);
maybe_done(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> maybe_done(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> maybe_done(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -94,10 +94,10 @@ done(<<S/?encoding, Rest/binary>>, Opts) when ?is_whitespace(S) ->
done(<<?solidus/?encoding, Rest/binary>>, ?comments_enabled(Opts)) ->
maybe_comment(Rest, fun(Resume) -> done(Resume, Opts) end);
done(<<>>, Opts) ->
{event, end_json, fun() -> {incomplete, fun(Stream) -> done(Stream, Opts) end} end};
{event, end_json, fun() -> {incomplete, fun(end_stream) -> done(<<>>, Opts); (Stream) -> done(Stream, Opts) end} end};
done(Bin, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> done(<<Bin/binary, Stream/binary>>, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> done(<<Bin/binary, Stream/binary>>, Opts) end}
; false -> {error, badjson}
end.
@ -112,7 +112,7 @@ object(<<?solidus/?encoding, Rest/binary>>, Stack, ?comments_enabled(Opts)) ->
maybe_comment(Rest, fun(Resume) -> object(Resume, Stack, Opts) end);
object(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> object(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> object(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -143,7 +143,7 @@ array(<<?solidus/?encoding, Rest/binary>>, Stack, ?comments_enabled(Opts)) ->
maybe_comment(Rest, fun(Resume) -> array(Resume, Stack, Opts) end);
array(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> array(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> array(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -172,7 +172,7 @@ value(<<?solidus/?encoding, Rest/binary>>, Stack, ?comments_enabled(Opts)) ->
maybe_comment(Rest, fun(Resume) -> value(Resume, Stack, Opts) end);
value(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> value(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> value(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -185,7 +185,7 @@ colon(<<?solidus/?encoding, Rest/binary>>, Stack, ?comments_enabled(Opts)) ->
maybe_comment(Rest, fun(Resume) -> colon(Resume, Stack, Opts) end);
colon(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> colon(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> colon(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -198,7 +198,7 @@ key(<<?solidus/?encoding, Rest/binary>>, Stack, ?comments_enabled(Opts)) ->
maybe_comment(Rest, fun(Resume) -> key(Resume, Stack, Opts) end);
key(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> key(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> key(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -219,7 +219,7 @@ string(<<S/?encoding, Rest/binary>>, Stack, Opts, Acc) when ?is_noncontrol(S) ->
string(Rest, Stack, Opts, [S] ++ Acc);
string(Bin, Stack, Opts, Acc) ->
case partial_utf(Bin) of
true -> {incomplete, fun(Stream) -> string(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> string(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
; false -> {error, badjson}
end.
@ -292,7 +292,7 @@ escape(<<S/?encoding, Rest/binary>>, Stack, Opts, Acc)
string(Rest, Stack, Opts, [S] ++ Acc);
escape(Bin, Stack, Opts, Acc) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> escape(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> escape(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
; false -> {error, badjson}
end.
@ -341,7 +341,7 @@ escaped_unicode(<<S/?encoding, Rest/binary>>, Stack, Opts, String, Acc) when ?is
escaped_unicode(Rest, Stack, Opts, String, [S] ++ Acc);
escaped_unicode(Bin, Stack, Opts, String, Acc) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> escaped_unicode(<<Bin/binary, Stream/binary>>, Stack, Opts, String, Acc) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> escaped_unicode(<<Bin/binary, Stream/binary>>, Stack, Opts, String, Acc) end}
; false -> {error, badjson}
end.
@ -371,7 +371,7 @@ negative(<<S/?encoding, Rest/binary>>, Stack, Opts, Acc) when ?is_nonzero(S) ->
integer(Rest, Stack, Opts, [S] ++ Acc);
negative(Bin, Stack, Opts, Acc) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> negative(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> negative(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
; false -> {error, badjson}
end.
@ -395,10 +395,15 @@ zero(<<S/?encoding, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) ->
zero(<<?solidus/?encoding, Rest/binary>>, Stack, ?comments_enabled(Opts), Acc) ->
maybe_comment(Rest, fun(Resume) -> zero(Resume, Stack, Opts, Acc) end);
zero(<<>>, [], Opts, Acc) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {incomplete, fun(Stream) -> zero(Stream, [], Opts, Acc) end} end};
{incomplete, fun(end_stream) ->
{event, {integer, lists:reverse(Acc)}, fun() ->
{event, end_json, fun() -> zero(<<>>, [], Opts, Acc) end}
end}
; (Stream) -> zero(Stream, [], Opts, Acc)
end};
zero(Bin, Stack, Opts, Acc) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> zero(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> zero(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
; false -> {error, badjson}
end.
@ -430,10 +435,15 @@ integer(<<S/?encoding, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) -
integer(<<?solidus/?encoding, Rest/binary>>, Stack, ?comments_enabled(Opts), Acc) ->
maybe_comment(Rest, fun(Resume) -> integer(Resume, Stack, Opts, Acc) end);
integer(<<>>, [], Opts, Acc) ->
{event, {integer, lists:reverse(Acc)}, fun() -> {incomplete, fun(Stream) -> integer(Stream, [], Opts, Acc) end} end};
{incomplete, fun(end_stream) ->
{event, {integer, lists:reverse(Acc)}, fun() ->
{event, end_json, fun() -> integer(<<>>, [], Opts, Acc) end}
end}
; (Stream) -> integer(Stream, [], Opts, Acc)
end};
integer(Bin, Stack, Opts, Acc) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> integer(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> integer(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
; false -> {error, badjson}
end.
@ -444,7 +454,7 @@ initial_decimal(<<?zero/?encoding, Rest/binary>>, Stack, Opts, Acc) ->
decimal(Rest, Stack, Opts, [?zero] ++ Acc);
initial_decimal(Bin, Stack, Opts, Acc) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> initial_decimal(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> initial_decimal(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
; false -> {error, badjson}
end.
@ -474,10 +484,15 @@ decimal(<<S/?encoding, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) -
decimal(<<?solidus/?encoding, Rest/binary>>, Stack, ?comments_enabled(Opts), Acc) ->
maybe_comment(Rest, fun(Resume) -> decimal(Resume, Stack, Opts, Acc) end);
decimal(<<>>, [], Opts, Acc) ->
{event, {float, lists:reverse(Acc)}, fun() -> {incomplete, fun(Stream) -> decimal(Stream, [], Opts, Acc) end} end};
{incomplete, fun(end_stream) ->
{event, {float, lists:reverse(Acc)}, fun() ->
{event, end_json, fun() -> decimal(<<>>, [], Opts, Acc) end}
end}
; (Stream) -> decimal(Stream, [], Opts, Acc)
end};
decimal(Bin, Stack, Opts, Acc) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> decimal(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> decimal(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
; false -> {error, badjson}
end.
@ -488,7 +503,7 @@ e(<<S/?encoding, Rest/binary>>, Stack, Opts, Acc) when S =:= ?positive; S =:= ?n
ex(Rest, Stack, Opts, [S] ++ Acc);
e(Bin, Stack, Opts, Acc) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> e(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> e(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
; false -> {error, badjson}
end.
@ -497,7 +512,7 @@ ex(<<S/?encoding, Rest/binary>>, Stack, Opts, Acc) when S =:= ?zero; ?is_nonzero
exp(Rest, Stack, Opts, [S] ++ Acc);
ex(Bin, Stack, Opts, Acc) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> ex(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> ex(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
; false -> {error, badjson}
end.
@ -523,10 +538,15 @@ exp(<<S/?encoding, Rest/binary>>, Stack, Opts, Acc) when ?is_whitespace(S) ->
exp(<<?solidus/?encoding, Rest/binary>>, Stack, ?comments_enabled(Opts), Acc) ->
maybe_comment(Rest, fun(Resume) -> exp(Resume, Stack, Opts, Acc) end);
exp(<<>>, [], Opts, Acc) ->
{event, {float, lists:reverse(Acc)}, fun() -> {incomplete, fun(Stream) -> exp(Stream, [], Opts, Acc) end} end};
{incomplete, fun(end_stream) ->
{event, {float, lists:reverse(Acc)}, fun() ->
{event, end_json, fun() -> exp(<<>>, [], Opts, Acc) end}
end}
; (Stream) -> exp(Stream, [], Opts, Acc)
end};
exp(Bin, Stack, Opts, Acc) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> exp(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> exp(<<Bin/binary, Stream/binary>>, Stack, Opts, Acc) end}
; false -> {error, badjson}
end.
@ -535,7 +555,7 @@ tr(<<$r/?encoding, Rest/binary>>, Stack, Opts) ->
tru(Rest, Stack, Opts);
tr(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> tr(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> tr(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -544,7 +564,7 @@ tru(<<$u/?encoding, Rest/binary>>, Stack, Opts) ->
true(Rest, Stack, Opts);
tru(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> tru(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> tru(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -553,7 +573,7 @@ true(<<$e/?encoding, Rest/binary>>, Stack, Opts) ->
{event, {literal, true}, fun() -> maybe_done(Rest, Stack, Opts) end};
true(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> true(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> true(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -562,7 +582,7 @@ fa(<<$a/?encoding, Rest/binary>>, Stack, Opts) ->
fal(Rest, Stack, Opts);
fa(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> fa(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> fa(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -571,7 +591,7 @@ fal(<<$l/?encoding, Rest/binary>>, Stack, Opts) ->
fals(Rest, Stack, Opts);
fal(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> fal(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> fal(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -580,7 +600,7 @@ fals(<<$s/?encoding, Rest/binary>>, Stack, Opts) ->
false(Rest, Stack, Opts);
fals(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> fals(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> fals(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -589,7 +609,7 @@ false(<<$e/?encoding, Rest/binary>>, Stack, Opts) ->
{event, {literal, false}, fun() -> maybe_done(Rest, Stack, Opts) end};
false(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> false(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> false(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -598,7 +618,7 @@ nu(<<$u/?encoding, Rest/binary>>, Stack, Opts) ->
nul(Rest, Stack, Opts);
nu(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> nu(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> nu(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -607,7 +627,7 @@ nul(<<$l/?encoding, Rest/binary>>, Stack, Opts) ->
null(Rest, Stack, Opts);
nul(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> nul(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> nul(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -616,7 +636,7 @@ null(<<$l/?encoding, Rest/binary>>, Stack, Opts) ->
{event, {literal, null}, fun() -> maybe_done(Rest, Stack, Opts) end};
null(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> null(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> null(<<Bin/binary, Stream/binary>>, Stack, Opts) end}
; false -> {error, badjson}
end.
@ -630,7 +650,7 @@ maybe_comment(<<?star/?encoding, Rest/binary>>, Resume) ->
comment(Rest, Resume);
maybe_comment(Bin, Resume) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> maybe_comment(<<Bin/binary, Stream/binary>>, Resume) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> maybe_comment(<<Bin/binary, Stream/binary>>, Resume) end}
; false -> {error, badjson}
end.
@ -641,7 +661,7 @@ comment(<<_/?encoding, Rest/binary>>, Resume) ->
comment(Rest, Resume);
comment(Bin, Resume) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> comment(<<Bin/binary, Stream/binary>>, Resume) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> comment(<<Bin/binary, Stream/binary>>, Resume) end}
; false -> {error, badjson}
end.
@ -652,6 +672,6 @@ maybe_comment_done(<<_/?encoding, Rest/binary>>, Resume) ->
comment(Rest, Resume);
maybe_comment_done(Bin, Resume) ->
case ?partial_codepoint(Bin) of
true -> {incomplete, fun(Stream) -> maybe_comment_done(<<Bin/binary, Stream/binary>>, Resume) end}
true -> {incomplete, fun(end_stream) -> {error, badjson}; (Stream) -> maybe_comment_done(<<Bin/binary, Stream/binary>>, Resume) end}
; false -> {error, badjson}
end.

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
[start_array, {string, "foo"}, {string, "bar"}, {string, "baz"}, start_array, {literal, true}, end_array, start_array, {literal, false}, end_array, start_array, {literal, null}, end_array, {literal, true}, {literal, false}, {literal, null}, {float, "0.7"}, start_object, {key, "key"}, {string, "value"}, end_object, start_array, start_object, end_object, {literal, null}, {literal, null}, {literal, null}, start_array, end_array, end_array, {string, "\n\r\\"}, start_array, {integer, "-1"}, end_array, end_array].
[start_array, {string, "foo"}, {string, "bar"}, {string, "baz"}, start_array, {literal, true}, end_array, start_array, {literal, false}, end_array, start_array, {literal, null}, end_array, {literal, true}, {literal, false}, {literal, null}, {float, "0.7"}, start_object, {key, "key"}, {string, "value"}, end_object, start_array, start_object, end_object, {literal, null}, {literal, null}, {literal, null}, start_array, end_array, end_array, {string, "\n\r\\"}, start_array, {integer, "-1"}, end_array, end_array, end_json].

View file

@ -1,3 +1,3 @@
[start_array, {string, "a string"}, {integer, "1"}, start_object, {key, "key"}, start_array, end_array, {key, "another key"}, {integer, "0"}, end_object, {literal, true}, end_array].
[start_array, {string, "a string"}, {integer, "1"}, start_object, {key, "key"}, start_array, end_array, {key, "another key"}, {integer, "0"}, end_object, {literal, true}, end_array, end_json].
[{comments, true}].

View file

@ -1 +1 @@
[start_array, start_array, start_array, end_array, end_array, end_array].
[start_array, start_array, start_array, end_array, end_array, end_array, end_json].

View file

@ -1 +1 @@
[start_array, end_array].
[start_array, end_array, end_json].

View file

@ -1,3 +1,3 @@
[start_array, end_array].
[start_array, end_array, end_json].
[{comments, true}].

View file

@ -1 +1 @@
[start_object, end_object].
[start_object, end_object, end_json].

View file

@ -1,3 +1,3 @@
[start_object, end_object].
[start_object, end_object, end_json].
[{comments, true}].

View file

@ -1,3 +1,3 @@
[start_array, {string, [66560]}, end_array].
[start_array, {string, [66560]}, end_array, end_json].
[{escaped_unicode, codepoint}].

View file

@ -1,3 +1,3 @@
[start_array, start_array, {float, "2.0e7"}, end_array, {float, "2.0e7"}, start_object, {key, "key"}, {float, "2.0e7"}, {key, "another key"}, {float, "2.0e7"}, end_object, {float, "4.2e70"}, end_array].
[start_array, start_array, {float, "2.0e7"}, end_array, {float, "2.0e7"}, start_object, {key, "key"}, {float, "2.0e7"}, {key, "another key"}, {float, "2.0e7"}, end_object, {float, "4.2e70"}, end_array, end_json].
[{comments, true}].

View file

@ -1,3 +1,3 @@
[start_array, start_array, {float, "2.0"}, end_array, {float, "2.0"}, start_object, {key, "key"}, {float, "2.0e7"}, {key, "another key"}, {float, "2.0e7"}, end_object, start_object, {key, "key"}, {float, "2.0"}, {key, "another key"}, {float, "2.0"}, end_object, {float, "4.2"}, end_array].
[start_array, start_array, {float, "2.0"}, end_array, {float, "2.0"}, start_object, {key, "key"}, {float, "2.0e7"}, {key, "another key"}, {float, "2.0e7"}, end_object, start_object, {key, "key"}, {float, "2.0"}, {key, "another key"}, {float, "2.0"}, end_object, {float, "4.2"}, end_array, end_json].
[{comments, true}].

View file

@ -1 +1 @@
[start_array, start_array, {integer, "20"}, end_array, {integer, "20"}, start_object, {key, "key"}, {integer, "20"}, {key, "another key"}, {integer, "20"}, end_object, {integer, "42"}, end_array].
[start_array, start_array, {integer, "20"}, end_array, {integer, "20"}, start_object, {key, "key"}, {integer, "20"}, {key, "another key"}, {integer, "20"}, end_object, {integer, "42"}, end_array, end_json].

View file

@ -1 +1 @@
[start_array,{string,[32, 119070, 32]},end_array].
[start_array,{string,[32, 119070, 32]},end_array,end_json].

View file

@ -1 +1 @@
[{literal, false}].
[{literal, false}, end_json].

View file

@ -1 +1 @@
[{literal, null}].
[{literal, null}, end_json].

View file

@ -1 +1 @@
[{integer, "42"}].
[{integer, "42"}, end_json].

View file

@ -1 +1 @@
[{integer, "-42"}].
[{integer, "-42"}, end_json].

View file

@ -1 +1 @@
[{float, "-0.7"}].
[{float, "-0.7"}, end_json].

View file

@ -1 +1 @@
[{float, "0.7"}].
[{float, "0.7"}, end_json].

View file

@ -1 +1 @@
[{integer, "0"}].
[{integer, "0"}, end_json].

View file

@ -1 +1 @@
[{float, "1.0e100"}].
[{float, "1.0e100"}, end_json].

View file

@ -1 +1 @@
[{integer, "7"}].
[{integer, "7"}, end_json].

View file

@ -1 +1 @@
[{string, "this is a naked string"}].
[{string, "this is a naked string"}, end_json].

View file

@ -1 +1 @@
[{literal, true}].
[{literal, true}, end_json].

View file

@ -1 +1 @@
[start_array, start_array, {integer, "-0"}, end_array, {integer, "-0"}, start_object, {key, "key"}, {integer, "-0"}, {key, "another key"}, {integer, "-0"}, end_object, {integer, "-0"}, end_array].
[start_array, start_array, {integer, "-0"}, end_array, {integer, "-0"}, start_object, {key, "key"}, {integer, "-0"}, {key, "another key"}, {integer, "-0"}, end_object, {integer, "-0"}, end_array, end_json].

View file

@ -1 +1 @@
[ start_array, {integer, "1"}, {integer, "2"}, {integer, "3"}, {integer, "4"}, {integer, "5"}, {integer, "6"}, {integer, "7"}, {integer, "8"}, {integer, "9"}, {integer, "42"}, {integer, "127"}, {integer, "99999999999999999999999999999"}, {float, "1.0e1"}, {float, "1.0e1"}, {float, "1.0e1"}, {float, "1.325e478534"}, {integer, "-1"}, {float, "-1.0e-1"}, {float, "3.7e-57834235"}, end_array ].
[ start_array, {integer, "1"}, {integer, "2"}, {integer, "3"}, {integer, "4"}, {integer, "5"}, {integer, "6"}, {integer, "7"}, {integer, "8"}, {integer, "9"}, {integer, "42"}, {integer, "127"}, {integer, "99999999999999999999999999999"}, {float, "1.0e1"}, {float, "1.0e1"}, {float, "1.0e1"}, {float, "1.325e478534"}, {integer, "-1"}, {float, "-1.0e-1"}, {float, "3.7e-57834235"}, end_array, end_json].

View file

@ -1 +1 @@
[start_object, {key, "foo"}, {string, "bar"}, {key, "baz"}, {literal, true}, {key, "false"}, {literal, null}, {key, "object"}, start_object, {key, "key"}, {string, "value"}, end_object, {key, "list"}, start_array, {literal, null}, {literal, null}, {literal, null}, start_array, end_array, {string, "\n\r\\"}, end_array, end_object].
[start_object, {key, "foo"}, {string, "bar"}, {key, "baz"}, {literal, true}, {key, "false"}, {literal, null}, {key, "object"}, start_object, {key, "key"}, {string, "value"}, end_object, {key, "list"}, start_array, {literal, null}, {literal, null}, {literal, null}, start_array, end_array, {string, "\n\r\\"}, end_array, end_object, end_json].

View file

@ -1 +1 @@
[start_array, {string, "this is a random string with \n embedded escapes in it"}, end_array].
[start_array, {string, "this is a random string with \n embedded escapes in it"}, end_array, end_json].

View file

@ -1,3 +1,3 @@
[start_array, {string, "\""}, {string, "\\"}, {string, "/"}, {string, "\b"}, {string, "\f"}, {string, "\n"}, {string, "\r"}, {string, "\t"}, end_array].
[start_array, {string, "\""}, {string, "\\"}, {string, "/"}, {string, "\b"}, {string, "\f"}, {string, "\n"}, {string, "\r"}, {string, "\t"}, end_array, end_json].

View file

@ -1,3 +1,3 @@
[start_array, {string, "arabic letter alef: "}, {string, [16#0627]}, end_array].
[start_array, {string, "arabic letter alef: "}, {string, [16#0627]}, end_array, end_json].
[{escaped_unicode, codepoint}].

View file

@ -1,3 +1,3 @@
[start_array, {string, "arabic letter alef: "}, {string, "\\u0627"}, end_array].
[start_array, {string, "arabic letter alef: "}, {string, "\\u0627"}, end_array, end_json].
[{escaped_unicode, ascii}].

View file

@ -1 +1 @@
[start_array, {float, "0.3"}, end_array].
[start_array, {float, "0.3"}, end_array, end_json].

View file

@ -1 +1 @@
[start_array, start_array, {integer, "0"}, end_array, {integer, "0"}, start_object, {key, "key"}, {integer, "0"}, {key, "another key"}, {integer, "0"}, end_object, {integer, "0"}, end_array].
[start_array, start_array, {integer, "0"}, end_array, {integer, "0"}, start_object, {key, "key"}, {integer, "0"}, {key, "another key"}, {integer, "0"}, end_object, {integer, "0"}, end_array, end_json].

144
test/jsx_test.escript Executable file
View file

@ -0,0 +1,144 @@
#!/usr/bin/env escript
%% The MIT License
%% Copyright (c) 2010 Alisdair Sullivan <alisdairsullivan@yahoo.ca>
%% Permission is hereby granted, free of charge, to any person obtaining a copy
%% of this software and associated documentation files (the "Software"), to deal
%% in the Software without restriction, including without limitation the rights
%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
%% copies of the Software, and to permit persons to whom the Software is
%% furnished to do so, subject to the following conditions:
%% The above copyright notice and this permission notice shall be included in
%% all copies or substantial portions of the Software.
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
%% THE SOFTWARE.
-module(jsx_test).
-export([main/1]).
main([]) ->
test("./test/cases");
main([Path]) ->
test(Path).
test(Dir) ->
code:add_path("ebin"),
ValidJSONTests = load_tests(Dir),
etap:plan((length(ValidJSONTests) * 10) + 1),
run_tests(ValidJSONTests),
etap:is(multi_decode(multi_json_body(), []), multi_test_result(), "multi terms"),
etap:end_tests().
load_tests(Dir) ->
TestSpecs = filelib:wildcard("*.test", Dir),
load_tests(TestSpecs, Dir, []).
load_tests([], _Dir, Acc) ->
lists:reverse(Acc);
load_tests([Test|Rest], Dir, Acc) ->
try
TestName = filename:basename(Test, ".test"),
{ok, JSON} = file:read_file(Dir ++ "/" ++ TestName ++ ".json"),
case file:consult(Dir ++ "/" ++ Test) of
{ok, [Events]} ->
load_tests(Rest, Dir, [{TestName, JSON, Events, []}] ++ Acc)
; {ok, [Events, Flags]} ->
load_tests(Rest, Dir, [{TestName, JSON, Events, Flags}] ++ Acc)
end
catch _:_ -> load_tests(Rest, Dir, Acc) end.
run_tests([]) ->
ok;
run_tests([{TestName, JSON, Events, Flags}|Rest]) ->
etap:is(decode(JSON, Flags), Events, TestName ++ ": utf8"),
etap:is(incremental_decode(JSON, Flags), Events, TestName ++ ": incremental utf8"),
etap:is(decode(to_utf16(JSON), Flags), Events, TestName ++ ": utf16"),
etap:is(incremental_decode(to_utf16(JSON), Flags), Events, TestName ++ ": incremental utf16"),
etap:is(decode(to_utf16le(JSON), Flags), Events, TestName ++ ": utf16le"),
etap:is(incremental_decode(to_utf16le(JSON), Flags), Events, TestName ++ ": incremental utf16le"),
etap:is(decode(to_utf32(JSON), Flags), Events, TestName ++ ": utf32"),
etap:is(incremental_decode(to_utf32(JSON), Flags), Events, TestName ++ ": incremental utf32"),
etap:is(decode(to_utf32le(JSON), Flags), Events, TestName ++ ": utf32le"),
etap:is(incremental_decode(to_utf32le(JSON), Flags), Events, TestName ++ ": incremental utf32le"),
run_tests(Rest).
decode(JSON, Flags) ->
P = jsx:parser(Flags),
decode_loop(P(JSON), []).
decode_loop({event, end_json, Next}, Acc) ->
lists:reverse([end_json] ++ Acc);
decode_loop({incomplete, More}, Acc) ->
decode_loop(More(end_stream), Acc);
decode_loop({event, E, Next}, Acc) ->
decode_loop(Next(), [E] ++ Acc).
incremental_decode(<<C:1/binary, Rest/binary>>, Flags) ->
P = jsx:parser(Flags),
incremental_decode_loop(P(C), Rest, []).
incremental_decode_loop({incomplete, Next}, <<>>, Acc) ->
incremental_decode_loop(Next(end_stream), <<>>, Acc);
incremental_decode_loop({incomplete, Next}, <<C:1/binary, Rest/binary>>, Acc) ->
incremental_decode_loop(Next(C), Rest, Acc);
incremental_decode_loop({event, end_json, Next}, _Rest, Acc) ->
lists:reverse([end_json] ++ Acc);
incremental_decode_loop({event, Event, Next}, Rest, Acc) ->
incremental_decode_loop(Next(), Rest, [Event] ++ Acc).
multi_decode(JSON, Flags) ->
P = jsx:parser(Flags ++ [{multi_term, true}]),
multi_decode_loop(P(JSON), [[]]).
multi_decode_loop({incomplete, _Next}, [[]|Acc]) ->
lists:reverse(Acc);
multi_decode_loop({event, end_json, Next}, [S|Acc]) ->
multi_decode_loop(Next(), [[]|[lists:reverse(S)] ++ Acc]);
multi_decode_loop({event, E, Next}, [S|Acc]) ->
multi_decode_loop(Next(), [[E] ++ S] ++ Acc).
to_utf16(Bin) -> unicode:characters_to_binary(Bin, utf8, utf16).
to_utf16le(Bin) -> unicode:characters_to_binary(Bin, utf8, {utf16,little}).
to_utf32(Bin) -> unicode:characters_to_binary(Bin, utf8, utf32).
to_utf32le(Bin) -> unicode:characters_to_binary(Bin, utf8, {utf32,little}).
multi_json_body() ->
<<"0 1 -1 1e1 0.7 0.7e-1 true false null {} [] [1, 2, 3] \"hope this works\"">>.
multi_test_result() ->
[ [{integer, "0"}],
[{integer, "1"}],
[{integer, "-1"}],
[{float, "1.0e1"}],
[{float, "0.7"}],
[{float, "0.7e-1"}],
[{literal, true}],
[{literal, false}],
[{literal, null}],
[start_object, end_object],
[start_array, end_array],
[start_array, {integer, "1"}, {integer, "2"}, {integer, "3"}, end_array],
[{string, "hope this works"}]
].