|
@@ -27,6 +27,8 @@
|
|
|
%%%---------------------------------------------------------------------------------------
|
|
|
-module(jsone_decode).
|
|
|
|
|
|
+-compile(inline).
|
|
|
+
|
|
|
%%--------------------------------------------------------------------------------
|
|
|
%% Exported API
|
|
|
%%--------------------------------------------------------------------------------
|
|
@@ -57,91 +59,91 @@
|
|
|
%% デコードに失敗した場合は`{invalid_json, 失敗位置より後のJSON::binary()}'形式のエラーが送出される.
|
|
|
-spec decode(binary()) -> {jsone:json_value(), RestJson::binary()}.
|
|
|
decode(<<Json/binary>>) ->
|
|
|
- whitespace(Json, value, []).
|
|
|
+ whitespace(Json, value, [], <<"">>).
|
|
|
|
|
|
%%--------------------------------------------------------------------------------
|
|
|
%% Internal Functions
|
|
|
%%--------------------------------------------------------------------------------
|
|
|
--spec next(binary(), jsone:json_value(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-next(<<Bin/binary>>, Value, []) ->
|
|
|
+-spec next(binary(), jsone:json_value(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+next(<<Bin/binary>>, Value, [], _Buf) ->
|
|
|
{Value, Bin};
|
|
|
-next(<<Bin/binary>>, Value, [Next | Nexts]) ->
|
|
|
+next(<<Bin/binary>>, Value, [Next | Nexts], Buf) ->
|
|
|
case Next of
|
|
|
- {array_next, Values} -> whitespace(Bin, {array_next, [Value | Values]}, Nexts);
|
|
|
- {object_value, Members} -> whitespace(Bin, {object_value, Value, Members}, Nexts);
|
|
|
- {object_next, Key, Members} -> whitespace(Bin, {object_next, Key, Value, Members}, Nexts)
|
|
|
+ {array_next, Values} -> whitespace(Bin, {array_next, [Value | Values]}, Nexts, Buf);
|
|
|
+ {object_value, Members} -> whitespace(Bin, {object_value, Value, Members}, Nexts, Buf);
|
|
|
+ {object_next, Key, Members} -> whitespace(Bin, {object_next, Key, Value, Members}, Nexts, Buf)
|
|
|
end.
|
|
|
|
|
|
--spec whitespace(binary(), whitespace_next(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-whitespace(<<$ , Bin/binary>>, Next, Nexts) -> whitespace(Bin, Next, Nexts);
|
|
|
-whitespace(<<$\t, Bin/binary>>, Next, Nexts) -> whitespace(Bin, Next, Nexts);
|
|
|
-whitespace(<<$\r, Bin/binary>>, Next, Nexts) -> whitespace(Bin, Next, Nexts);
|
|
|
-whitespace(<<$\n, Bin/binary>>, Next, Nexts) -> whitespace(Bin, Next, Nexts);
|
|
|
-whitespace(<<Bin/binary>>, Next, Nexts) ->
|
|
|
+-spec whitespace(binary(), whitespace_next(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+whitespace(<<$ , Bin/binary>>, Next, Nexts, Buf) -> whitespace(Bin, Next, Nexts, Buf);
|
|
|
+whitespace(<<$\t, Bin/binary>>, Next, Nexts, Buf) -> whitespace(Bin, Next, Nexts, Buf);
|
|
|
+whitespace(<<$\r, Bin/binary>>, Next, Nexts, Buf) -> whitespace(Bin, Next, Nexts, Buf);
|
|
|
+whitespace(<<$\n, Bin/binary>>, Next, Nexts, Buf) -> whitespace(Bin, Next, Nexts, Buf);
|
|
|
+whitespace(<<Bin/binary>>, Next, Nexts, Buf) ->
|
|
|
case Next of
|
|
|
- value -> value(Bin, Nexts);
|
|
|
- array -> array(Bin, Nexts);
|
|
|
- object -> object(Bin, Nexts);
|
|
|
+ value -> value(Bin, Nexts, Buf);
|
|
|
+ array -> array(Bin, Nexts, Buf);
|
|
|
+ object -> object(Bin, Nexts, Buf);
|
|
|
string -> case Bin of
|
|
|
- <<$", Bin2/binary>> -> string(Bin2, [], Nexts);
|
|
|
+ <<$", Bin2/binary>> -> string(Bin2, byte_size(Buf), Nexts, Buf);
|
|
|
_ -> ?ERROR(Bin)
|
|
|
end;
|
|
|
- {array_next, Values} -> array_next(Bin, Values, Nexts);
|
|
|
- {object_value, Key, Members} -> object_value(Bin, Key, Members, Nexts);
|
|
|
- {object_next, Key, Value, Members} -> object_next(Bin, [{Key, Value} | Members], Nexts)
|
|
|
+ {array_next, Values} -> array_next(Bin, Values, Nexts, Buf);
|
|
|
+ {object_value, Key, Members} -> object_value(Bin, Key, Members, Nexts, Buf);
|
|
|
+ {object_next, Key, Value, Members} -> object_next(Bin, [{Key, Value} | Members], Nexts, Buf)
|
|
|
end.
|
|
|
|
|
|
--spec value(binary(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-value(<<"false", Bin/binary>>, Nexts) -> next(Bin, false, Nexts);
|
|
|
-value(<<"true", Bin/binary>>, Nexts) -> next(Bin, true, Nexts);
|
|
|
-value(<<"null", Bin/binary>>, Nexts) -> next(Bin, null, Nexts);
|
|
|
-value(<<$[, Bin/binary>>, Nexts) -> whitespace(Bin, array, Nexts);
|
|
|
-value(<<${, Bin/binary>>, Nexts) -> whitespace(Bin, object, Nexts);
|
|
|
-value(<<$", Bin/binary>>, Nexts) -> string(Bin, [], Nexts);
|
|
|
-value(<<Bin/binary>>, Nexts) -> number(Bin, Nexts).
|
|
|
-
|
|
|
--spec array(binary(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-array(<<$], Bin/binary>>, Nexts) -> next(Bin, [], Nexts);
|
|
|
-array(<<Bin/binary>>, Nexts) -> whitespace(Bin, value, [{array_next, []} | Nexts]).
|
|
|
-
|
|
|
--spec array_next(binary(), [jsone:json_value()], [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-array_next(<<$], Bin/binary>>, Values, Nexts) -> next(Bin, lists:reverse(Values), Nexts);
|
|
|
-array_next(<<$,, Bin/binary>>, Values, Nexts) -> whitespace(Bin, value, [{array_next, Values} | Nexts]);
|
|
|
-array_next(<<Bin/binary>>, _Values, _Nexts) -> ?ERROR(Bin).
|
|
|
-
|
|
|
--spec object(binary(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-object(<<$}, Bin/binary>>, Nexts) -> next(Bin, {object, []}, Nexts);
|
|
|
-object(<<Bin/binary>>, Nexts) -> whitespace(Bin, string, [{object_value, []} | Nexts]).
|
|
|
-
|
|
|
--spec object_value(binary(), jsone:json_string(), jsone:json_object_members(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-object_value(<<$:, Bin/binary>>, Key, Members, Nexts) -> whitespace(Bin, value, [{object_next, Key, Members} | Nexts]);
|
|
|
-object_value(<<Bin/binary>>, _Key, _Members, _Nexts) -> ?ERROR(Bin).
|
|
|
-
|
|
|
--spec object_next(binary(), jsone:json_object_members(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-object_next(<<$}, Bin/binary>>, Members, Nexts) -> next(Bin, {object, lists:reverse(Members)}, Nexts);
|
|
|
-object_next(<<$,, Bin/binary>>, Members, Nexts) -> whitespace(Bin, string, [{object_value, Members} | Nexts]);
|
|
|
-object_next(<<Bin/binary>>, _Members, _Nexts) -> ?ERROR(Bin).
|
|
|
-
|
|
|
--spec string(binary(), iolist(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-string(<<$", Bin/binary>>, Acc, Nexts) -> next(Bin, list_to_binary(lists:reverse(Acc)), Nexts);
|
|
|
-string(<<$\\, B/binary>>, Acc, Nexts) ->
|
|
|
+-spec value(binary(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+value(<<"false", Bin/binary>>, Nexts, Buf) -> next(Bin, false, Nexts, Buf);
|
|
|
+value(<<"true", Bin/binary>>, Nexts, Buf) -> next(Bin, true, Nexts, Buf);
|
|
|
+value(<<"null", Bin/binary>>, Nexts, Buf) -> next(Bin, null, Nexts, Buf);
|
|
|
+value(<<$[, Bin/binary>>, Nexts, Buf) -> whitespace(Bin, array, Nexts, Buf);
|
|
|
+value(<<${, Bin/binary>>, Nexts, Buf) -> whitespace(Bin, object, Nexts, Buf);
|
|
|
+value(<<$", Bin/binary>>, Nexts, Buf) -> string(Bin, byte_size(Buf), Nexts, Buf);
|
|
|
+value(<<Bin/binary>>, Nexts, Buf) -> number(Bin, Nexts, Buf).
|
|
|
+
|
|
|
+-spec array(binary(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+array(<<$], Bin/binary>>, Nexts, Buf) -> next(Bin, [], Nexts, Buf);
|
|
|
+array(<<Bin/binary>>, Nexts, Buf) -> whitespace(Bin, value, [{array_next, []} | Nexts], Buf).
|
|
|
+
|
|
|
+-spec array_next(binary(), [jsone:json_value()], [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+array_next(<<$], Bin/binary>>, Values, Nexts, Buf) -> next(Bin, lists:reverse(Values), Nexts, Buf);
|
|
|
+array_next(<<$,, Bin/binary>>, Values, Nexts, Buf) -> whitespace(Bin, value, [{array_next, Values} | Nexts], Buf);
|
|
|
+array_next(<<Bin/binary>>, _Values, _Nexts, _Buf) -> ?ERROR(Bin).
|
|
|
+
|
|
|
+-spec object(binary(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+object(<<$}, Bin/binary>>, Nexts, Buf) -> next(Bin, {object, []}, Nexts, Buf);
|
|
|
+object(<<Bin/binary>>, Nexts, Buf) -> whitespace(Bin, string, [{object_value, []} | Nexts], Buf).
|
|
|
+
|
|
|
+-spec object_value(binary(), jsone:json_string(), jsone:json_object_members(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+object_value(<<$:, Bin/binary>>, Key, Members, Nexts, Buf) -> whitespace(Bin, value, [{object_next, Key, Members} | Nexts], Buf);
|
|
|
+object_value(<<Bin/binary>>, _Key, _Members, _Nexts, _Buf) -> ?ERROR(Bin).
|
|
|
+
|
|
|
+-spec object_next(binary(), jsone:json_object_members(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+object_next(<<$}, Bin/binary>>, Members, Nexts, Buf) -> next(Bin, {object, lists:reverse(Members)}, Nexts, Buf);
|
|
|
+object_next(<<$,, Bin/binary>>, Members, Nexts, Buf) -> whitespace(Bin, string, [{object_value, Members} | Nexts], Buf);
|
|
|
+object_next(<<Bin/binary>>, _Members, _Nexts, _Buf) -> ?ERROR(Bin).
|
|
|
+
|
|
|
+-spec string(binary(), non_neg_integer(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+string(<<$", Bin/binary>>, Start, Nexts, Buf) -> next(Bin, binary:part(Buf, Start, byte_size(Buf) - Start), Nexts, Buf);
|
|
|
+string(<<$\\, B/binary>>, Start, Nexts, Buf) ->
|
|
|
case B of
|
|
|
- <<$", Bin/binary>> -> string(Bin, [$" | Acc], Nexts);
|
|
|
- <<$/, Bin/binary>> -> string(Bin, [$/ | Acc], Nexts);
|
|
|
- <<$\\,Bin/binary>> -> string(Bin, [$\\| Acc], Nexts);
|
|
|
- <<$b, Bin/binary>> -> string(Bin, [$\b | Acc], Nexts);
|
|
|
- <<$f, Bin/binary>> -> string(Bin, [$\f | Acc], Nexts);
|
|
|
- <<$n, Bin/binary>> -> string(Bin, [$\n | Acc], Nexts);
|
|
|
- <<$r, Bin/binary>> -> string(Bin, [$\r | Acc], Nexts);
|
|
|
- <<$t, Bin/binary>> -> string(Bin, [$\t | Acc], Nexts);
|
|
|
- <<$u, Bin/binary>> -> unicode_string(Bin, Acc, Nexts);
|
|
|
+ <<$", Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $">>);
|
|
|
+ <<$/, Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $/>>);
|
|
|
+ <<$\\,Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $\\>>);
|
|
|
+ <<$b, Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $\b>>);
|
|
|
+ <<$f, Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $\f>>);
|
|
|
+ <<$n, Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $\n>>);
|
|
|
+ <<$r, Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $\r>>);
|
|
|
+ <<$t, Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $\t>>);
|
|
|
+ <<$u, Bin/binary>> -> unicode_string(Bin, Start, Nexts, Buf);
|
|
|
_ -> ?ERROR(B)
|
|
|
end;
|
|
|
-string(<<C, Bin/binary>>, Acc, Nexts) when 16#20 =< C ->
|
|
|
- string(Bin, [C | Acc], Nexts).
|
|
|
+string(<<C, Bin/binary>>, Start, Nexts, Buf) when 16#20 =< C ->
|
|
|
+ string(Bin, Start, Nexts, <<Buf/binary, C>>).
|
|
|
|
|
|
--spec unicode_string(binary(), iolist(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-unicode_string(<<N:4/binary, Bin/binary>>, Acc, Nexts) ->
|
|
|
+-spec unicode_string(binary(), non_neg_integer(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+unicode_string(<<N:4/binary, Bin/binary>>, Start, Nexts, Buf) ->
|
|
|
case binary_to_integer(N, 16) of
|
|
|
High when 16#D800 =< High, High =< 16#DBFF ->
|
|
|
%% サロゲートペア
|
|
@@ -150,7 +152,7 @@ unicode_string(<<N:4/binary, Bin/binary>>, Acc, Nexts) ->
|
|
|
case binary_to_integer(N2, 16) of
|
|
|
Low when 16#DC00 =< Low, Low =< 16#DFFF ->
|
|
|
Unicode = 16#10000 + (High - 16#D800) * 16#400 + (Low - 16#DC00),
|
|
|
- string(Bin2, unicode_to_utf8(Unicode, Acc), Nexts);
|
|
|
+ string(Bin2, Start, Nexts, unicode_to_utf8(Unicode, Buf));
|
|
|
_ -> ?ERROR(Bin)
|
|
|
end;
|
|
|
_ -> ?ERROR(Bin)
|
|
@@ -158,86 +160,86 @@ unicode_string(<<N:4/binary, Bin/binary>>, Acc, Nexts) ->
|
|
|
Unicode when 16#DC00 =< Unicode, Unicode =< 16#DFFF -> % サロゲートペアの後半部分
|
|
|
?ERROR(<<N/binary, Bin/binary>>);
|
|
|
Unicode ->
|
|
|
- string(Bin, unicode_to_utf8(Unicode, Acc), Nexts)
|
|
|
+ string(Bin, Start, Nexts, unicode_to_utf8(Unicode, Buf))
|
|
|
end;
|
|
|
-unicode_string(<<Bin/binary>>, _Acc, _Nexts) ->
|
|
|
+unicode_string(<<Bin/binary>>, _Acc, _Nexts, _Buf) ->
|
|
|
?ERROR(Bin).
|
|
|
|
|
|
--spec unicode_to_utf8(0..1114111, iolist()) -> iolist().
|
|
|
-unicode_to_utf8(Code, Acc) when Code < 16#80 ->
|
|
|
- [Code | Acc];
|
|
|
-unicode_to_utf8(Code, Acc) when Code < 16#800 ->
|
|
|
+-spec unicode_to_utf8(0..1114111, binary()) -> iolist().
|
|
|
+unicode_to_utf8(Code, Buf) when Code < 16#80 ->
|
|
|
+ <<Buf/binary, Code>>;
|
|
|
+unicode_to_utf8(Code, Buf) when Code < 16#800 ->
|
|
|
A = 2#11000000 bor (Code bsr 6),
|
|
|
B = 2#10000000 bor (Code band 2#111111),
|
|
|
- [B, A | Acc];
|
|
|
-unicode_to_utf8(Code, Acc) when Code < 16#10000 ->
|
|
|
+ <<Buf/binary, A, B>>;
|
|
|
+unicode_to_utf8(Code, Buf) when Code < 16#10000 ->
|
|
|
A = 2#11100000 bor (Code bsr 12),
|
|
|
B = 2#10000000 bor ((Code bsr 6) band 2#111111),
|
|
|
C = 2#10000000 bor (Code band 2#111111),
|
|
|
- [C, B, A | Acc];
|
|
|
-unicode_to_utf8(Code, Acc) -> % NOTE: サロゲートペアの仕組み上、コード値が上限を越えることはないので、ここでの範囲チェックは不要
|
|
|
+ <<Buf/binary, A, B, C>>;
|
|
|
+unicode_to_utf8(Code, Buf) -> % NOTE: サロゲートペアの仕組み上、コード値が上限を越えることはないので、ここでの範囲チェックは不要
|
|
|
A = 2#11110000 bor (Code bsr 18),
|
|
|
B = 2#10000000 bor ((Code bsr 12) band 2#111111),
|
|
|
C = 2#10000000 bor ((Code bsr 6) band 2#111111),
|
|
|
D = 2#10000000 bor (Code band 2#111111),
|
|
|
- [D, C, B, A | Acc].
|
|
|
-
|
|
|
--spec number(binary(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-number(<<$-, Bin/binary>>, Nexts) -> number_integer_part(Bin, -1, Nexts);
|
|
|
-number(<<Bin/binary>>, Nexts) -> number_integer_part(Bin, 1, Nexts).
|
|
|
-
|
|
|
--spec number_integer_part(binary(), 1|-1, [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-number_integer_part(<<$0, Bin/binary>>, Sign, Nexts) ->
|
|
|
- number_fraction_part(Bin, Sign, 0, Nexts);
|
|
|
-number_integer_part(<<C, Bin/binary>>, Sign, Nexts) when $1 =< C, C =< $9 ->
|
|
|
- number_integer_part_rest(Bin, C - $0, Sign, Nexts);
|
|
|
-number_integer_part(<<Bin/binary>>, _Sign, _Nexts) ->
|
|
|
+ <<Buf/binary, A, B, C, D>>.
|
|
|
+
|
|
|
+-spec number(binary(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+number(<<$-, Bin/binary>>, Nexts, Buf) -> number_integer_part(Bin, -1, Nexts, Buf);
|
|
|
+number(<<Bin/binary>>, Nexts, Buf) -> number_integer_part(Bin, 1, Nexts, Buf).
|
|
|
+
|
|
|
+-spec number_integer_part(binary(), 1|-1, [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+number_integer_part(<<$0, Bin/binary>>, Sign, Nexts, Buf) ->
|
|
|
+ number_fraction_part(Bin, Sign, 0, Nexts, Buf);
|
|
|
+number_integer_part(<<C, Bin/binary>>, Sign, Nexts, Buf) when $1 =< C, C =< $9 ->
|
|
|
+ number_integer_part_rest(Bin, C - $0, Sign, Nexts, Buf);
|
|
|
+number_integer_part(<<Bin/binary>>, _Sign, _Nexts, _Buf) ->
|
|
|
?ERROR(Bin).
|
|
|
|
|
|
--spec number_integer_part_rest(binary(), non_neg_integer(), 1|-1, [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-number_integer_part_rest(<<C, Bin/binary>>, N, Sign, Nexts) when $0 =< C, C =< $9 ->
|
|
|
- number_integer_part_rest(Bin, N * 10 + C - $0, Sign, Nexts);
|
|
|
-number_integer_part_rest(<<Bin/binary>>, N, Sign, Nexts) ->
|
|
|
- number_fraction_part(Bin, Sign, N, Nexts).
|
|
|
-
|
|
|
--spec number_fraction_part(binary(), 1|-1, non_neg_integer(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-number_fraction_part(<<$., Bin/binary>>, Sign, Int, Nexts) ->
|
|
|
- number_fraction_part_rest(Bin, Sign, Int, 0, Nexts);
|
|
|
-number_fraction_part(<<Bin/binary>>, Sign, Int, Nexts) ->
|
|
|
- number_exponation_part(Bin, Sign * Int, 0, Nexts).
|
|
|
-
|
|
|
--spec number_fraction_part_rest(binary(), 1|-1, non_neg_integer(), non_neg_integer(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-number_fraction_part_rest(<<C, Bin/binary>>, Sign, N, DecimalOffset, Nexts) when $0 =< C, C =< $9 ->
|
|
|
- number_fraction_part_rest(Bin, Sign, N * 10 + C - $0, DecimalOffset + 1, Nexts);
|
|
|
-number_fraction_part_rest(<<Bin/binary>>, Sign, N, DecimalOffset, Nexts) when DecimalOffset > 0 ->
|
|
|
- number_exponation_part(Bin, Sign * N, DecimalOffset, Nexts);
|
|
|
-number_fraction_part_rest(<<Bin/binary>>, _Sign, _N, _DecimalOffset, _Nexts) ->
|
|
|
+-spec number_integer_part_rest(binary(), non_neg_integer(), 1|-1, [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+number_integer_part_rest(<<C, Bin/binary>>, N, Sign, Nexts, Buf) when $0 =< C, C =< $9 ->
|
|
|
+ number_integer_part_rest(Bin, N * 10 + C - $0, Sign, Nexts, Buf);
|
|
|
+number_integer_part_rest(<<Bin/binary>>, N, Sign, Nexts, Buf) ->
|
|
|
+ number_fraction_part(Bin, Sign, N, Nexts, Buf).
|
|
|
+
|
|
|
+-spec number_fraction_part(binary(), 1|-1, non_neg_integer(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+number_fraction_part(<<$., Bin/binary>>, Sign, Int, Nexts, Buf) ->
|
|
|
+ number_fraction_part_rest(Bin, Sign, Int, 0, Nexts, Buf);
|
|
|
+number_fraction_part(<<Bin/binary>>, Sign, Int, Nexts, Buf) ->
|
|
|
+ number_exponation_part(Bin, Sign * Int, 0, Nexts, Buf).
|
|
|
+
|
|
|
+-spec number_fraction_part_rest(binary(), 1|-1, non_neg_integer(), non_neg_integer(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+number_fraction_part_rest(<<C, Bin/binary>>, Sign, N, DecimalOffset, Nexts, Buf) when $0 =< C, C =< $9 ->
|
|
|
+ number_fraction_part_rest(Bin, Sign, N * 10 + C - $0, DecimalOffset + 1, Nexts, Buf);
|
|
|
+number_fraction_part_rest(<<Bin/binary>>, Sign, N, DecimalOffset, Nexts, Buf) when DecimalOffset > 0 ->
|
|
|
+ number_exponation_part(Bin, Sign * N, DecimalOffset, Nexts, Buf);
|
|
|
+number_fraction_part_rest(<<Bin/binary>>, _Sign, _N, _DecimalOffset, _Nexts, _Buf) ->
|
|
|
?ERROR(Bin).
|
|
|
|
|
|
--spec number_exponation_part(binary(), integer(), non_neg_integer(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-number_exponation_part(<<$e, $+, Bin/binary>>, N, DecimalOffset, Nexts) ->
|
|
|
- number_exponation_part(Bin, N, DecimalOffset, 1, 0, true, Nexts);
|
|
|
-number_exponation_part(<<$E, $+, Bin/binary>>, N, DecimalOffset, Nexts) ->
|
|
|
- number_exponation_part(Bin, N, DecimalOffset, 1, 0, true, Nexts);
|
|
|
-number_exponation_part(<<$e, $-, Bin/binary>>, N, DecimalOffset, Nexts) ->
|
|
|
- number_exponation_part(Bin, N, DecimalOffset, -1, 0, true, Nexts);
|
|
|
-number_exponation_part(<<$E, $-, Bin/binary>>, N, DecimalOffset, Nexts) ->
|
|
|
- number_exponation_part(Bin, N, DecimalOffset, -1, 0, true, Nexts);
|
|
|
-number_exponation_part(<<$e, Bin/binary>>, N, DecimalOffset, Nexts) ->
|
|
|
- number_exponation_part(Bin, N, DecimalOffset, 1, 0, true, Nexts);
|
|
|
-number_exponation_part(<<$E, Bin/binary>>, N, DecimalOffset, Nexts) ->
|
|
|
- number_exponation_part(Bin, N, DecimalOffset, 1, 0, true, Nexts);
|
|
|
-number_exponation_part(<<Bin/binary>>, N, DecimalOffset, Nexts) ->
|
|
|
+-spec number_exponation_part(binary(), integer(), non_neg_integer(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+number_exponation_part(<<$e, $+, Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
|
|
|
+ number_exponation_part(Bin, N, DecimalOffset, 1, 0, true, Nexts, Buf);
|
|
|
+number_exponation_part(<<$E, $+, Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
|
|
|
+ number_exponation_part(Bin, N, DecimalOffset, 1, 0, true, Nexts, Buf);
|
|
|
+number_exponation_part(<<$e, $-, Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
|
|
|
+ number_exponation_part(Bin, N, DecimalOffset, -1, 0, true, Nexts, Buf);
|
|
|
+number_exponation_part(<<$E, $-, Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
|
|
|
+ number_exponation_part(Bin, N, DecimalOffset, -1, 0, true, Nexts, Buf);
|
|
|
+number_exponation_part(<<$e, Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
|
|
|
+ number_exponation_part(Bin, N, DecimalOffset, 1, 0, true, Nexts, Buf);
|
|
|
+number_exponation_part(<<$E, Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
|
|
|
+ number_exponation_part(Bin, N, DecimalOffset, 1, 0, true, Nexts, Buf);
|
|
|
+number_exponation_part(<<Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
|
|
|
case DecimalOffset of
|
|
|
- 0 -> next(Bin, N, Nexts);
|
|
|
- _ -> next(Bin, N / math:pow(10, DecimalOffset), Nexts)
|
|
|
+ 0 -> next(Bin, N, Nexts, Buf);
|
|
|
+ _ -> next(Bin, N / math:pow(10, DecimalOffset), Nexts, Buf)
|
|
|
end.
|
|
|
|
|
|
--spec number_exponation_part(binary(), integer(), non_neg_integer(), 1|-1, non_neg_integer(), boolean(), [next()]) -> {jsone:json_value(), Rest::binary()}.
|
|
|
-number_exponation_part(<<C, Bin/binary>>, N, DecimalOffset, ExpSign, Exp, _, Nexts) when $0 =< C, C =< $9 ->
|
|
|
- number_exponation_part(Bin, N, DecimalOffset, ExpSign, Exp * 10 + C - $0, false, Nexts);
|
|
|
-number_exponation_part(<<Bin/binary>>, N, DecimalOffset, ExpSign, Exp, false, Nexts) ->
|
|
|
+-spec number_exponation_part(binary(), integer(), non_neg_integer(), 1|-1, non_neg_integer(), boolean(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
|
|
|
+number_exponation_part(<<C, Bin/binary>>, N, DecimalOffset, ExpSign, Exp, _, Nexts, Buf) when $0 =< C, C =< $9 ->
|
|
|
+ number_exponation_part(Bin, N, DecimalOffset, ExpSign, Exp * 10 + C - $0, false, Nexts, Buf);
|
|
|
+number_exponation_part(<<Bin/binary>>, N, DecimalOffset, ExpSign, Exp, false, Nexts, Buf) ->
|
|
|
Pos = ExpSign * Exp - DecimalOffset,
|
|
|
- next(Bin, N * math:pow(10, Pos), Nexts);
|
|
|
-number_exponation_part(<<Bin/binary>>, _N, _DecimalOffset, _ExpSign, _Exp, _IsFirst, _Nexts) ->
|
|
|
+ next(Bin, N * math:pow(10, Pos), Nexts, Buf);
|
|
|
+number_exponation_part(<<Bin/binary>>, _N, _DecimalOffset, _ExpSign, _Exp, _IsFirst, _Nexts, _Buf) ->
|
|
|
?ERROR(Bin).
|