general cleanup of modules, moved most types, specs, defines and records to header files and did some minor reformatting to adhere to style guidelines
This commit is contained in:
parent
86b4fbbec9
commit
c098b06e88
16 changed files with 247 additions and 147 deletions
51
include/jsx.hrl
Normal file
51
include/jsx.hrl
Normal file
|
@ -0,0 +1,51 @@
|
|||
%% The MIT License
|
||||
|
||||
%% Copyright (c) 2010 Alisdair Sullivan <alisdairsullivan@yahoo.ca>
|
||||
|
||||
%% Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
%% of this software and associated documentation files (the "Software"), to deal
|
||||
%% in the Software without restriction, including without limitation the rights
|
||||
%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
%% copies of the Software, and to permit persons to whom the Software is
|
||||
%% furnished to do so, subject to the following conditions:
|
||||
|
||||
%% The above copyright notice and this permission notice shall be included in
|
||||
%% all copies or substantial portions of the Software.
|
||||
|
||||
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
%% THE SOFTWARE.
|
||||
|
||||
-include("jsx_common.hrl").
|
||||
|
||||
|
||||
|
||||
%% opts record
|
||||
-record(opts, {
|
||||
comments = false,
|
||||
escaped_unicode = codepoint,
|
||||
multi_term = false,
|
||||
encoding = auto
|
||||
}).
|
||||
|
||||
|
||||
-spec parser() -> jsx_parser().
|
||||
-spec parser(Opts::jsx_opts()) -> jsx_parser().
|
||||
|
||||
-spec term_to_json(JSON::eep0018()) -> binary().
|
||||
-spec term_to_json(JSON::eep0018(), Opts::encoder_opts()) -> binary().
|
||||
|
||||
-spec json_to_term(JSON::binary()) -> eep0018().
|
||||
-spec json_to_term(JSON::binary(), Opts::decoder_opts()) -> eep0018().
|
||||
|
||||
-spec is_json(JSON::binary()) -> true | false.
|
||||
-spec is_json(JSON::binary(), Opts::verify_opts()) -> true | false.
|
||||
|
||||
-spec format(JSON::binary()) -> binary() | iolist().
|
||||
-spec format(JSON::binary(), Opts::format_opts()) -> binary() | iolist().
|
||||
|
||||
-spec eventify(List::list()) -> jsx_parser_result().
|
|
@ -21,8 +21,10 @@
|
|||
%% THE SOFTWARE.
|
||||
|
||||
|
||||
%% unsure of how to specify a binary with a complex structure like utfx encoded
|
||||
%% binaries. this should be further limited somehow probably.
|
||||
|
||||
-define(is_utf_encoding(X),
|
||||
X == utf8; X == utf16; X == utf32; X == {utf16, little}; X == {utf32, little}
|
||||
).
|
||||
|
||||
|
||||
-type jsx_opts() :: [jsx_opt()].
|
||||
|
@ -33,7 +35,6 @@
|
|||
|
||||
|
||||
%% events emitted by the parser and component types
|
||||
|
||||
-type unicode_codepoint() :: 0..16#10ffff.
|
||||
-type unicode_string() :: [unicode_codepoint()].
|
||||
|
||||
|
@ -52,7 +53,6 @@
|
|||
|
||||
|
||||
%% this probably doesn't work properly
|
||||
|
||||
-type jsx_parser() :: fun((binary()) -> jsx_parser_result()).
|
||||
|
||||
-type jsx_parser_result() :: {event, jsx_event(), fun(() -> jsx_parser_result())}
|
||||
|
@ -61,6 +61,10 @@
|
|||
| ok.
|
||||
|
||||
|
||||
-type supported_utf() :: utf8 | utf16 | {utf16, little} | utf32 | {utf32, little}.
|
||||
|
||||
|
||||
%% eep0018 json specification
|
||||
-type eep0018() :: eep0018_object() | eep0018_array().
|
||||
|
||||
-type eep0018_array() :: [eep0018_term()].
|
||||
|
@ -75,9 +79,6 @@
|
|||
-type eep0018_number() :: float() | integer().
|
||||
|
||||
|
||||
-type supported_utf() :: utf8 | utf16 | {utf16, little} | utf32 | {utf32, little}.
|
||||
|
||||
|
||||
-type encoder_opts() :: [encoder_opt()].
|
||||
-type encoder_opt() :: {strict, true | false}
|
||||
| {encoding, supported_utf()}
|
||||
|
@ -87,7 +88,6 @@
|
|||
| indent.
|
||||
|
||||
|
||||
|
||||
-type decoder_opts() :: [decoder_opt()].
|
||||
-type decoder_opt() :: {strict, true | false}
|
||||
| {comments, true | false}
|
|
@ -20,6 +20,13 @@
|
|||
%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
%% THE SOFTWARE.
|
||||
|
||||
-include("./include/jsx_common.hrl").
|
||||
|
||||
|
||||
|
||||
-spec parse(JSON::eep0018(), Opts::jsx_opts()) -> jsx_parser_result().
|
||||
|
||||
|
||||
%% option flags
|
||||
|
||||
-define(comments_enabled(X), {_, true, _, _, _} = X).
|
||||
|
|
30
include/jsx_eep0018.hrl
Normal file
30
include/jsx_eep0018.hrl
Normal file
|
@ -0,0 +1,30 @@
|
|||
%% The MIT License
|
||||
|
||||
%% Copyright (c) 2010 Alisdair Sullivan <alisdairsullivan@yahoo.ca>
|
||||
|
||||
%% Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
%% of this software and associated documentation files (the "Software"), to deal
|
||||
%% in the Software without restriction, including without limitation the rights
|
||||
%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
%% copies of the Software, and to permit persons to whom the Software is
|
||||
%% furnished to do so, subject to the following conditions:
|
||||
|
||||
%% The above copyright notice and this permission notice shall be included in
|
||||
%% all copies or substantial portions of the Software.
|
||||
|
||||
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
%% THE SOFTWARE.
|
||||
|
||||
-include("jsx_common.hrl").
|
||||
|
||||
|
||||
|
||||
-spec json_to_term(JSON::binary(), Opts::decoder_opts()) -> eep0018().
|
||||
|
||||
-spec term_to_json(JSON::eep0018(), Opts::encoder_opts()) -> binary().
|
||||
|
46
include/jsx_format.hrl
Normal file
46
include/jsx_format.hrl
Normal file
|
@ -0,0 +1,46 @@
|
|||
%% The MIT License
|
||||
|
||||
%% Copyright (c) 2010 Alisdair Sullivan <alisdairsullivan@yahoo.ca>
|
||||
|
||||
%% Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
%% of this software and associated documentation files (the "Software"), to deal
|
||||
%% in the Software without restriction, including without limitation the rights
|
||||
%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
%% copies of the Software, and to permit persons to whom the Software is
|
||||
%% furnished to do so, subject to the following conditions:
|
||||
|
||||
%% The above copyright notice and this permission notice shall be included in
|
||||
%% all copies or substantial portions of the Software.
|
||||
|
||||
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
%% THE SOFTWARE.
|
||||
|
||||
-include("jsx_common.hrl").
|
||||
|
||||
|
||||
|
||||
-record(opts, {
|
||||
space = 0,
|
||||
indent = 0,
|
||||
output_encoding = utf8,
|
||||
strict = true
|
||||
}).
|
||||
|
||||
|
||||
-define(newline, $\n).
|
||||
-define(space, 16#20). %% ascii code for space
|
||||
-define(quote, $\").
|
||||
-define(comma, $,).
|
||||
-define(colon, $:).
|
||||
-define(start_object, ${).
|
||||
-define(end_object, $}).
|
||||
-define(start_array, $[).
|
||||
-define(end_array, $]).
|
||||
|
||||
|
||||
-spec format(JSON::binary(), Opts::format_opts()) -> binary() | iolist().
|
27
include/jsx_verify.hrl
Normal file
27
include/jsx_verify.hrl
Normal file
|
@ -0,0 +1,27 @@
|
|||
%% The MIT License
|
||||
|
||||
%% Copyright (c) 2010 Alisdair Sullivan <alisdairsullivan@yahoo.ca>
|
||||
|
||||
%% Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
%% of this software and associated documentation files (the "Software"), to deal
|
||||
%% in the Software without restriction, including without limitation the rights
|
||||
%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
%% copies of the Software, and to permit persons to whom the Software is
|
||||
%% furnished to do so, subject to the following conditions:
|
||||
|
||||
%% The above copyright notice and this permission notice shall be included in
|
||||
%% all copies or substantial portions of the Software.
|
||||
|
||||
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
%% THE SOFTWARE.
|
||||
|
||||
-include("jsx_common.hrl").
|
||||
|
||||
|
||||
|
||||
-spec is_json(JSON::binary(), Opts::verify_opts()) -> true | false.
|
|
@ -29,15 +29,14 @@
|
|||
-module(?name).
|
||||
-author("alisdairsullivan@yahoo.ca").
|
||||
|
||||
|
||||
-export([parse/2]).
|
||||
|
||||
|
||||
-include("./include/jsx_decoder.hrl").
|
||||
-include("./include/jsx_types.hrl").
|
||||
|
||||
|
||||
|
||||
-spec parse(JSON::eep0018(), Opts::jsx_opts()) -> jsx_parser_result().
|
||||
|
||||
parse(JSON, Opts) ->
|
||||
start(JSON, [], Opts).
|
||||
|
||||
|
@ -70,6 +69,7 @@ start(Bin, Stack, Opts) ->
|
|||
; false -> {error, badjson}
|
||||
end.
|
||||
|
||||
|
||||
maybe_done(<<S/?encoding, Rest/binary>>, Stack, Opts) when ?is_whitespace(S) ->
|
||||
maybe_done(Rest, Stack, Opts);
|
||||
maybe_done(<<?end_object/?encoding, Rest/binary>>, [object|Stack], Opts) ->
|
||||
|
@ -92,6 +92,7 @@ maybe_done(Bin, Stack, Opts) ->
|
|||
; false -> {error, badjson}
|
||||
end.
|
||||
|
||||
|
||||
done(<<S/?encoding, Rest/binary>>, Opts) when ?is_whitespace(S) ->
|
||||
done(Rest, Opts);
|
||||
done(<<?solidus/?encoding, Rest/binary>>, ?comments_enabled(Opts)) ->
|
||||
|
@ -348,6 +349,7 @@ escaped_unicode(Bin, Stack, Opts, String, Acc) ->
|
|||
; false -> {error, badjson}
|
||||
end.
|
||||
|
||||
|
||||
%% upon encountering a low pair json/hex encoded value, check to see if there's a high
|
||||
%% value already in the accumulator
|
||||
check_acc_for_surrogate([D, C, B, A, $u, ?rsolidus|Rest])
|
||||
|
@ -361,6 +363,7 @@ check_acc_for_surrogate([D, C, B, A, $u, ?rsolidus|Rest])
|
|||
check_acc_for_surrogate(_) ->
|
||||
false.
|
||||
|
||||
|
||||
%% stole this from the unicode spec
|
||||
surrogate_to_codepoint(High, Low) ->
|
||||
(High - 16#d800) * 16#400 + (Low - 16#dc00) + 16#10000.
|
||||
|
|
30
src/jsx.erl
30
src/jsx.erl
|
@ -24,6 +24,7 @@
|
|||
-module(jsx).
|
||||
-author("alisdairsullivan@yahoo.ca").
|
||||
|
||||
|
||||
%% the core parser api
|
||||
-export([parser/0, parser/1]).
|
||||
-export([term_to_json/1, term_to_json/2]).
|
||||
|
@ -34,21 +35,9 @@
|
|||
|
||||
|
||||
%% types for function specifications
|
||||
-include("./include/jsx_types.hrl").
|
||||
-include("./include/jsx.hrl").
|
||||
|
||||
|
||||
%% opts record
|
||||
-record(opts, {
|
||||
comments = false,
|
||||
escaped_unicode = codepoint,
|
||||
multi_term = false,
|
||||
encoding = auto
|
||||
}).
|
||||
|
||||
|
||||
|
||||
-spec parser() -> jsx_parser().
|
||||
-spec parser(Opts::jsx_opts()) -> jsx_parser().
|
||||
|
||||
parser() ->
|
||||
parser([]).
|
||||
|
@ -68,9 +57,6 @@ parser(OptsList) ->
|
|||
end.
|
||||
|
||||
|
||||
-spec term_to_json(JSON::eep0018()) -> binary().
|
||||
-spec term_to_json(JSON::eep0018(), Opts::encoder_opts()) -> binary().
|
||||
|
||||
term_to_json(JSON) ->
|
||||
term_to_json(JSON, []).
|
||||
|
||||
|
@ -78,9 +64,6 @@ term_to_json(JSON, Opts) ->
|
|||
jsx_eep0018:term_to_json(JSON, Opts).
|
||||
|
||||
|
||||
-spec json_to_term(JSON::binary()) -> eep0018().
|
||||
-spec json_to_term(JSON::binary(), Opts::decoder_opts()) -> eep0018().
|
||||
|
||||
json_to_term(JSON) ->
|
||||
json_to_term(JSON, []).
|
||||
|
||||
|
@ -88,9 +71,6 @@ json_to_term(JSON, Opts) ->
|
|||
jsx_eep0018:json_to_term(JSON, Opts).
|
||||
|
||||
|
||||
-spec is_json(JSON::binary()) -> true | false.
|
||||
-spec is_json(JSON::binary(), Opts::verify_opts()) -> true | false.
|
||||
|
||||
is_json(JSON) ->
|
||||
is_json(JSON, []).
|
||||
|
||||
|
@ -98,9 +78,6 @@ is_json(JSON, Opts) ->
|
|||
jsx_verify:is_json(JSON, Opts).
|
||||
|
||||
|
||||
-spec format(JSON::binary()) -> binary() | iolist().
|
||||
-spec format(JSON::binary(), Opts::format_opts()) -> binary() | iolist().
|
||||
|
||||
format(JSON) ->
|
||||
format(JSON, []).
|
||||
|
||||
|
@ -108,11 +85,8 @@ format(JSON, Opts) ->
|
|||
jsx_format:format(JSON, Opts).
|
||||
|
||||
|
||||
-spec eventify(List::list()) -> jsx_parser_result().
|
||||
|
||||
%% fake the jsx api for any list, useful if you want to serialize a structure to
|
||||
%% json using the pretty printer, or verify a sequence could be valid json
|
||||
|
||||
eventify([]) ->
|
||||
fun() -> {incomplete, fun(List) when is_list(List) -> eventify(List); (_) -> erlang:error(badarg) end} end;
|
||||
eventify([Next|Rest]) ->
|
||||
|
|
|
@ -24,9 +24,12 @@
|
|||
-module(jsx_eep0018).
|
||||
-author("alisdairsullivan@yahoo.ca").
|
||||
|
||||
|
||||
-export([json_to_term/2, term_to_json/2]).
|
||||
|
||||
-include("./include/jsx_types.hrl").
|
||||
|
||||
-include("./include/jsx_eep0018.hrl").
|
||||
|
||||
|
||||
-ifdef(test).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
@ -34,8 +37,6 @@
|
|||
|
||||
|
||||
|
||||
-spec json_to_term(JSON::binary(), Opts::decoder_opts()) -> eep0018().
|
||||
|
||||
json_to_term(JSON, Opts) ->
|
||||
P = jsx:parser(opts_to_jsx_opts(Opts)),
|
||||
case proplists:get_value(strict, Opts, true) of
|
||||
|
@ -48,9 +49,6 @@ json_to_term(JSON, Opts) ->
|
|||
%% terms to json strings, but it expects a jsx event iterator. luckily, the mapping from
|
||||
%% erlang terms to jsx events is straightforward and the iterator can be faked with an
|
||||
%% anonymous function
|
||||
|
||||
-spec term_to_json(JSON::eep0018(), Opts::encoder_opts()) -> binary().
|
||||
|
||||
term_to_json(List, Opts) ->
|
||||
case proplists:get_value(strict, Opts, true) of
|
||||
true when is_list(List) -> continue
|
||||
|
@ -62,7 +60,6 @@ term_to_json(List, Opts) ->
|
|||
|
||||
|
||||
%% parse opts for the decoder
|
||||
|
||||
opts_to_jsx_opts(Opts) ->
|
||||
opts_to_jsx_opts(Opts, []).
|
||||
|
||||
|
@ -85,7 +82,6 @@ opts_to_jsx_opts([], Acc) ->
|
|||
|
||||
%% ensure the first jsx event we get is start_object or start_array when running
|
||||
%% in strict mode
|
||||
|
||||
collect_strict({event, Start, Next}, Acc, Opts) when Start =:= start_object; Start =:= start_array ->
|
||||
collect(Next(), [[]|Acc], Opts);
|
||||
collect_strict(_, _, _) ->
|
||||
|
@ -93,10 +89,8 @@ collect_strict(_, _, _) ->
|
|||
|
||||
|
||||
%% collect decoder events and convert to eep0018 format
|
||||
|
||||
collect({event, Start, Next}, Acc, Opts) when Start =:= start_object; Start =:= start_array ->
|
||||
collect(Next(), [[]|Acc], Opts);
|
||||
|
||||
%% special case for empty object
|
||||
collect({event, end_object, Next}, [[], Parent|Rest], Opts) when is_list(Parent) ->
|
||||
collect(Next(), [[[{}]] ++ Parent] ++ Rest, Opts);
|
||||
|
@ -111,10 +105,8 @@ collect({event, end_object, Next}, [[], Key, Parent|Rest], Opts) ->
|
|||
collect({event, End, Next}, [Current, Key, Parent|Rest], Opts)
|
||||
when End =:= end_object; End =:= end_array ->
|
||||
collect(Next(), [[{Key, lists:reverse(Current)}] ++ Parent] ++ Rest, Opts);
|
||||
|
||||
collect({event, end_json, _Next}, [[Acc]], _Opts) ->
|
||||
Acc;
|
||||
|
||||
%% key can only be emitted inside of a json object, so just insert it directly into
|
||||
%% the head of the accumulator and deal with it when we receive it's paired value
|
||||
collect({event, {key, _} = PreKey, Next}, [Current|_] = Acc, Opts) ->
|
||||
|
@ -123,7 +115,6 @@ collect({event, {key, _} = PreKey, Next}, [Current|_] = Acc, Opts) ->
|
|||
true -> erlang:error(badarg)
|
||||
; false -> collect(Next(), [Key] ++ Acc, Opts)
|
||||
end;
|
||||
|
||||
%% check acc to see if we're inside an object or an array. because inside an object
|
||||
%% context the events that fall this far are always preceded by a key (which are
|
||||
%% binaries or atoms), if Current is a list, we're inside an array, else, an
|
||||
|
@ -132,7 +123,6 @@ collect({event, Event, Next}, [Current|Rest], Opts) when is_list(Current) ->
|
|||
collect(Next(), [[event(Event, Opts)] ++ Current] ++ Rest, Opts);
|
||||
collect({event, Event, Next}, [Key, Current|Rest], Opts) ->
|
||||
collect(Next(), [[{Key, event(Event, Opts)}] ++ Current] ++ Rest, Opts);
|
||||
|
||||
%% if our first returned event is {incomplete, ...} try to force end and return the
|
||||
%% Event if one is returned
|
||||
collect({incomplete, More}, [[]], Opts) ->
|
||||
|
@ -140,13 +130,11 @@ collect({incomplete, More}, [[]], Opts) ->
|
|||
{event, Event, _Next} -> event(Event, Opts)
|
||||
; _ -> erlang:error(badarg)
|
||||
end;
|
||||
|
||||
%% any other event is an error
|
||||
collect(_, _, _) -> erlang:error(badarg).
|
||||
|
||||
|
||||
%% helper functions for converting jsx events to eep0018 formats
|
||||
|
||||
event({string, String}, _Opts) ->
|
||||
unicode:characters_to_binary(String);
|
||||
event({key, Key}, Opts) ->
|
||||
|
@ -180,7 +168,6 @@ decode_key_repeats(_Key, []) -> false.
|
|||
|
||||
|
||||
%% convert eep0018 representation to jsx events. note special casing for the empty object
|
||||
|
||||
term_to_events([{}]) ->
|
||||
[end_object, start_object];
|
||||
term_to_events([First|_] = List) when is_tuple(First) ->
|
||||
|
@ -347,7 +334,6 @@ format(Dpoint, Digits) when Dpoint > 0 ->
|
|||
format(Dpoint, Digits) when Dpoint < 0 ->
|
||||
format(Digits, 1, []) ++ "e" ++ integer_to_list(Dpoint - 1).
|
||||
|
||||
|
||||
format([], 0, Acc) ->
|
||||
lists:reverse("0." ++ Acc);
|
||||
format([], ignore, Acc) ->
|
||||
|
@ -364,7 +350,6 @@ to_ascii(X) -> [X + 48]. %% ascii "1" is [49], "2" is [50], etc...
|
|||
%% json string escaping, for utf8 binaries. escape the json control sequences to their
|
||||
%% json equivalent, escape other control characters to \uXXXX sequences, everything
|
||||
%% else should be a legal json string component
|
||||
|
||||
json_escape(String) ->
|
||||
json_escape(String, <<>>).
|
||||
|
||||
|
@ -400,6 +385,7 @@ json_escape_sequence(C) when C < 16#20 ->
|
|||
<<_:8, A:4, B:4>> = <<C:16>>, % first two hex digits are always zero
|
||||
<<$\\, $u, $0, $0, (to_hex(A)), (to_hex(B))>>.
|
||||
|
||||
|
||||
to_hex(15) -> $f;
|
||||
to_hex(14) -> $e;
|
||||
to_hex(13) -> $d;
|
||||
|
|
|
@ -24,10 +24,11 @@
|
|||
-module(jsx_format).
|
||||
-author("alisdairsullivan@yahoo.ca").
|
||||
|
||||
|
||||
-export([format/2]).
|
||||
|
||||
|
||||
-include("./include/jsx_types.hrl").
|
||||
-include("./include/jsx_format.hrl").
|
||||
|
||||
|
||||
-ifdef(test).
|
||||
|
@ -35,33 +36,10 @@
|
|||
-endif.
|
||||
|
||||
|
||||
-record(opts, {
|
||||
space = 0,
|
||||
indent = 0,
|
||||
output_encoding = utf8,
|
||||
strict = true
|
||||
}).
|
||||
|
||||
|
||||
|
||||
-define(newline, $\n).
|
||||
-define(space, 16#20). %% ascii code for space
|
||||
-define(quote, $\").
|
||||
-define(comma, $,).
|
||||
-define(colon, $:).
|
||||
-define(start_object, ${).
|
||||
-define(end_object, $}).
|
||||
-define(start_array, $[).
|
||||
-define(end_array, $]).
|
||||
|
||||
|
||||
|
||||
-spec format(JSON::binary(), Opts::format_opts()) -> binary() | iolist().
|
||||
|
||||
format(JSON, Opts) when is_binary(JSON) ->
|
||||
P = jsx:parser(extract_parser_opts(Opts)),
|
||||
format(fun() -> P(JSON) end, Opts);
|
||||
|
||||
format(F, OptsList) when is_function(F) ->
|
||||
Opts = parse_opts(OptsList, #opts{}),
|
||||
{Continue, String} = format_something(F(), Opts, 0),
|
||||
|
@ -126,6 +104,7 @@ format_object({event, {key, Key}, Next}, Acc, Opts, Level) ->
|
|||
)
|
||||
end.
|
||||
|
||||
|
||||
format_array({event, end_array, Next}, Acc, _Opts, _Level) ->
|
||||
{Next, Acc};
|
||||
format_array(Event, Acc, Opts, Level) ->
|
||||
|
@ -138,10 +117,6 @@ format_array(Event, Acc, Opts, Level) ->
|
|||
end.
|
||||
|
||||
|
||||
-define(is_utf_encoding(X),
|
||||
X == utf8; X == utf16; X == utf32; X == {utf16, little}; X == {utf32, little}
|
||||
).
|
||||
|
||||
encode(Acc, Opts) when is_list(Acc) ->
|
||||
case Opts#opts.output_encoding of
|
||||
iolist -> Acc
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
|
||||
-file("./include/jsx_decoder.hrl", 1).
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 35).
|
||||
|
||||
-file("./include/jsx_types.hrl", 1).
|
||||
-file("./include/jsx_common.hrl", 1).
|
||||
|
||||
-type jsx_opts() :: [jsx_opt()].
|
||||
|
||||
|
@ -51,6 +49,12 @@
|
|||
| {error, badjson}
|
||||
| ok.
|
||||
|
||||
-type supported_utf() :: utf8
|
||||
| utf16
|
||||
| {utf16, little}
|
||||
| utf32
|
||||
| {utf32, little}.
|
||||
|
||||
-type eep0018() :: eep0018_object() | eep0018_array().
|
||||
|
||||
-type eep0018_array() :: [eep0018_term()].
|
||||
|
@ -71,12 +75,6 @@
|
|||
|
||||
-type eep0018_number() :: float() | integer().
|
||||
|
||||
-type supported_utf() :: utf8
|
||||
| utf16
|
||||
| {utf16, little}
|
||||
| utf32
|
||||
| {utf32, little}.
|
||||
|
||||
-type encoder_opts() :: [encoder_opt()].
|
||||
|
||||
-type encoder_opt() :: {strict, true | false}
|
||||
|
@ -111,11 +109,13 @@
|
|||
| indent
|
||||
| {output_encoding, supported_utf()}.
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 36).
|
||||
-file("./include/jsx_decoder.hrl", 24).
|
||||
|
||||
-spec parse(JSON :: eep0018(), Opts :: jsx_opts()) ->
|
||||
jsx_parser_result().
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 35).
|
||||
|
||||
parse(JSON, Opts) ->
|
||||
start(JSON, [], Opts).
|
||||
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
|
||||
-file("./include/jsx_decoder.hrl", 1).
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 35).
|
||||
|
||||
-file("./include/jsx_types.hrl", 1).
|
||||
-file("./include/jsx_common.hrl", 1).
|
||||
|
||||
-type jsx_opts() :: [jsx_opt()].
|
||||
|
||||
|
@ -51,6 +49,12 @@
|
|||
| {error, badjson}
|
||||
| ok.
|
||||
|
||||
-type supported_utf() :: utf8
|
||||
| utf16
|
||||
| {utf16, little}
|
||||
| utf32
|
||||
| {utf32, little}.
|
||||
|
||||
-type eep0018() :: eep0018_object() | eep0018_array().
|
||||
|
||||
-type eep0018_array() :: [eep0018_term()].
|
||||
|
@ -71,12 +75,6 @@
|
|||
|
||||
-type eep0018_number() :: float() | integer().
|
||||
|
||||
-type supported_utf() :: utf8
|
||||
| utf16
|
||||
| {utf16, little}
|
||||
| utf32
|
||||
| {utf32, little}.
|
||||
|
||||
-type encoder_opts() :: [encoder_opt()].
|
||||
|
||||
-type encoder_opt() :: {strict, true | false}
|
||||
|
@ -111,11 +109,13 @@
|
|||
| indent
|
||||
| {output_encoding, supported_utf()}.
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 36).
|
||||
-file("./include/jsx_decoder.hrl", 24).
|
||||
|
||||
-spec parse(JSON :: eep0018(), Opts :: jsx_opts()) ->
|
||||
jsx_parser_result().
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 35).
|
||||
|
||||
parse(JSON, Opts) ->
|
||||
start(JSON, [], Opts).
|
||||
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
|
||||
-file("./include/jsx_decoder.hrl", 1).
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 35).
|
||||
|
||||
-file("./include/jsx_types.hrl", 1).
|
||||
-file("./include/jsx_common.hrl", 1).
|
||||
|
||||
-type jsx_opts() :: [jsx_opt()].
|
||||
|
||||
|
@ -51,6 +49,12 @@
|
|||
| {error, badjson}
|
||||
| ok.
|
||||
|
||||
-type supported_utf() :: utf8
|
||||
| utf16
|
||||
| {utf16, little}
|
||||
| utf32
|
||||
| {utf32, little}.
|
||||
|
||||
-type eep0018() :: eep0018_object() | eep0018_array().
|
||||
|
||||
-type eep0018_array() :: [eep0018_term()].
|
||||
|
@ -71,12 +75,6 @@
|
|||
|
||||
-type eep0018_number() :: float() | integer().
|
||||
|
||||
-type supported_utf() :: utf8
|
||||
| utf16
|
||||
| {utf16, little}
|
||||
| utf32
|
||||
| {utf32, little}.
|
||||
|
||||
-type encoder_opts() :: [encoder_opt()].
|
||||
|
||||
-type encoder_opt() :: {strict, true | false}
|
||||
|
@ -111,11 +109,13 @@
|
|||
| indent
|
||||
| {output_encoding, supported_utf()}.
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 36).
|
||||
-file("./include/jsx_decoder.hrl", 24).
|
||||
|
||||
-spec parse(JSON :: eep0018(), Opts :: jsx_opts()) ->
|
||||
jsx_parser_result().
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 35).
|
||||
|
||||
parse(JSON, Opts) ->
|
||||
start(JSON, [], Opts).
|
||||
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
|
||||
-file("./include/jsx_decoder.hrl", 1).
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 35).
|
||||
|
||||
-file("./include/jsx_types.hrl", 1).
|
||||
-file("./include/jsx_common.hrl", 1).
|
||||
|
||||
-type jsx_opts() :: [jsx_opt()].
|
||||
|
||||
|
@ -51,6 +49,12 @@
|
|||
| {error, badjson}
|
||||
| ok.
|
||||
|
||||
-type supported_utf() :: utf8
|
||||
| utf16
|
||||
| {utf16, little}
|
||||
| utf32
|
||||
| {utf32, little}.
|
||||
|
||||
-type eep0018() :: eep0018_object() | eep0018_array().
|
||||
|
||||
-type eep0018_array() :: [eep0018_term()].
|
||||
|
@ -71,12 +75,6 @@
|
|||
|
||||
-type eep0018_number() :: float() | integer().
|
||||
|
||||
-type supported_utf() :: utf8
|
||||
| utf16
|
||||
| {utf16, little}
|
||||
| utf32
|
||||
| {utf32, little}.
|
||||
|
||||
-type encoder_opts() :: [encoder_opt()].
|
||||
|
||||
-type encoder_opt() :: {strict, true | false}
|
||||
|
@ -111,11 +109,13 @@
|
|||
| indent
|
||||
| {output_encoding, supported_utf()}.
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 36).
|
||||
-file("./include/jsx_decoder.hrl", 24).
|
||||
|
||||
-spec parse(JSON :: eep0018(), Opts :: jsx_opts()) ->
|
||||
jsx_parser_result().
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 35).
|
||||
|
||||
parse(JSON, Opts) ->
|
||||
start(JSON, [], Opts).
|
||||
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
|
||||
-file("./include/jsx_decoder.hrl", 1).
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 35).
|
||||
|
||||
-file("./include/jsx_types.hrl", 1).
|
||||
-file("./include/jsx_common.hrl", 1).
|
||||
|
||||
-type jsx_opts() :: [jsx_opt()].
|
||||
|
||||
|
@ -51,6 +49,12 @@
|
|||
| {error, badjson}
|
||||
| ok.
|
||||
|
||||
-type supported_utf() :: utf8
|
||||
| utf16
|
||||
| {utf16, little}
|
||||
| utf32
|
||||
| {utf32, little}.
|
||||
|
||||
-type eep0018() :: eep0018_object() | eep0018_array().
|
||||
|
||||
-type eep0018_array() :: [eep0018_term()].
|
||||
|
@ -71,12 +75,6 @@
|
|||
|
||||
-type eep0018_number() :: float() | integer().
|
||||
|
||||
-type supported_utf() :: utf8
|
||||
| utf16
|
||||
| {utf16, little}
|
||||
| utf32
|
||||
| {utf32, little}.
|
||||
|
||||
-type encoder_opts() :: [encoder_opt()].
|
||||
|
||||
-type encoder_opt() :: {strict, true | false}
|
||||
|
@ -111,11 +109,13 @@
|
|||
| indent
|
||||
| {output_encoding, supported_utf()}.
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 36).
|
||||
-file("./include/jsx_decoder.hrl", 24).
|
||||
|
||||
-spec parse(JSON :: eep0018(), Opts :: jsx_opts()) ->
|
||||
jsx_parser_result().
|
||||
|
||||
-file("priv/jsx_decoder_template.erl", 35).
|
||||
|
||||
parse(JSON, Opts) ->
|
||||
start(JSON, [], Opts).
|
||||
|
||||
|
|
|
@ -24,9 +24,12 @@
|
|||
-module(jsx_verify).
|
||||
-author("alisdairsullivan@yahoo.ca").
|
||||
|
||||
|
||||
-export([is_json/2]).
|
||||
|
||||
-include("./include/jsx_types.hrl").
|
||||
|
||||
-include("./include/jsx_verify.hrl").
|
||||
|
||||
|
||||
-ifdef(test).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
@ -34,8 +37,6 @@
|
|||
|
||||
|
||||
|
||||
-spec is_json(JSON::binary(), Opts::verify_opts()) -> true | false.
|
||||
|
||||
is_json(JSON, Opts) ->
|
||||
Encoding = proplists:get_value(encoding, Opts, utf8),
|
||||
Comments = proplists:get_value(comments, Opts, false),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue