Browse Source

配列とオブジェクトのデコード処理の先頭で、空白文字の除去処理が重複して行われていたのを修正

Takeru Ohta 11 years ago
parent
commit
d766be8686
2 changed files with 28 additions and 15 deletions
  1. 14 13
      src/jsone_decode.erl
  2. 14 2
      test/jsone_decode_tests.erl

+ 14 - 13
src/jsone_decode.erl

@@ -44,10 +44,10 @@
 -type whitespace_next() :: value
                          | array
                          | object
-                         | string
                          | {array_next, [jsone:json_value()]}
+                         | {object_key, jsone:json_object_members()}
                          | {object_value, jsone:json_string(), jsone:json_object_members()}
-                         | {object_next, jsone:json_string(), jsone:json_value(), jsone:json_object_members()}.
+                         | {object_next, jsone:json_object_members()}.
 
 -type decode_result() :: {ok, jsone:json_value(), Rest::binary()} | {error, {Reason::term(), [erlang:stack_item()]}}.
 
@@ -69,7 +69,7 @@ next(<<Bin/binary>>, Value, [Next | Nexts], Buf) ->
     case Next of
         {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)
+        {object_next, Key, Members} -> whitespace(Bin, {object_next, [{Key, Value} | Members]}, Nexts, Buf)
     end.
 
 -spec whitespace(binary(), whitespace_next(), [next()], binary()) -> decode_result().
@@ -82,13 +82,10 @@ whitespace(<<Bin/binary>>,      Next, Nexts, Buf) ->
         value  -> value(Bin, Nexts, Buf);
         array  -> array(Bin, Nexts, Buf);
         object -> object(Bin, Nexts, Buf);
-        string -> case Bin of
-                      <<$", Bin2/binary>> -> string(Bin2, byte_size(Buf), Nexts, Buf);
-                      _                   -> ?ERROR(whitespace, [Bin, Next, Nexts, Buf])
-                  end;
-        {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)
+        {object_key, Members}        -> object_key(Bin, Members, Nexts, Buf);
+        {array_next, Values}         -> array_next(Bin, Values, Nexts, Buf);
+        {object_value, Key, Members} -> object_value(Bin, Key, Members, Nexts, Buf);
+        {object_next, Members}       -> object_next(Bin, Members, Nexts, Buf)
     end.
 
 -spec value(binary(), [next()], binary()) -> decode_result().
@@ -102,7 +99,7 @@ value(<<Bin/binary>>, Nexts, Buf)          -> number(Bin, Nexts, Buf).
 
 -spec array(binary(), [next()], binary()) -> decode_result().
 array(<<$], Bin/binary>>, Nexts, Buf) -> next(Bin, [], Nexts, Buf);
-array(<<Bin/binary>>, Nexts, Buf)     -> whitespace(Bin, value, [{array_next, []} | Nexts], Buf).
+array(<<Bin/binary>>, Nexts, Buf)     -> value(Bin, [{array_next, []} | Nexts], Buf).
 
 -spec array_next(binary(), [jsone:json_value()], [next()], binary()) -> decode_result().
 array_next(<<$], Bin/binary>>, Values, Nexts, Buf) -> next(Bin, lists:reverse(Values), Nexts, Buf);
@@ -111,7 +108,11 @@ array_next(Bin,                Values, Nexts, Buf) -> ?ERROR(array_next, [Bin, V
 
 -spec object(binary(), [next()], binary()) -> decode_result().
 object(<<$}, Bin/binary>>, Nexts, Buf) -> next(Bin, {[]}, Nexts, Buf);
-object(<<Bin/binary>>, Nexts, Buf) -> whitespace(Bin, string, [{object_value, []} | Nexts], Buf).
+object(<<Bin/binary>>, Nexts, Buf)     -> object_key(Bin, [], Nexts, Buf).
+
+-spec object_key(binary(), jsone:json_object_members(), [next()], binary()) -> decode_result().
+object_key(<<$", Bin/binary>>, Members, Nexts, Buf) -> string(Bin, byte_size(Buf), [{object_value, Members} | Nexts], Buf);
+object_key(<<Bin/binary>>, Members, Nexts, Buf)     -> ?ERROR(object_key, [Bin, Members, Nexts, Buf]).
 
 -spec object_value(binary(), jsone:json_string(), jsone:json_object_members(), [next()], binary()) -> decode_result().
 object_value(<<$:, Bin/binary>>, Key, Members, Nexts, Buf) -> whitespace(Bin, value, [{object_next, Key, Members} | Nexts], Buf);
@@ -119,7 +120,7 @@ object_value(Bin,                Key, Members, Nexts, Buf) -> ?ERROR(object_valu
 
 -spec object_next(binary(), jsone:json_object_members(), [next()], binary()) -> decode_result().
 object_next(<<$}, Bin/binary>>, Members, Nexts, Buf) -> next(Bin, {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) -> whitespace(Bin, {object_key, Members}, Nexts, Buf);
 object_next(Bin,                Members, Nexts, Buf) -> ?ERROR(object_next, [Bin, Members, Nexts, Buf]).
 
 -spec string(binary(), non_neg_integer(), [next()], binary()) -> decode_result().

+ 14 - 2
test/jsone_decode_tests.erl

@@ -121,7 +121,13 @@ decode_test_() ->
      %% 配列系
      {"配列がデコード可能",
       fun () ->
-              Input    = <<"[1, 2, \"abc\", null]">>,
+              Input    = <<"[1,2,\"abc\",null]">>,
+              Expected = [1, 2, <<"abc">>, null],
+              ?assertEqual({ok, Expected, <<"">>}, jsone_decode:decode(Input))
+      end},
+     {"空白文字を含む配列がデコード可能",
+      fun () ->
+              Input    = <<"[  1,\t2, \n \"abc\",\r null]">>,
               Expected = [1, 2, <<"abc">>, null],
               ?assertEqual({ok, Expected, <<"">>}, jsone_decode:decode(Input))
       end},
@@ -149,7 +155,13 @@ decode_test_() ->
      %% オブジェクト系
      {"オブジェクトがデコード可能",
       fun () ->
-              Input    = <<"{\"1\":2, \"key\":\"value\"}">>,
+              Input    = <<"{\"1\":2,\"key\":\"value\"}">>,
+              Expected = {[{<<"key">>, <<"value">>}, {<<"1">>, 2}]},
+              ?assertEqual({ok, Expected, <<"">>}, jsone_decode:decode(Input))
+      end},
+     {"空白文字を含むオブジェクトがデコード可能",
+      fun () ->
+              Input    = <<"{  \"1\" :\t 2,\n\r\"key\" :   \n  \"value\"}">>,
               Expected = {[{<<"key">>, <<"value">>}, {<<"1">>, 2}]},
               ?assertEqual({ok, Expected, <<"">>}, jsone_decode:decode(Input))
       end},