added naked (unwrapped) values option and rewrote the handling of comments to reduce line count and be slightly clearer

This commit is contained in:
alisdair sullivan 2010-05-18 12:41:32 -07:00
parent 121fe34474
commit 5c36ec18d7
2 changed files with 45 additions and 83 deletions

View file

@ -1,6 +1,7 @@
-record(opts, {
comments = false,
escaped_unicode = ascii
escaped_unicode = ascii,
naked_values = false
}).
%% whitespace

View file

@ -12,23 +12,32 @@ callback(Event, Callbacks) ->
%% this code is mostly autogenerated and mostly ugly. apologies. for more insight on
%% Callbacks or Opts, see the comments accompanying callback/2 (in this file) and
%% parse_opts/1 (in jsx.erl). Stack is a stack of flags used to track depth. all
%% pops, peeks and pushes are inlined. comments are handled in function to get around
%% a limitation of erlang's binary matching optimizations, and a function_clause
%% error is raised if comments are disallowed to maintain consistency with behaviour
%% of other invalid input
%% parse_opts/1 (in jsx.erl). Stack is a stack of flags used to track depth and to
%% keep track of whether we are returning from a value or a key inside objects. all
%% pops, peeks and pushes are inlined. the code that handles naked values and comments
%% is not optimized by the compiler for efficient matching, but you shouldn't be using
%% naked values or comments anyways, they are horrible and contrary to the spec.
start(<<?start_object/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
object(Rest, [key|Stack], callback(start_object, Callbacks), Opts);
start(<<?start_array/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
array(Rest, [array|Stack], callback(start_array, Callbacks), Opts);
start(<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
case Opts#opts.comments of
true ->
maybe_comment(Rest, fun(Resume) -> start(Resume, Stack, Callbacks, Opts) end)
; false ->
erlang:error(function_clause, [<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts])
end;
start(<<?quote/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.naked_values == true ->
string(Rest, Stack, Callbacks, Opts, []);
start(<<$t/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.naked_values == true ->
tr(Rest, Stack, Callbacks, Opts);
start(<<$f/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.naked_values == true ->
fa(Rest, Stack, Callbacks, Opts);
start(<<$n/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.naked_values == true ->
nu(Rest, Stack, Callbacks, Opts);
start(<<?negative/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.naked_values == true ->
negative(Rest, Stack, Callbacks, Opts, "-");
start(<<?zero/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.naked_values == true ->
zero(Rest, Stack, Callbacks, Opts, "0");
start(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts) when ?is_nonzero(S), Opts#opts.naked_values == true ->
integer(Rest, Stack, Callbacks, Opts, [S]);
start(<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.comments == true ->
maybe_comment(Rest, fun(Resume) -> start(Resume, Stack, Callbacks, Opts) end);
start(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts) when ?is_whitespace(S) ->
start(Rest, Stack, Callbacks, Opts);
start(<<>>, Stack, Callbacks, Opts) ->
@ -43,13 +52,8 @@ maybe_done(<<?comma/utf8, Rest/binary>>, [object|Stack], Callbacks, Opts) ->
key(Rest, [key|Stack], Callbacks, Opts);
maybe_done(<<?comma/utf8, Rest/binary>>, [array|_] = Stack, Callbacks, Opts) ->
value(Rest, Stack, Callbacks, Opts);
maybe_done(<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
case Opts#opts.comments of
true ->
maybe_comment(Rest, fun(Resume) -> maybe_done(Resume, Stack, Callbacks, Opts) end)
; false ->
erlang:error(function_clause, [<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts])
end;
maybe_done(<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.comments == true ->
maybe_comment(Rest, fun(Resume) -> maybe_done(Resume, Stack, Callbacks, Opts) end);
maybe_done(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts) when ?is_whitespace(S) ->
maybe_done(Rest, Stack, Callbacks, Opts);
maybe_done(<<>>, [], Callbacks, _Opts) ->
@ -62,13 +66,8 @@ object(<<?end_object/utf8, Rest/binary>>, [key|Stack], Callbacks, Opts) ->
maybe_done(Rest, Stack, callback(end_object, Callbacks), Opts);
object(<<?quote/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
string(Rest, Stack, Callbacks, Opts, []);
object(<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
case Opts#opts.comments of
true ->
maybe_comment(Rest, fun(Resume) -> object(Resume, Stack, Callbacks, Opts) end)
; false ->
erlang:error(function_clause, [<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts])
end;
object(<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.comments == true ->
maybe_comment(Rest, fun(Resume) -> object(Resume, Stack, Callbacks, Opts) end);
object(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts) when ?is_whitespace(S) ->
object(Rest, Stack, Callbacks, Opts);
object(<<>>, Stack, Callbacks, Opts) ->
@ -95,13 +94,8 @@ array(<<?zero/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
zero(Rest, Stack, Callbacks, Opts, "0");
array(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts) when ?is_nonzero(S) ->
integer(Rest, Stack, Callbacks, Opts, [S]);
array(<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
case Opts#opts.comments of
true ->
maybe_comment(Rest, fun(Resume) -> array(Resume, Stack, Callbacks, Opts) end)
; false ->
erlang:error(function_clause, [<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts])
end;
array(<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.comments == true ->
maybe_comment(Rest, fun(Resume) -> array(Resume, Stack, Callbacks, Opts) end);
array(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts) when ?is_whitespace(S) ->
array(Rest, Stack, Callbacks, Opts);
array(<<>>, Stack, Callbacks, Opts) ->
@ -126,13 +120,8 @@ value(<<?zero/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
zero(Rest, Stack, Callbacks, Opts, "0");
value(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts) when ?is_nonzero(S) ->
integer(Rest, Stack, Callbacks, Opts, [S]);
value(<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
case Opts#opts.comments of
true ->
maybe_comment(Rest, fun(Resume) -> value(Resume, Stack, Callbacks, Opts) end)
; false ->
erlang:error(function_clause, [<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts])
end;
value(<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.comments == true ->
maybe_comment(Rest, fun(Resume) -> value(Resume, Stack, Callbacks, Opts) end);
value(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts) when ?is_whitespace(S) ->
value(Rest, Stack, Callbacks, Opts);
value(<<>>, Stack, Callbacks, Opts) ->
@ -141,13 +130,8 @@ value(<<>>, Stack, Callbacks, Opts) ->
colon(<<?colon/utf8, Rest/binary>>, [key|Stack], Callbacks, Opts) ->
value(Rest, [object|Stack], Callbacks, Opts);
colon(<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
case Opts#opts.comments of
true ->
maybe_comment(Rest, fun(Resume) -> colon(Resume, Stack, Callbacks, Opts) end)
; false ->
erlang:error(function_clause, [<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts])
end;
colon(<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.comments == true ->
maybe_comment(Rest, fun(Resume) -> colon(Resume, Stack, Callbacks, Opts) end);
colon(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts) when ?is_whitespace(S) ->
colon(Rest, Stack, Callbacks, Opts);
colon(<<>>, Stack, Callbacks, Opts) ->
@ -156,13 +140,8 @@ colon(<<>>, Stack, Callbacks, Opts) ->
key(<<?quote/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
string(Rest, Stack, Callbacks, Opts, []);
key(<<?rsolidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) ->
case Opts#opts.comments of
true ->
maybe_comment(Rest, fun(Resume) -> key(Resume, Stack, Callbacks, Opts) end)
; false ->
erlang:error(function_clause, [<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts])
end;
key(<<?rsolidus/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.comments == true ->
maybe_comment(Rest, fun(Resume) -> key(Resume, Stack, Callbacks, Opts) end);
key(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts) when ?is_whitespace(S) ->
key(Rest, Stack, Callbacks, Opts);
key(<<>>, Stack, Callbacks, Opts) ->
@ -237,6 +216,8 @@ escaped_unicode(<<>>, Stack, Callbacks, Opts, String, Acc) ->
%% being emitted to the callback handler. no processing of numbers is done in
%% process, it's left for the user, though there are convenience functions to
%% convert them into erlang floats/integers in jsx_utils.erl.
%% TODO: actually write that jsx_utils.erl module mentioned above...
negative(<<"0"/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) ->
zero(Rest, Stack, Callbacks, Opts, "0" ++ Acc);
@ -258,13 +239,8 @@ zero(<<?decimalpoint/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) ->
fraction(Rest, Stack, Callbacks, Opts, [?decimalpoint] ++ Acc);
zero(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) ->
maybe_done(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts);
zero(<<?rsolidus/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) ->
case Opts#opts.comments of
true ->
maybe_comment(Rest, fun(Resume) -> zero(Resume, Stack, Callbacks, Opts, Acc) end)
; false ->
erlang:error(function_clause, [<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts])
end;
zero(<<?rsolidus/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true ->
maybe_comment(Rest, fun(Resume) -> zero(Resume, Stack, Callbacks, Opts, Acc) end);
zero(<<>>, Stack, Callbacks, Opts, Acc) ->
fun(Stream) -> zero(Stream, Stack, Callbacks, Opts, Acc) end.
@ -289,13 +265,8 @@ integer(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) when ?is_nonzero(S
integer(Rest, Stack, Callbacks, Opts, [S] ++ Acc);
integer(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) ->
maybe_done(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts);
integer(<<?rsolidus/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) ->
case Opts#opts.comments of
true ->
maybe_comment(Rest, fun(Resume) -> integer(Resume, Stack, Callbacks, Opts, Acc) end)
; false ->
erlang:error(function_clause, [<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts])
end;
integer(<<?rsolidus/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true ->
maybe_comment(Rest, fun(Resume) -> integer(Resume, Stack, Callbacks, Opts, Acc) end);
integer(<<>>, Stack, Callbacks, Opts, Acc) ->
fun(Stream) -> integer(Stream, Stack, Callbacks, Opts, Acc) end.
@ -318,13 +289,8 @@ fraction(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) when ?is_nonzero(
fraction(Rest, Stack, Callbacks, Opts, [S] ++ Acc);
fraction(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) ->
maybe_done(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts);
fraction(<<?rsolidus/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) ->
case Opts#opts.comments of
true ->
maybe_comment(Rest, fun(Resume) -> fraction(Resume, Stack, Callbacks, Opts, Acc) end)
; false ->
erlang:error(function_clause, [<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts])
end;
fraction(<<?rsolidus/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true ->
maybe_comment(Rest, fun(Resume) -> fraction(Resume, Stack, Callbacks, Opts, Acc) end);
fraction(<<>>, Stack, Callbacks, Opts, Acc) ->
fun(Stream) -> fraction(Stream, Stack, Callbacks, Opts, Acc) end.
@ -357,13 +323,8 @@ exp(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) when ?is_nonzero(S) ->
exp(Rest, Stack, Callbacks, Opts, [S] ++ Acc);
exp(<<S/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) ->
maybe_done(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts);
exp(<<?rsolidus/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) ->
case Opts#opts.comments of
true ->
maybe_comment(Rest, fun(Resume) -> exp(Resume, Stack, Callbacks, Opts, Acc) end)
; false ->
erlang:error(function_clause, [<<?solidus/utf8, Rest/binary>>, Stack, Callbacks, Opts])
end;
exp(<<?rsolidus/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true ->
maybe_comment(Rest, fun(Resume) -> exp(Resume, Stack, Callbacks, Opts, Acc) end);
exp(<<>>, Stack, Callbacks, Opts, Acc) ->
fun(Stream) -> exp(Stream, Stack, Callbacks, Opts, Acc) end.