diff --git a/src/jsx.erl b/src/jsx.erl index a8ddf8f..8478358 100644 --- a/src/jsx.erl +++ b/src/jsx.erl @@ -62,13 +62,10 @@ parse_opts([{escaped_unicode, Value}|Rest], Opts) -> parse_opts(Rest, Opts#opts{escaped_unicode = Value}); parse_opts([{naked_values, Value}|Rest], Opts) -> true = lists:member(Value, [true, false]), - parse_opts(Rest, Opts#opts{naked_values = Value, explicit_termination = true}); + parse_opts(Rest, Opts#opts{naked_values = Value}); parse_opts([{encoding, Value}|Rest], Opts) -> true = lists:member(Value, [utf8]), - parse_opts(Rest, Opts#opts{encoding = Value}); -parse_opts([{explicit_termination, Value}|Rest], Opts) -> - true = lists:member(Value, [true, false]), - parse_opts(Rest, Opts#opts{explicit_termination = Value}). + parse_opts(Rest, Opts#opts{encoding = Value}). %% ensures there's no invalid characters left in the stream upon completion of parsing diff --git a/src/jsx_common.hrl b/src/jsx_common.hrl index 3700b03..4bf1673 100644 --- a/src/jsx_common.hrl +++ b/src/jsx_common.hrl @@ -25,8 +25,7 @@ comments = false, escaped_unicode = ascii, naked_values = false, - encoding = utf8, - explicit_termination = false + encoding = utf8 }). %% whitespace diff --git a/src/jsx_decoder.erl b/src/jsx_decoder.erl index f5be509..3533c7c 100644 --- a/src/jsx_decoder.erl +++ b/src/jsx_decoder.erl @@ -59,10 +59,16 @@ start(<>, Stack, Callbacks, Opts) when ?is_nonzero(S), Opts#opts integer(Rest, Stack, Callbacks, Opts, [S]); start(<>, Stack, Callbacks, Opts) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> start(Resume, Stack, Callbacks, Opts) end); +start(<<>>, [], Callbacks, Opts) -> + fun(<<>>) -> {fold(completed_parse, Callbacks), <<>>} + ; (Stream) -> start(Stream, [], Callbacks, Opts) + end; start(<<>>, Stack, Callbacks, Opts) -> fun(Stream) -> start(Stream, Stack, Callbacks, Opts) end. +maybe_done(<>, [], Callbacks, _Opts) -> + {fold(completed_parse, Callbacks), Rest}; maybe_done(<>, Stack, Callbacks, Opts) when ?is_whitespace(S) -> maybe_done(Rest, Stack, Callbacks, Opts); maybe_done(<>, [object|Stack], Callbacks, Opts) -> @@ -75,12 +81,6 @@ maybe_done(<>, [array|_] = Stack, Callbacks, Opts) -> value(Rest, Stack, Callbacks, Opts); maybe_done(<>, Stack, Callbacks, Opts) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> maybe_done(Resume, Stack, Callbacks, Opts) end); -maybe_done(<<>>, [], Callbacks, Opts) when Opts#opts.explicit_termination == true -> - fun(<<>>) -> {fold(completed_parse, Callbacks), <<>>} - ;(Stream) -> maybe_done(Stream, [], Callbacks, Opts) - end; -maybe_done(<>, [], Callbacks, _Opts) -> - {fold(completed_parse, Callbacks), Rest}; maybe_done(<<>>, Stack, Callbacks, Opts) -> fun(Stream) -> maybe_done(Stream, Stack, Callbacks, Opts) end. @@ -264,12 +264,10 @@ zero(<>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) -> maybe_done(Rest, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts); zero(<>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> zero(Resume, Stack, Callbacks, Opts, Acc) end); -zero(<>, [], Callbacks, Opts, Acc) when Opts#opts.explicit_termination == true -> - fun(<<>>) -> {fold(completed_parse, fold({number, lists:reverse(Acc)}, Callbacks)), Rest} - ;(Stream) -> zero(Stream, [], Callbacks, Opts, Acc) - end; zero(<<>>, Stack, Callbacks, Opts, Acc) -> - fun(Stream) -> zero(Stream, Stack, Callbacks, Opts, Acc) end. + fun(<<>>) -> maybe_done(<<>>, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts) + ; (Stream) -> zero(Stream, Stack, Callbacks, Opts, Acc) + end. integer(<>, Stack, Callbacks, Opts, Acc) when ?is_nonzero(S) -> @@ -294,12 +292,10 @@ integer(<>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) maybe_done(Rest, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts); integer(<>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> integer(Resume, Stack, Callbacks, Opts, Acc) end); -integer(<<>> = Rest, [], Callbacks, Opts, Acc) when Opts#opts.explicit_termination == true -> - fun(<<>>) -> {fold(completed_parse, fold({number, lists:reverse(Acc)}, Callbacks)), Rest} - ;(Stream) -> integer(Stream, [], Callbacks, Opts, Acc) - end; integer(<<>>, Stack, Callbacks, Opts, Acc) -> - fun(Stream) -> integer(Stream, Stack, Callbacks, Opts, Acc) end. + fun(<<>>) -> maybe_done(<<>>, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts) + ; (Stream) -> integer(Stream, Stack, Callbacks, Opts, Acc) + end. fraction(<>, Stack, Callbacks, Opts, Acc) when ?is_nonzero(S) -> fraction(Rest, Stack, Callbacks, Opts, [S] ++ Acc); @@ -321,12 +317,10 @@ fraction(<>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) maybe_done(Rest, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts); fraction(<>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> fraction(Resume, Stack, Callbacks, Opts, Acc) end); -fraction(<>, [], Callbacks, Opts, Acc) when Opts#opts.explicit_termination == true -> - fun(<<>>) -> {fold(completed_parse, fold({number, lists:reverse(Acc)}, Callbacks)), Rest} - ;(Stream) -> fraction(Stream, [], Callbacks, Opts, Acc) - end; fraction(<<>>, Stack, Callbacks, Opts, Acc) -> - fun(Stream) -> fraction(Stream, Stack, Callbacks, Opts, Acc) end. + fun(<<>>) -> maybe_done(<<>>, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts) + ; (Stream) -> fraction(Stream, Stack, Callbacks, Opts, Acc) + end. e(<>, Stack, Callbacks, Opts, Acc) when S =:= ?zero; ?is_nonzero(S) -> @@ -359,12 +353,10 @@ exp(<>, Stack, Callbacks, Opts, Acc) when Opts#opts.comme maybe_comment(Rest, fun(Resume) -> exp(Resume, Stack, Callbacks, Opts, Acc) end); exp(<>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) -> maybe_done(Rest, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts); -exp(<>, [], Callbacks, Opts, Acc) when Opts#opts.explicit_termination == true -> - fun(<<>>) -> {fold(completed_parse, fold({number, lists:reverse(Acc)}, Callbacks)), Rest} - ;(Stream) -> exp(Stream, [], Callbacks, Opts, Acc) - end; exp(<<>>, Stack, Callbacks, Opts, Acc) -> - fun(Stream) -> exp(Stream, Stack, Callbacks, Opts, Acc) end. + fun(<<>>) -> maybe_done(<<>>, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts) + ; (Stream) -> exp(Stream, Stack, Callbacks, Opts, Acc) + end. tr(<<$r, Rest/binary>>, Stack, Callbacks, Opts) -> diff --git a/test/jsx_test.erl b/test/jsx_test.erl index b51b3d3..a1b7b91 100644 --- a/test/jsx_test.erl +++ b/test/jsx_test.erl @@ -50,24 +50,28 @@ test_body(TestSpec, Dir) -> case file:consult(Dir ++ "/" ++ TestSpec) of {ok, [Events]} -> Decoder = jsx:decoder(), - [{TestName, ?_assertEqual(incremental_decode(Decoder, JSON), Events)}] ++ + [{TestName ++ "_incremental", ?_assertEqual(incremental_decode(Decoder, JSON), Events)}] ++ [{TestName, ?_assertEqual(decode(Decoder, JSON), Events)}] ; {ok, [Events, Flags]} -> Decoder = jsx:decoder(Flags), - [{TestName, ?_assertEqual(incremental_decode(Decoder, JSON), Events)}] ++ + [{TestName ++ "_incremental", ?_assertEqual(incremental_decode(Decoder, JSON), Events)}] ++ [{TestName, ?_assertEqual(decode(Decoder, JSON), Events)}] end catch _:_ -> [] end. incremental_decode(F, <<>>) -> - {Result, Rest} = F(<<>>), - true = jsx:tail_clean(Rest), - Result; + case F(<<>>) of + G when is_function(G) -> + {Result, <<>>} = G(<<>>), + Result + ; {Result, Rest} -> + Result + end; incremental_decode(F, <>) -> case F(<>) of G when is_function(G) -> - decode(G, Rest) + incremental_decode(G, Rest) ; {Result, _} -> Result end. @@ -78,7 +82,7 @@ decode(F, JSON) -> {Result, <<>>} = G(<<>>), Result ; {Result, Rest} -> - true = jsx:tail_clean(Rest), + {_, <<>>} = (F(Rest))(<<>>), Result end. \ No newline at end of file