Skip to content

Commit 704547f

Browse files
author
David Hull
committed
Add jiffy:partial_encode/2 function.
1 parent 5b7cf0b commit 704547f

File tree

5 files changed

+61
-12
lines changed

5 files changed

+61
-12
lines changed

c_src/encoder.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -628,16 +628,28 @@ enc_object_element(Encoder* e, int first, ERL_NIF_TERM curr, ERL_NIF_TERM* stack
628628
if(!first && !enc_comma(e)) {
629629
return enc_error(e, "internal_error");
630630
}
631-
if(!enc_string(e, tuple[0])) {
632-
return enc_obj_error(e, "invalid_object_member_key", tuple[0]);
633-
}
634-
if(!enc_colon(e)) {
635-
return enc_error(e, "internal_error");
631+
if(enif_compare(tuple[0], e->atoms->atom_partial_object) == 0) {
632+
if(!enif_is_binary(env, tuple[1])) {
633+
return enc_obj_error(e, "invalid_json_string", curr);
634+
}
635+
if(!enc_json(e, tuple[1])) {
636+
return enc_error(e, "internal_error");
637+
}
638+
stack = enif_make_list_cell(env, curr, stack);
639+
stack = enif_make_list_cell(env, e->atoms->ref_object, stack);
640+
*stackp = stack;
641+
} else {
642+
if(!enc_string(e, tuple[0])) {
643+
return enc_obj_error(e, "invalid_object_member_key", tuple[0]);
644+
}
645+
if(!enc_colon(e)) {
646+
return enc_error(e, "internal_error");
647+
}
648+
stack = enif_make_list_cell(env, curr, stack);
649+
stack = enif_make_list_cell(env, e->atoms->ref_object, stack);
650+
stack = enif_make_list_cell(env, tuple[1], stack);
651+
*stackp = stack;
636652
}
637-
stack = enif_make_list_cell(env, curr, stack);
638-
stack = enif_make_list_cell(env, e->atoms->ref_object, stack);
639-
stack = enif_make_list_cell(env, tuple[1], stack);
640-
*stackp = stack;
641653
return 0;
642654
}
643655

@@ -843,7 +855,8 @@ encode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
843855
ret = enc_object_element(e, 1, tuple[0], &stack);
844856
if (ret) { goto done; }
845857
} else if(arity == 2) {
846-
if(enif_compare(tuple[0], e->atoms->atom_json) != 0) {
858+
if((enif_compare(tuple[0], e->atoms->atom_json) != 0) &&
859+
(enif_compare(tuple[0], e->atoms->atom_partial_array) != 0)) {
847860
ret = enc_obj_error(e, "invalid_ejson", curr);
848861
goto done;
849862
}

c_src/jiffy.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
1717
st->atom_true = make_atom(env, "true");
1818
st->atom_false = make_atom(env, "false");
1919
st->atom_json = make_atom(env, "json");
20+
st->atom_partial_object = make_atom(env, "$partial_object$");
21+
st->atom_partial_array = make_atom(env, "$partial_array$");
2022
st->atom_bignum = make_atom(env, "bignum");
2123
st->atom_bignum_e = make_atom(env, "bignum_e");
2224
st->atom_bigdbl = make_atom(env, "bigdbl");

c_src/jiffy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ typedef struct {
2020
ERL_NIF_TERM atom_true;
2121
ERL_NIF_TERM atom_false;
2222
ERL_NIF_TERM atom_json;
23+
ERL_NIF_TERM atom_partial_object;
24+
ERL_NIF_TERM atom_partial_array;
2325
ERL_NIF_TERM atom_bignum;
2426
ERL_NIF_TERM atom_bignum_e;
2527
ERL_NIF_TERM atom_bigdbl;

src/jiffy.erl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
% See the LICENSE file for more information.
33

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

88
-compile([no_native]).
@@ -107,6 +107,16 @@ encode(Data, Options) ->
107107
end.
108108

109109

110+
-spec partial_encode(json_array(), encode_options()) -> {'$partial_array$', binary()};
111+
(json_object(), encode_options()) -> {'$partial_object$', binary()}.
112+
partial_encode(Data, Options) when is_list(Data) ->
113+
Json = iolist_to_binary(encode(Data, Options)),
114+
{'$partial_array$', binary_part(Json, 1, byte_size(Json) - 2)};
115+
partial_encode(Data, Options) when is_tuple(Data) ->
116+
Json = iolist_to_binary(encode(Data, Options)),
117+
{'$partial_object$', binary_part(Json, 1, byte_size(Json) - 2)}.
118+
119+
110120
finish_decode({bignum, Value}) ->
111121
list_to_integer(binary_to_list(Value));
112122
finish_decode({bignum_e, Value}) ->

test/jiffy_16_preencode_tests.erl

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ gen(ok, {E1, J, E2}) ->
1919
{"Decode", ?_assertEqual(E2, dec(J))}
2020
]};
2121

22+
gen(ok, {E, J}) ->
23+
{msg("~p", [E]), [
24+
{"Encode", ?_assertEqual(J, enc(E))}
25+
]};
26+
2227
gen(error, E) ->
2328
{msg("Error: ~p", [E]), [
2429
?_assertThrow({error, _}, enc(E))
@@ -45,7 +50,24 @@ cases(ok) ->
4550
, { [ {json, JSON}, {json, JSON} ], <<"[[1,\"a\"],[1,\"a\"]]">>, [ EJSON, EJSON ]}
4651
, { {[ {<<"a">>, {json, JSON}} ]}, <<"{\"a\":[1,\"a\"]}">>, {[ {<<"a">>, EJSON} ]}}
4752
],
48-
TopTests ++ BuriedTests;
53+
54+
PartialArray = jiffy:partial_encode([ 2, 3 ], []),
55+
PartialArrayTests =
56+
[ {[ PartialArray ], <<"[2,3]">>}
57+
, {[ 1, PartialArray ], <<"[1,2,3]">>}
58+
, {[ PartialArray, 4 ], <<"[2,3,4]">>}
59+
, {[ 1, PartialArray, 4 ], <<"[1,2,3,4]">>}
60+
],
61+
62+
PartialObject = jiffy:partial_encode({[ {<<"ii">>, <<"two">>}, {<<"iii">>, 3} ]}, []),
63+
PartialObjectTests =
64+
[ {{[ PartialObject ]}, <<"{\"ii\":\"two\",\"iii\":3}">>}
65+
, {{[ {<<"i">>, 1}, PartialObject ]}, <<"{\"i\":1,\"ii\":\"two\",\"iii\":3}">>}
66+
, {{[ PartialObject, {<<"iv">>, 4} ]}, <<"{\"ii\":\"two\",\"iii\":3,\"iv\":4}">>}
67+
, {{[ {<<"i">>, 1}, PartialObject, {<<"iv">>, 4} ]}, <<"{\"i\":1,\"ii\":\"two\",\"iii\":3,\"iv\":4}">>}
68+
],
69+
70+
TopTests ++ BuriedTests ++ PartialArrayTests ++ PartialObjectTests;
4971

5072
cases(error) ->
5173
[ {json, true}

0 commit comments

Comments
 (0)