From a99644a926c2d1b233d180281303d2f4ee443561 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Mon, 27 Sep 2010 14:07:36 -0700 Subject: [PATCH] modified error return value from {error, badjson} to {error, {badjson, Bin}} where Bin is the input from the point of the error --- README.markdown | 2 +- doc/overview.edoc | 4 +- include/jsx_common.hrl | 2 +- include/jsx_decoder.hrl | 134 ++++++++++++++++++++-------------------- src/jsx.erl | 10 +-- 5 files changed, 77 insertions(+), 75 deletions(-) diff --git a/README.markdown b/README.markdown index d59bf05..e187a53 100644 --- a/README.markdown +++ b/README.markdown @@ -13,7 +13,7 @@ it also includes an implementation of [eep0018][3], a pretty printer, a verifier ### usage ### -jsx provides an iterator based api that returns tuples of the form `{event, Event, Next}` where `Event` is an atom or tuple (see below) representing the json structure or value encountered. `Next` is a zero arity function that returns the next tuple in the sequence when called. it is stream based, and can also return the tuple `{incomplete, More}` to signify that input is exhausted. `More` is an arity one function that, when called with another binary, attempts to continue parsing treating the new binary as the tail of the preceding binary. errors in the json document are represented by the tuple `{error, badjson}` +jsx provides an iterator based api that returns tuples of the form `{event, Event, Next}` where `Event` is an atom or tuple (see below) representing the json structure or value encountered. `Next` is a zero arity function that returns the next tuple in the sequence when called. it is stream based, and can also return the tuple `{incomplete, More}` to signify that input is exhausted. `More` is an arity one function that, when called with another binary, attempts to continue parsing treating the new binary as the tail of the preceding binary. errors in the json document are represented by the tuple `{error, {badjson, Bin}}` the following module diff --git a/doc/overview.edoc b/doc/overview.edoc index 110076d..ab7c842 100644 --- a/doc/overview.edoc +++ b/doc/overview.edoc @@ -65,7 +65,9 @@ the decoder can also return two other tuples: the parser and resumes parsing as if never interrupted. the semantics are as if the new binary were appended to the already parsed binary - {error, badjson} + {error, {badjson, Bin}} + Bin -- the remainder of the input at the point of the error. the first + byte of the binary is the byte that failed to match ''' `incomplete' is returned when input is exhausted. `error' is returned when invalid json input is detected. how obvious diff --git a/include/jsx_common.hrl b/include/jsx_common.hrl index 33fb9e6..d2d4351 100644 --- a/include/jsx_common.hrl +++ b/include/jsx_common.hrl @@ -69,7 +69,7 @@ -type jsx_parser_result() :: {event, jsx_event(), fun(() -> jsx_parser_result())} | {incomplete, jsx_parser()} - | {error, badjson}. + | {error, {badjson, binary()}}. -type supported_utf() :: utf8 diff --git a/include/jsx_decoder.hrl b/include/jsx_decoder.hrl index 4baadcf..aeccead 100644 --- a/include/jsx_decoder.hrl +++ b/include/jsx_decoder.hrl @@ -183,11 +183,11 @@ start(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> start(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -211,11 +211,11 @@ maybe_done(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> maybe_done(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -226,7 +226,7 @@ done(<>, #opts{comments=true}=Opts) -> done(<<>>, Opts) -> {event, end_json, fun() -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, <<>>}} ; (Stream) -> done(Stream, Opts) end} @@ -235,11 +235,11 @@ done(Bin, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> done(<>, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -258,11 +258,11 @@ object(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> object(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -294,11 +294,11 @@ array(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> array(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -328,11 +328,11 @@ value(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> value(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -346,11 +346,11 @@ colon(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> colon(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -367,11 +367,11 @@ key(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> key(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -390,7 +390,7 @@ unquoted_key(Bin, Stack, Opts, Acc) -> case partial_utf(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> unquoted_key(<>, Stack, @@ -398,7 +398,7 @@ unquoted_key(Bin, Stack, Opts, Acc) -> Acc ) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -423,11 +423,11 @@ string(Bin, Stack, Opts, Acc) -> case partial_utf(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> string(<>, Stack, Opts, Acc) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -506,11 +506,11 @@ escape(Bin, Stack, Opts, Acc) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> escape(<>, Stack, Opts, Acc) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -571,7 +571,7 @@ escaped_unicode(Bin, Stack, Opts, String, Acc) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> escaped_unicode(<>, Stack, @@ -580,7 +580,7 @@ escaped_unicode(Bin, Stack, Opts, String, Acc) -> Acc ) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -613,11 +613,11 @@ negative(Bin, Stack, Opts, Acc) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> negative(<>, Stack, Opts, Acc) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -656,11 +656,11 @@ zero(Bin, Stack, Opts, Acc) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> zero(<>, Stack, Opts, Acc) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -711,11 +711,11 @@ integer(Bin, Stack, Opts, Acc) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> integer(<>, Stack, Opts, Acc) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -728,7 +728,7 @@ initial_decimal(Bin, Stack, Opts, Acc) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> initial_decimal(<>, Stack, @@ -736,7 +736,7 @@ initial_decimal(Bin, Stack, Opts, Acc) -> Acc ) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -785,11 +785,11 @@ decimal(Bin, Stack, Opts, Acc) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> decimal(<>, Stack, Opts, Acc) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -803,11 +803,11 @@ e(Bin, Stack, Opts, Acc) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> e(<>, Stack, Opts, Acc) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -818,11 +818,11 @@ ex(Bin, Stack, Opts, Acc) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> ex(<>, Stack, Opts, Acc) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -863,11 +863,11 @@ exp(Bin, Stack, Opts, Acc) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> exp(<>, Stack, Opts, Acc) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -877,11 +877,11 @@ tr(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> tr(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -891,11 +891,11 @@ tru(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> tru(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -905,11 +905,11 @@ true(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> true(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -919,11 +919,11 @@ fa(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> fa(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -933,11 +933,11 @@ fal(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> fal(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -947,11 +947,11 @@ fals(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> fals(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -961,11 +961,11 @@ false(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> false(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -975,11 +975,11 @@ nu(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> nu(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -989,11 +989,11 @@ nul(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> nul(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -1003,11 +1003,11 @@ null(Bin, Stack, Opts) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> null(<>, Stack, Opts) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -1022,11 +1022,11 @@ maybe_comment(Bin, Resume) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> maybe_comment(<>, Resume) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -1038,11 +1038,11 @@ comment(Bin, Resume) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> comment(<>, Resume) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. @@ -1054,9 +1054,9 @@ maybe_comment_done(Bin, Resume) -> case ?partial_codepoint(Bin) of true -> {incomplete, fun(end_stream) -> - {error, badjson} + {error, {badjson, Bin}} ; (Stream) -> maybe_comment_done(<>, Resume) end} - ; false -> {error, badjson} + ; false -> {error, {badjson, Bin}} end. \ No newline at end of file diff --git a/src/jsx.erl b/src/jsx.erl index 563888b..58c678f 100644 --- a/src/jsx.erl +++ b/src/jsx.erl @@ -50,7 +50,7 @@ %% @type jsx_parser_result() = {event, jsx_event(), (() -> jsx_parser_result())} %% | {incomplete, jsx_parser()} -%% | {error, badjson} +%% | {error, {badjson, binary()}} %% | {error, badarg}. %% @type jsx_event() = start_object @@ -490,7 +490,7 @@ detect_encoding(<>, Opts) when X =/= 0 -> try {incomplete, Next} = (jsx_utf8:parser(Opts))(<>), Next(end_stream) - catch error:function_clause -> {error, badjson} + catch error:function_clause -> {error, {badjson, <>}} end ; (Stream) -> detect_encoding(<>, Opts) end @@ -501,7 +501,7 @@ detect_encoding(<<0, X>>, Opts) when X =/= 0 -> try {incomplete, Next} = (jsx_utf16:parser(Opts))(<<0, X>>), Next(end_stream) - catch error:function_clause -> {error, badjson} + catch error:function_clause -> {error, {badjson, <<0, X>>}} end ; (Stream) -> detect_encoding(<<0, X, Stream/binary>>, Opts) end @@ -512,7 +512,7 @@ detect_encoding(<>, Opts) when X =/= 0 -> try {incomplete, Next} = (jsx_utf16le:parser(Opts))(<>), Next(end_stream) - catch error:function_clause -> {error, badjson} + catch error:function_clause -> {error, {badjson, <>}} end ; (Stream) -> detect_encoding(<>, Opts) end @@ -521,7 +521,7 @@ detect_encoding(<>, Opts) when X =/= 0 -> %% not enough input, request more detect_encoding(Bin, Opts) -> {incomplete, - fun(end_stream) -> {error, badjson} + fun(end_stream) -> {error, {badjson, Bin}} ; (Stream) -> detect_encoding(<>, Opts) end }.