Skip to content

Commit

Permalink
Add jiffy:partial_encode/2 function.
Browse files Browse the repository at this point in the history
  • Loading branch information
David Hull committed Mar 15, 2017
1 parent 5b7cf0b commit 704547f
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 12 deletions.
33 changes: 23 additions & 10 deletions c_src/encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,16 +628,28 @@ enc_object_element(Encoder* e, int first, ERL_NIF_TERM curr, ERL_NIF_TERM* stack
if(!first && !enc_comma(e)) {
return enc_error(e, "internal_error");
}
if(!enc_string(e, tuple[0])) {
return enc_obj_error(e, "invalid_object_member_key", tuple[0]);
}
if(!enc_colon(e)) {
return enc_error(e, "internal_error");
if(enif_compare(tuple[0], e->atoms->atom_partial_object) == 0) {
if(!enif_is_binary(env, tuple[1])) {
return enc_obj_error(e, "invalid_json_string", curr);
}
if(!enc_json(e, tuple[1])) {
return enc_error(e, "internal_error");
}
stack = enif_make_list_cell(env, curr, stack);
stack = enif_make_list_cell(env, e->atoms->ref_object, stack);
*stackp = stack;
} else {
if(!enc_string(e, tuple[0])) {
return enc_obj_error(e, "invalid_object_member_key", tuple[0]);
}
if(!enc_colon(e)) {
return enc_error(e, "internal_error");
}
stack = enif_make_list_cell(env, curr, stack);
stack = enif_make_list_cell(env, e->atoms->ref_object, stack);
stack = enif_make_list_cell(env, tuple[1], stack);
*stackp = stack;
}
stack = enif_make_list_cell(env, curr, stack);
stack = enif_make_list_cell(env, e->atoms->ref_object, stack);
stack = enif_make_list_cell(env, tuple[1], stack);
*stackp = stack;
return 0;
}

Expand Down Expand Up @@ -843,7 +855,8 @@ encode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ret = enc_object_element(e, 1, tuple[0], &stack);
if (ret) { goto done; }
} else if(arity == 2) {
if(enif_compare(tuple[0], e->atoms->atom_json) != 0) {
if((enif_compare(tuple[0], e->atoms->atom_json) != 0) &&
(enif_compare(tuple[0], e->atoms->atom_partial_array) != 0)) {
ret = enc_obj_error(e, "invalid_ejson", curr);
goto done;
}
Expand Down
2 changes: 2 additions & 0 deletions c_src/jiffy.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
st->atom_true = make_atom(env, "true");
st->atom_false = make_atom(env, "false");
st->atom_json = make_atom(env, "json");
st->atom_partial_object = make_atom(env, "$partial_object$");
st->atom_partial_array = make_atom(env, "$partial_array$");
st->atom_bignum = make_atom(env, "bignum");
st->atom_bignum_e = make_atom(env, "bignum_e");
st->atom_bigdbl = make_atom(env, "bigdbl");
Expand Down
2 changes: 2 additions & 0 deletions c_src/jiffy.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ typedef struct {
ERL_NIF_TERM atom_true;
ERL_NIF_TERM atom_false;
ERL_NIF_TERM atom_json;
ERL_NIF_TERM atom_partial_object;
ERL_NIF_TERM atom_partial_array;
ERL_NIF_TERM atom_bignum;
ERL_NIF_TERM atom_bignum_e;
ERL_NIF_TERM atom_bigdbl;
Expand Down
12 changes: 11 additions & 1 deletion src/jiffy.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
% See the LICENSE file for more information.

-module(jiffy).
-export([decode/1, decode/2, encode/1, encode/2]).
-export([decode/1, decode/2, encode/1, encode/2, partial_encode/2]).
-define(NOT_LOADED, not_loaded(?LINE)).

-compile([no_native]).
Expand Down Expand Up @@ -107,6 +107,16 @@ encode(Data, Options) ->
end.


-spec partial_encode(json_array(), encode_options()) -> {'$partial_array$', binary()};
(json_object(), encode_options()) -> {'$partial_object$', binary()}.
partial_encode(Data, Options) when is_list(Data) ->
Json = iolist_to_binary(encode(Data, Options)),
{'$partial_array$', binary_part(Json, 1, byte_size(Json) - 2)};
partial_encode(Data, Options) when is_tuple(Data) ->
Json = iolist_to_binary(encode(Data, Options)),
{'$partial_object$', binary_part(Json, 1, byte_size(Json) - 2)}.


finish_decode({bignum, Value}) ->
list_to_integer(binary_to_list(Value));
finish_decode({bignum_e, Value}) ->
Expand Down
24 changes: 23 additions & 1 deletion test/jiffy_16_preencode_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ gen(ok, {E1, J, E2}) ->
{"Decode", ?_assertEqual(E2, dec(J))}
]};

gen(ok, {E, J}) ->
{msg("~p", [E]), [
{"Encode", ?_assertEqual(J, enc(E))}
]};

gen(error, E) ->
{msg("Error: ~p", [E]), [
?_assertThrow({error, _}, enc(E))
Expand All @@ -45,7 +50,24 @@ cases(ok) ->
, { [ {json, JSON}, {json, JSON} ], <<"[[1,\"a\"],[1,\"a\"]]">>, [ EJSON, EJSON ]}
, { {[ {<<"a">>, {json, JSON}} ]}, <<"{\"a\":[1,\"a\"]}">>, {[ {<<"a">>, EJSON} ]}}
],
TopTests ++ BuriedTests;

PartialArray = jiffy:partial_encode([ 2, 3 ], []),
PartialArrayTests =
[ {[ PartialArray ], <<"[2,3]">>}
, {[ 1, PartialArray ], <<"[1,2,3]">>}
, {[ PartialArray, 4 ], <<"[2,3,4]">>}
, {[ 1, PartialArray, 4 ], <<"[1,2,3,4]">>}
],

PartialObject = jiffy:partial_encode({[ {<<"ii">>, <<"two">>}, {<<"iii">>, 3} ]}, []),
PartialObjectTests =
[ {{[ PartialObject ]}, <<"{\"ii\":\"two\",\"iii\":3}">>}
, {{[ {<<"i">>, 1}, PartialObject ]}, <<"{\"i\":1,\"ii\":\"two\",\"iii\":3}">>}
, {{[ PartialObject, {<<"iv">>, 4} ]}, <<"{\"ii\":\"two\",\"iii\":3,\"iv\":4}">>}
, {{[ {<<"i">>, 1}, PartialObject, {<<"iv">>, 4} ]}, <<"{\"i\":1,\"ii\":\"two\",\"iii\":3,\"iv\":4}">>}
],

TopTests ++ BuriedTests ++ PartialArrayTests ++ PartialObjectTests;

cases(error) ->
[ {json, true}
Expand Down

0 comments on commit 704547f

Please sign in to comment.