the option single_quotes in functions dealing with json inputs now allows json that uses single quotes to deliminate keys and strings to be processed, note that this changes the escaping rules slightly

This commit is contained in:
alisdair sullivan 2012-03-14 23:01:59 -07:00
parent b3d9f5e6ff
commit 1d5b9e7410
5 changed files with 91 additions and 13 deletions

View file

@ -59,7 +59,8 @@ decoder(Handler, State, Opts) ->
%% kv seperator
-define(comma, 16#2C).
-define(quote, 16#22).
-define(doublequote, 16#22).
-define(singlequote, 16#27).
-define(colon, 16#3A).
%% string escape sequences
@ -130,7 +131,9 @@ decoder(Handler, State, Opts) ->
-define(end_seq(Seq), unicode:characters_to_binary(lists:reverse(Seq))).
value(<<?quote, Rest/binary>>, Handler, Stack, Opts) ->
value(<<?doublequote, Rest/binary>>, Handler, Stack, Opts) ->
string(Rest, Handler, [?new_seq()|Stack], Opts);
value(<<?singlequote, Rest/binary>>, Handler, Stack, Opts = #opts{single_quotes=true}) ->
string(Rest, Handler, [?new_seq()|Stack], Opts);
value(<<$t, Rest/binary>>, Handler, Stack, Opts) ->
tr(Rest, Handler, Stack, Opts);
@ -156,7 +159,9 @@ value(Bin, Handler, Stack, Opts) ->
?error([Bin, Handler, Stack, Opts]).
object(<<?quote, Rest/binary>>, Handler, Stack, Opts) ->
object(<<?doublequote, Rest/binary>>, Handler, Stack, Opts) ->
string(Rest, Handler, [?new_seq()|Stack], Opts);
object(<<?singlequote, Rest/binary>>, Handler, Stack, Opts = #opts{single_quotes=true}) ->
string(Rest, Handler, [?new_seq()|Stack], Opts);
object(<<?end_object, Rest/binary>>, {Handler, State}, [key|Stack], Opts) ->
maybe_done(Rest, {Handler, Handler:handle_event(end_object, State)}, Stack, Opts);
@ -168,7 +173,9 @@ object(Bin, Handler, Stack, Opts) ->
?error([Bin, Handler, Stack, Opts]).
array(<<?quote, Rest/binary>>, Handler, Stack, Opts) ->
array(<<?doublequote, Rest/binary>>, Handler, Stack, Opts) ->
string(Rest, Handler, [?new_seq()|Stack], Opts);
array(<<?singlequote, Rest/binary>>, Handler, Stack, Opts = #opts{single_quotes=true}) ->
string(Rest, Handler, [?new_seq()|Stack], Opts);
array(<<$t, Rest/binary>>, Handler, Stack, Opts) ->
tr(Rest, Handler, Stack, Opts);
@ -206,7 +213,9 @@ colon(Bin, Handler, Stack, Opts) ->
?error([Bin, Handler, Stack, Opts]).
key(<<?quote, Rest/binary>>, Handler, Stack, Opts) ->
key(<<?doublequote, Rest/binary>>, Handler, Stack, Opts) ->
string(Rest, Handler, [?new_seq()|Stack], Opts);
key(<<?singlequote, Rest/binary>>, Handler, Stack, Opts = #opts{single_quotes=true}) ->
string(Rest, Handler, [?new_seq()|Stack], Opts);
key(<<S, Rest/binary>>, Handler, Stack, Opts) when ?is_whitespace(S) ->
key(Rest, Handler, Stack, Opts);
@ -233,13 +242,25 @@ partial_utf(<<X, Y, Z>>)
partial_utf(_) -> false.
string(<<?quote/utf8, Rest/binary>>, {Handler, State}, [Acc, key|Stack], Opts) ->
string(<<?doublequote, Rest/binary>>, {Handler, State}, [Acc, key|Stack], Opts) ->
colon(Rest,
{Handler, Handler:handle_event({key, ?end_seq(Acc)}, State)},
[key|Stack],
Opts
);
string(<<?quote/utf8, Rest/binary>>, {Handler, State}, [Acc|Stack], Opts) ->
string(<<?singlequote, Rest/binary>>, {Handler, State}, [Acc, key|Stack], Opts = #opts{single_quotes=true}) ->
colon(Rest,
{Handler, Handler:handle_event({key, ?end_seq(Acc)}, State)},
[key|Stack],
Opts
);
string(<<?doublequote, Rest/binary>>, {Handler, State}, [Acc|Stack], Opts) ->
maybe_done(Rest,
{Handler, Handler:handle_event({string, ?end_seq(Acc)}, State)},
Stack,
Opts
);
string(<<?singlequote, Rest/binary>>, {Handler, State}, [Acc|Stack], Opts = #opts{single_quotes=true}) ->
maybe_done(Rest,
{Handler, Handler:handle_event({string, ?end_seq(Acc)}, State)},
Stack,
@ -318,8 +339,10 @@ escape(<<$t, Rest/binary>>, Handler, [Acc|Stack], Opts) ->
escape(<<$u, Rest/binary>>, Handler, Stack, Opts) ->
escaped_unicode(Rest, Handler, [?new_seq()|Stack], Opts);
escape(<<S, Rest/binary>>, Handler, [Acc|Stack], Opts)
when S =:= ?quote; S =:= ?solidus; S =:= ?rsolidus ->
when S =:= ?doublequote; S =:= ?solidus; S =:= ?rsolidus ->
string(Rest, Handler, [?acc_seq(Acc, S)|Stack], Opts);
escape(<<?singlequote, Rest/binary>>, Handler, [Acc|Stack], Opts = #opts{single_quotes=true}) ->
string(Rest, Handler, [?acc_seq(Acc, ?singlequote)|Stack], Opts);
escape(<<>>, Handler, Stack, Opts) ->
?incomplete(escape, <<>>, Handler, Stack, Opts);
escape(Bin, Handler, Stack, Opts) ->