{unquoted_keys, true | false} now allows control of whether unquoted object keys are rejected or not by the parser/eep0018 decoder

This commit is contained in:
alisdair sullivan 2010-09-23 22:08:34 -07:00
parent b73e506fe2
commit 098fcbab1e
3 changed files with 61 additions and 0 deletions

View file

@ -32,6 +32,7 @@
-record(opts, { -record(opts, {
comments = false, comments = false,
escaped_unicode = codepoint, escaped_unicode = codepoint,
unquoted_keys = false,
multi_term = false, multi_term = false,
encoding = auto encoding = auto
}). }).
@ -143,6 +144,9 @@ parse_opts([{comments, Value}|Rest], Opts) ->
parse_opts([{escaped_unicode, Value}|Rest], Opts) -> parse_opts([{escaped_unicode, Value}|Rest], Opts) ->
true = lists:member(Value, [ascii, codepoint, none]), true = lists:member(Value, [ascii, codepoint, none]),
parse_opts(Rest, Opts#opts{escaped_unicode=Value}); parse_opts(Rest, Opts#opts{escaped_unicode=Value});
parse_opts([{unquoted_keys, Value}|Rest], Opts) ->
true = lists:member(Value, [true, false]),
parse_opts(Rest, Opts#opts{unquoted_keys=Value});
parse_opts([{multi_term, Value}|Rest], Opts) -> parse_opts([{multi_term, Value}|Rest], Opts) ->
true = lists:member(Value, [true, false]), true = lists:member(Value, [true, false]),
parse_opts(Rest, Opts#opts{multi_term=Value}); parse_opts(Rest, Opts#opts{multi_term=Value});
@ -247,6 +251,9 @@ object(<<?end_object/?utfx, Rest/binary>>, [key|Stack], Opts) ->
{event, end_object, fun() -> maybe_done(Rest, Stack, Opts) end}; {event, end_object, fun() -> maybe_done(Rest, Stack, Opts) end};
object(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts) -> object(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts) ->
maybe_comment(Rest, fun(Resume) -> object(Resume, Stack, Opts) end); maybe_comment(Rest, fun(Resume) -> object(Resume, Stack, Opts) end);
object(<<S/?utfx, Rest/binary>>, Stack, #opts{unquoted_keys=true}=Opts)
when ?is_noncontrol(S) ->
unquoted_key(Rest, Stack, Opts, [S]);
object(Bin, Stack, Opts) -> object(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of case ?partial_codepoint(Bin) of
true -> true ->
@ -353,6 +360,9 @@ key(<<?quote/?utfx, Rest/binary>>, Stack, Opts) ->
string(Rest, Stack, Opts, []); string(Rest, Stack, Opts, []);
key(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts) -> key(<<?solidus/?utfx, Rest/binary>>, Stack, #opts{comments=true}=Opts) ->
maybe_comment(Rest, fun(Resume) -> key(Resume, Stack, Opts) end); maybe_comment(Rest, fun(Resume) -> key(Resume, Stack, Opts) end);
key(<<S/?utfx, Rest/binary>>, Stack, #opts{unquoted_keys=true}=Opts)
when ?is_noncontrol(S) ->
unquoted_key(Rest, Stack, Opts, [S]);
key(Bin, Stack, Opts) -> key(Bin, Stack, Opts) ->
case ?partial_codepoint(Bin) of case ?partial_codepoint(Bin) of
true -> true ->
@ -365,6 +375,33 @@ key(Bin, Stack, Opts) ->
end. end.
unquoted_key(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc)
when ?is_whitespace(S) ->
{event, {key, lists:reverse(Acc)}, fun() -> colon(Rest, Stack, Opts) end};
unquoted_key(<<?colon/?utfx, Rest/binary>>, [key|Stack], Opts, Acc) ->
{event,
{key, lists:reverse(Acc)},
fun() -> value(Rest, [object|Stack], Opts) end
};
unquoted_key(<<S/?utfx, Rest/binary>>, Stack, Opts, Acc)
when ?is_noncontrol(S) ->
unquoted_key(Rest, Stack, Opts, [S] ++ Acc);
unquoted_key(Bin, Stack, Opts, Acc) ->
case partial_utf(Bin) of
true ->
{incomplete, fun(end_stream) ->
{error, badjson}
; (Stream) ->
unquoted_key(<<Bin/binary, Stream/binary>>,
Stack,
Opts,
Acc
)
end}
; false -> {error, badjson}
end.
%% string has an additional parameter, an accumulator (Acc) used to hold the %% string has an additional parameter, an accumulator (Acc) used to hold the
%% intermediate representation of the string being parsed. using a list of %% intermediate representation of the string being parsed. using a list of
%% integers representing unicode codepoints is faster than constructing %% integers representing unicode codepoints is faster than constructing

View file

@ -0,0 +1 @@
{foo : "bar", baz:true, false : null,object:{ key : "value" },list:[null,null,null,[],"\n\r\\"]}

View file

@ -0,0 +1,23 @@
{name, "object with unquoted keys"}.
{jsx, [start_object,
{key,"foo"},
{string,"bar"},
{key,"baz"},
{literal,true},
{key,"false"},
{literal,null},
{key,"object"},
start_object,
{key,"key"},
{string,"value"},
end_object,
{key,"list"},
start_array,
{literal,null},
{literal,null},
{literal,null},
start_array,end_array,
{string,"\n\r\\"},
end_array,end_object,end_json]}.
{json, "object_with_unquoted_keys.json"}.
{jsx_flags, [{unquoted_keys, true}]}.