jsone_decode.erl 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. %%% @doc JSON decoding module
  2. %%% @private
  3. %%% @end
  4. %%%
  5. %%% Copyright (c) 2013-2014, Takeru Ohta <phjgt308@gmail.com>
  6. %%%
  7. %%% The MIT License
  8. %%%
  9. %%% Permission is hereby granted, free of charge, to any person obtaining a copy
  10. %%% of this software and associated documentation files (the "Software"), to deal
  11. %%% in the Software without restriction, including without limitation the rights
  12. %%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. %%% copies of the Software, and to permit persons to whom the Software is
  14. %%% furnished to do so, subject to the following conditions:
  15. %%%
  16. %%% The above copyright notice and this permission notice shall be included in
  17. %%% all copies or substantial portions of the Software.
  18. %%%
  19. %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. %%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. %%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. %%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. %%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. %%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. %%% THE SOFTWARE.
  26. %%%
  27. %%%---------------------------------------------------------------------------------------
  28. -module(jsone_decode).
  29. %%--------------------------------------------------------------------------------
  30. %% Exported API
  31. %%--------------------------------------------------------------------------------
  32. -export([decode/1]).
  33. %%--------------------------------------------------------------------------------
  34. %% Macros & Types
  35. %%--------------------------------------------------------------------------------
  36. -define(ERROR(Json), error({invalid_json, Json})).
  37. -type next() :: {array_next, [jsone:json_value()]}
  38. | {object_value, jsone:json_object_members()}
  39. | {object_next, jsone:json_string(), jsone:json_object_members()}.
  40. -type whitespace_next() :: value
  41. | array
  42. | object
  43. | string
  44. | {array_next, [jsone:json_value()]}
  45. | {object_value, jsone:json_string(), jsone:json_object_members()}
  46. | {object_next, jsone:json_string(), jsone:json_value(), jsone:json_object_members()}.
  47. %%--------------------------------------------------------------------------------
  48. %% Exported Functions
  49. %%--------------------------------------------------------------------------------
  50. %% @doc JSONバイナリをデコードする.
  51. %%
  52. %% デコードに失敗した場合は`{invalid_json, 失敗位置より後のJSON::binary()}'形式のエラーが送出される.
  53. -spec decode(binary()) -> {jsone:json_value(), RestJson::binary()}.
  54. decode(<<Json/binary>>) ->
  55. whitespace(Json, value, [], <<"">>).
  56. %%--------------------------------------------------------------------------------
  57. %% Internal Functions
  58. %%--------------------------------------------------------------------------------
  59. -spec next(binary(), jsone:json_value(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  60. next(<<Bin/binary>>, Value, [], _Buf) ->
  61. {Value, Bin};
  62. next(<<Bin/binary>>, Value, [Next | Nexts], Buf) ->
  63. case Next of
  64. {array_next, Values} -> whitespace(Bin, {array_next, [Value | Values]}, Nexts, Buf);
  65. {object_value, Members} -> whitespace(Bin, {object_value, Value, Members}, Nexts, Buf);
  66. {object_next, Key, Members} -> whitespace(Bin, {object_next, Key, Value, Members}, Nexts, Buf)
  67. end.
  68. -spec whitespace(binary(), whitespace_next(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  69. whitespace(<<$ , Bin/binary>>, Next, Nexts, Buf) -> whitespace(Bin, Next, Nexts, Buf);
  70. whitespace(<<$\t, Bin/binary>>, Next, Nexts, Buf) -> whitespace(Bin, Next, Nexts, Buf);
  71. whitespace(<<$\r, Bin/binary>>, Next, Nexts, Buf) -> whitespace(Bin, Next, Nexts, Buf);
  72. whitespace(<<$\n, Bin/binary>>, Next, Nexts, Buf) -> whitespace(Bin, Next, Nexts, Buf);
  73. whitespace(<<Bin/binary>>, Next, Nexts, Buf) ->
  74. case Next of
  75. value -> value(Bin, Nexts, Buf);
  76. array -> array(Bin, Nexts, Buf);
  77. object -> object(Bin, Nexts, Buf);
  78. string -> case Bin of
  79. <<$", Bin2/binary>> -> string(Bin2, byte_size(Buf), Nexts, Buf);
  80. _ -> ?ERROR(Bin)
  81. end;
  82. {array_next, Values} -> array_next(Bin, Values, Nexts, Buf);
  83. {object_value, Key, Members} -> object_value(Bin, Key, Members, Nexts, Buf);
  84. {object_next, Key, Value, Members} -> object_next(Bin, [{Key, Value} | Members], Nexts, Buf)
  85. end.
  86. -spec value(binary(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  87. value(<<"false", Bin/binary>>, Nexts, Buf) -> next(Bin, false, Nexts, Buf);
  88. value(<<"true", Bin/binary>>, Nexts, Buf) -> next(Bin, true, Nexts, Buf);
  89. value(<<"null", Bin/binary>>, Nexts, Buf) -> next(Bin, null, Nexts, Buf);
  90. value(<<$[, Bin/binary>>, Nexts, Buf) -> whitespace(Bin, array, Nexts, Buf);
  91. value(<<${, Bin/binary>>, Nexts, Buf) -> whitespace(Bin, object, Nexts, Buf);
  92. value(<<$", Bin/binary>>, Nexts, Buf) -> string(Bin, byte_size(Buf), Nexts, Buf);
  93. value(<<Bin/binary>>, Nexts, Buf) -> number(Bin, Nexts, Buf).
  94. -spec array(binary(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  95. array(<<$], Bin/binary>>, Nexts, Buf) -> next(Bin, [], Nexts, Buf);
  96. array(<<Bin/binary>>, Nexts, Buf) -> whitespace(Bin, value, [{array_next, []} | Nexts], Buf).
  97. -spec array_next(binary(), [jsone:json_value()], [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  98. array_next(<<$], Bin/binary>>, Values, Nexts, Buf) -> next(Bin, lists:reverse(Values), Nexts, Buf);
  99. array_next(<<$,, Bin/binary>>, Values, Nexts, Buf) -> whitespace(Bin, value, [{array_next, Values} | Nexts], Buf);
  100. array_next(<<Bin/binary>>, _Values, _Nexts, _Buf) -> ?ERROR(Bin).
  101. -spec object(binary(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  102. object(<<$}, Bin/binary>>, Nexts, Buf) -> next(Bin, {object, []}, Nexts, Buf);
  103. object(<<Bin/binary>>, Nexts, Buf) -> whitespace(Bin, string, [{object_value, []} | Nexts], Buf).
  104. -spec object_value(binary(), jsone:json_string(), jsone:json_object_members(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  105. object_value(<<$:, Bin/binary>>, Key, Members, Nexts, Buf) -> whitespace(Bin, value, [{object_next, Key, Members} | Nexts], Buf);
  106. object_value(<<Bin/binary>>, _Key, _Members, _Nexts, _Buf) -> ?ERROR(Bin).
  107. -spec object_next(binary(), jsone:json_object_members(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  108. object_next(<<$}, Bin/binary>>, Members, Nexts, Buf) -> next(Bin, {object, Members}, Nexts, Buf);
  109. object_next(<<$,, Bin/binary>>, Members, Nexts, Buf) -> whitespace(Bin, string, [{object_value, Members} | Nexts], Buf);
  110. object_next(<<Bin/binary>>, _Members, _Nexts, _Buf) -> ?ERROR(Bin).
  111. -spec string(binary(), non_neg_integer(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  112. string(<<$", Bin/binary>>, Start, Nexts, Buf) -> next(Bin, binary:part(Buf, Start, byte_size(Buf) - Start), Nexts, Buf);
  113. string(<<$\\, B/binary>>, Start, Nexts, Buf) ->
  114. case B of
  115. <<$", Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $">>);
  116. <<$/, Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $/>>);
  117. <<$\\,Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $\\>>);
  118. <<$b, Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $\b>>);
  119. <<$f, Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $\f>>);
  120. <<$n, Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $\n>>);
  121. <<$r, Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $\r>>);
  122. <<$t, Bin/binary>> -> string(Bin, Start, Nexts, <<Buf/binary, $\t>>);
  123. <<$u, Bin/binary>> -> unicode_string(Bin, Start, Nexts, Buf);
  124. _ -> ?ERROR(B)
  125. end;
  126. string(<<C, Bin/binary>>, Start, Nexts, Buf) when 16#20 =< C ->
  127. string(Bin, Start, Nexts, <<Buf/binary, C>>).
  128. -spec unicode_string(binary(), non_neg_integer(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  129. unicode_string(<<N:4/binary, Bin/binary>>, Start, Nexts, Buf) ->
  130. case binary_to_integer(N, 16) of
  131. High when 16#D800 =< High, High =< 16#DBFF ->
  132. %% サロゲートペア
  133. case Bin of
  134. <<$\\, $u, N2:4/binary, Bin2/binary>> ->
  135. case binary_to_integer(N2, 16) of
  136. Low when 16#DC00 =< Low, Low =< 16#DFFF ->
  137. Unicode = 16#10000 + (High - 16#D800) * 16#400 + (Low - 16#DC00),
  138. string(Bin2, Start, Nexts, unicode_to_utf8(Unicode, Buf));
  139. _ -> ?ERROR(Bin)
  140. end;
  141. _ -> ?ERROR(Bin)
  142. end;
  143. Unicode when 16#DC00 =< Unicode, Unicode =< 16#DFFF -> % サロゲートペアの後半部分
  144. ?ERROR(<<N/binary, Bin/binary>>);
  145. Unicode ->
  146. string(Bin, Start, Nexts, unicode_to_utf8(Unicode, Buf))
  147. end;
  148. unicode_string(<<Bin/binary>>, _Acc, _Nexts, _Buf) ->
  149. ?ERROR(Bin).
  150. -spec unicode_to_utf8(0..1114111, binary()) -> binary().
  151. unicode_to_utf8(Code, Buf) when Code < 16#80 ->
  152. <<Buf/binary, Code>>;
  153. unicode_to_utf8(Code, Buf) when Code < 16#800 ->
  154. A = 2#11000000 bor (Code bsr 6),
  155. B = 2#10000000 bor (Code band 2#111111),
  156. <<Buf/binary, A, B>>;
  157. unicode_to_utf8(Code, Buf) when Code < 16#10000 ->
  158. A = 2#11100000 bor (Code bsr 12),
  159. B = 2#10000000 bor ((Code bsr 6) band 2#111111),
  160. C = 2#10000000 bor (Code band 2#111111),
  161. <<Buf/binary, A, B, C>>;
  162. unicode_to_utf8(Code, Buf) -> % NOTE: サロゲートペアの仕組み上、コード値が上限を越えることはないので、ここでの範囲チェックは不要
  163. A = 2#11110000 bor (Code bsr 18),
  164. B = 2#10000000 bor ((Code bsr 12) band 2#111111),
  165. C = 2#10000000 bor ((Code bsr 6) band 2#111111),
  166. D = 2#10000000 bor (Code band 2#111111),
  167. <<Buf/binary, A, B, C, D>>.
  168. -spec number(binary(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  169. number(<<$-, Bin/binary>>, Nexts, Buf) -> number_integer_part(Bin, -1, Nexts, Buf);
  170. number(<<Bin/binary>>, Nexts, Buf) -> number_integer_part(Bin, 1, Nexts, Buf).
  171. -spec number_integer_part(binary(), 1|-1, [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  172. number_integer_part(<<$0, Bin/binary>>, Sign, Nexts, Buf) ->
  173. number_fraction_part(Bin, Sign, 0, Nexts, Buf);
  174. number_integer_part(<<C, Bin/binary>>, Sign, Nexts, Buf) when $1 =< C, C =< $9 ->
  175. number_integer_part_rest(Bin, C - $0, Sign, Nexts, Buf);
  176. number_integer_part(<<Bin/binary>>, _Sign, _Nexts, _Buf) ->
  177. ?ERROR(Bin).
  178. -spec number_integer_part_rest(binary(), non_neg_integer(), 1|-1, [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  179. number_integer_part_rest(<<C, Bin/binary>>, N, Sign, Nexts, Buf) when $0 =< C, C =< $9 ->
  180. number_integer_part_rest(Bin, N * 10 + C - $0, Sign, Nexts, Buf);
  181. number_integer_part_rest(<<Bin/binary>>, N, Sign, Nexts, Buf) ->
  182. number_fraction_part(Bin, Sign, N, Nexts, Buf).
  183. -spec number_fraction_part(binary(), 1|-1, non_neg_integer(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  184. number_fraction_part(<<$., Bin/binary>>, Sign, Int, Nexts, Buf) ->
  185. number_fraction_part_rest(Bin, Sign, Int, 0, Nexts, Buf);
  186. number_fraction_part(<<Bin/binary>>, Sign, Int, Nexts, Buf) ->
  187. number_exponation_part(Bin, Sign * Int, 0, Nexts, Buf).
  188. -spec number_fraction_part_rest(binary(), 1|-1, non_neg_integer(), non_neg_integer(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  189. number_fraction_part_rest(<<C, Bin/binary>>, Sign, N, DecimalOffset, Nexts, Buf) when $0 =< C, C =< $9 ->
  190. number_fraction_part_rest(Bin, Sign, N * 10 + C - $0, DecimalOffset + 1, Nexts, Buf);
  191. number_fraction_part_rest(<<Bin/binary>>, Sign, N, DecimalOffset, Nexts, Buf) when DecimalOffset > 0 ->
  192. number_exponation_part(Bin, Sign * N, DecimalOffset, Nexts, Buf);
  193. number_fraction_part_rest(<<Bin/binary>>, _Sign, _N, _DecimalOffset, _Nexts, _Buf) ->
  194. ?ERROR(Bin).
  195. -spec number_exponation_part(binary(), integer(), non_neg_integer(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  196. number_exponation_part(<<$e, $+, Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
  197. number_exponation_part(Bin, N, DecimalOffset, 1, 0, true, Nexts, Buf);
  198. number_exponation_part(<<$E, $+, Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
  199. number_exponation_part(Bin, N, DecimalOffset, 1, 0, true, Nexts, Buf);
  200. number_exponation_part(<<$e, $-, Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
  201. number_exponation_part(Bin, N, DecimalOffset, -1, 0, true, Nexts, Buf);
  202. number_exponation_part(<<$E, $-, Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
  203. number_exponation_part(Bin, N, DecimalOffset, -1, 0, true, Nexts, Buf);
  204. number_exponation_part(<<$e, Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
  205. number_exponation_part(Bin, N, DecimalOffset, 1, 0, true, Nexts, Buf);
  206. number_exponation_part(<<$E, Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
  207. number_exponation_part(Bin, N, DecimalOffset, 1, 0, true, Nexts, Buf);
  208. number_exponation_part(<<Bin/binary>>, N, DecimalOffset, Nexts, Buf) ->
  209. case DecimalOffset of
  210. 0 -> next(Bin, N, Nexts, Buf);
  211. _ -> next(Bin, N / math:pow(10, DecimalOffset), Nexts, Buf)
  212. end.
  213. -spec number_exponation_part(binary(), integer(), non_neg_integer(), 1|-1, non_neg_integer(), boolean(), [next()], binary()) -> {jsone:json_value(), Rest::binary()}.
  214. number_exponation_part(<<C, Bin/binary>>, N, DecimalOffset, ExpSign, Exp, _, Nexts, Buf) when $0 =< C, C =< $9 ->
  215. number_exponation_part(Bin, N, DecimalOffset, ExpSign, Exp * 10 + C - $0, false, Nexts, Buf);
  216. number_exponation_part(<<Bin/binary>>, N, DecimalOffset, ExpSign, Exp, false, Nexts, Buf) ->
  217. Pos = ExpSign * Exp - DecimalOffset,
  218. next(Bin, N * math:pow(10, Pos), Nexts, Buf);
  219. number_exponation_part(<<Bin/binary>>, _N, _DecimalOffset, _ExpSign, _Exp, _IsFirst, _Nexts, _Buf) ->
  220. ?ERROR(Bin).