From 0a96a059a1ea5794dd9365f2a9df9bbf641972b8 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Thu, 24 Jun 2010 15:55:08 -0700 Subject: [PATCH] added test for multi_terms --- priv/jsx_test.escript | 69 ++++++++++++++++++++++++++++++++----------- src/jsx.erl | 7 +---- src/jsx_decoder.erl | 24 +++++---------- 3 files changed, 60 insertions(+), 40 deletions(-) diff --git a/priv/jsx_test.escript b/priv/jsx_test.escript index 0349f0e..e32d698 100755 --- a/priv/jsx_test.escript +++ b/priv/jsx_test.escript @@ -42,6 +42,7 @@ test(Dir) -> etap:plan(length(ValidJSONTests) * 5), Before = erlang:now(), run_tests(ValidJSONTests), + etap:is(multi_decode(multi_json_body(), []), multi_test_result(), "multi terms"), After = erlang:now(), etap:end_tests(), @@ -81,36 +82,70 @@ run_tests([{TestName, JSON, Events, Flags}|Rest]) -> etap:is(incremental_decode(to_utf32le(JSON), Flags), Events, TestName ++ ": incremental utf32le"), run_tests(Rest). -incremental_decode(<>, Flags) -> - P = jsx:parser(Flags), - incremental_decode(P(C), Rest, []). - -incremental_decode({incomplete, Next, _}, <>, Acc) -> - incremental_decode(Next(C), Rest, Acc); -incremental_decode({incomplete, _, Force}, <<>>, Acc) -> - incremental_decode(Force(), <<>>, Acc); -incremental_decode({event, end_json, Next}, <>, Acc) -> - incremental_decode(Next(C), Rest, Acc); -incremental_decode({event, end_json, _}, <<>>, Acc) -> - lists:reverse(Acc); -incremental_decode({event, Event, F}, Rest, Acc) -> - incremental_decode(F(), Rest, [Event] ++ Acc). - - + decode(JSON, Flags) -> P = jsx:parser(Flags), decode_loop(P(JSON), []). - + decode_loop({incomplete, _Next, Force}, Acc) -> decode_loop(Force(), Acc); decode_loop({event, end_json, _}, Acc) -> lists:reverse(Acc); decode_loop({event, E, Next}, Acc) -> decode_loop(Next(), [E] ++ Acc). + + +incremental_decode(<>, Flags) -> + P = jsx:parser(Flags), + incremental_decode_loop(P(C), Rest, []). + +incremental_decode_loop({incomplete, Next, _}, <>, Acc) -> + incremental_decode_loop(Next(C), Rest, Acc); +incremental_decode_loop({incomplete, _, Force}, <<>>, Acc) -> + incremental_decode_loop(Force(), <<>>, Acc); +incremental_decode_loop({event, end_json, Next}, <>, Acc) -> + incremental_decode_loop(Next(C), Rest, Acc); +incremental_decode_loop({event, end_json, _}, <<>>, Acc) -> + lists:reverse(Acc); +incremental_decode_loop({event, Event, F}, Rest, Acc) -> + incremental_decode_loop(F(), Rest, [Event] ++ Acc). + + +multi_decode(JSON, Flags) -> + P = jsx:parser(Flags ++ [{multi_term, true}]), + multi_decode_loop(P(JSON), [[]]). +multi_decode_loop({incomplete, _Next, Force}, [[]|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"}] + ]. + \ No newline at end of file diff --git a/src/jsx.erl b/src/jsx.erl index 8fe9448..82d7248 100644 --- a/src/jsx.erl +++ b/src/jsx.erl @@ -68,12 +68,7 @@ parse_opts([{escaped_unicode, Value}|Rest], {Comments, _EscapedUnicode, Multi}) true = lists:member(Value, [ascii, codepoint, none]), parse_opts(Rest, {Comments, Value, Multi}); parse_opts([{multi_term, Value}|Rest], {Comments, EscapedUnicode, _Multi}) -> - ok = case Value of - S when is_binary(S) -> ok - ; whitespace -> ok - ; true -> ok - ; false -> ok - end, + true = lists:member(Value, [true, false]), parse_opts(Rest, {Comments, EscapedUnicode, Value}); parse_opts([{encoding, _}|Rest], Opts) -> parse_opts(Rest, Opts). diff --git a/src/jsx_decoder.erl b/src/jsx_decoder.erl index 6b10bca..cbbf8ea 100644 --- a/src/jsx_decoder.erl +++ b/src/jsx_decoder.erl @@ -88,12 +88,13 @@ maybe_done(<>, [array|_] = Stack, Opts) -> value(Rest, Stack, Opts); maybe_done(<>, Stack, ?comments_enabled(Opts)) -> maybe_comment(Rest, fun(Resume) -> maybe_done(Resume, Stack, Opts) end); -maybe_done(Bin, [], ?multi_term(Opts)) -> - {event, end_json, fun(Stream) -> - Rest = strip(<>, Opts), - start(<>, [], Opts) end}; +maybe_done(Rest, [], ?multi_term(Opts)) -> + {event, end_json, fun() -> start(Rest, [], Opts) end}; maybe_done(<<>>, [], Opts) -> - {event, end_json, fun(Stream) -> maybe_done(Stream, [], Opts) end}; + {incomplete, + fun(Stream) -> maybe_done(Stream, [], Opts) end, + fun() -> {event, end_json, fun() -> maybe_done(<<>>, [], Opts) end} end + }; maybe_done(Bin, Stack, Opts) -> ?incomplete(?partial_codepoint(Bin), fun(Stream) -> maybe_done(<>, Stack, Opts) end, @@ -673,15 +674,4 @@ maybe_comment_done(Bin, Resume) -> ?incomplete(?partial_codepoint(Bin), fun(Stream) -> maybe_comment_done(<>, Resume) end, ?ferror - ). - - -%% strip whitespace and comments (if enabled) from a stream, returning the -%% stream when the first non-whitespace/comment character is encountered - -strip(<>, Opts) when ?is_whitespace(S) -> - strip(Rest, Opts); -strip(<>, ?comments_enabled(Opts)) -> - maybe_comment(Rest, fun(Resume) -> strip(Resume, Opts) end); -strip(Bin, _Opts) -> - Bin. \ No newline at end of file + ). \ No newline at end of file