Improved Elixir compatibility This implements the `use_nil` option as discussed on issue #64. Passing the atom `use_nil` as an option to both encode and decode will replace the atom `null` with `nil` when decoding and encode `nil` as `null` when encoding values.
Fixes #64 Fixes #68 Project: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/commit/2dbf89f5 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/tree/2dbf89f5 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/diff/2dbf89f5 Branch: refs/heads/master Commit: 2dbf89f51c547914e994f51457140df9e9a1ca83 Parents: 99867af Author: Stanislav Vishnevskiy <[email protected]> Authored: Tue Aug 19 11:44:49 2014 -0700 Committer: Paul J. Davis <[email protected]> Committed: Tue Aug 19 14:48:50 2014 -0500 ---------------------------------------------------------------------- c_src/decoder.c | 6 +++++- c_src/encoder.c | 9 +++++++-- c_src/jiffy.c | 2 ++ c_src/jiffy.h | 2 ++ test/jiffy_02_literal_tests.erl | 6 ++++++ 5 files changed, 22 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/2dbf89f5/c_src/decoder.c ---------------------------------------------------------------------- diff --git a/c_src/decoder.c b/c_src/decoder.c index 7cc74bd..e7dc48b 100644 --- a/c_src/decoder.c +++ b/c_src/decoder.c @@ -52,6 +52,7 @@ typedef struct { size_t bytes_per_iter; int is_partial; int return_maps; + int use_nil; char* p; unsigned char* u; @@ -79,6 +80,7 @@ dec_new(ErlNifEnv* env) d->bytes_per_iter = DEFAULT_BYTES_PER_ITER; d->is_partial = 0; d->return_maps = 0; + d->use_nil = 0; d->p = NULL; d->u = NULL; @@ -707,6 +709,8 @@ decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) #else return enif_make_badarg(env); #endif + } else if(enif_compare(val, d->atoms->atom_use_nil) == 0) { + d->use_nil = 1; } else { return enif_make_badarg(env); } @@ -777,7 +781,7 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) ret = dec_error(d, "invalid_literal"); goto done; } - val = d->atoms->atom_null; + val = d->use_nil ? d->atoms->atom_nil : d->atoms->atom_null; dec_pop(d, st_value); d->i += 4; break; http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/2dbf89f5/c_src/encoder.c ---------------------------------------------------------------------- diff --git a/c_src/encoder.c b/c_src/encoder.c index fff9752..b6ea141 100644 --- a/c_src/encoder.c +++ b/c_src/encoder.c @@ -33,6 +33,7 @@ typedef struct { int uescape; int pretty; + int use_nil; int shiftcnt; int count; @@ -75,6 +76,7 @@ enc_new(ErlNifEnv* env) e->bytes_per_iter = DEFAULT_BYTES_PER_ITER; e->uescape = 0; e->pretty = 0; + e->use_nil = 0; e->shiftcnt = 0; e->count = 0; @@ -578,6 +580,8 @@ encode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) e->uescape = 1; } else if(enif_compare(val, e->atoms->atom_pretty) == 0) { e->pretty = 1; + } else if(enif_compare(val, e->atoms->atom_use_nil) == 0) { + e->use_nil = 1; } else if(enif_compare(val, e->atoms->atom_force_utf8) == 0) { // Ignore, handled in Erlang } else if(get_bytes_per_iter(env, val, &(e->bytes_per_iter))) { @@ -708,11 +712,12 @@ encode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) stack = enif_make_list_cell(env, curr, stack); stack = enif_make_list_cell(env, e->atoms->ref_array, stack); stack = enif_make_list_cell(env, item, stack); - } else if(enif_compare(curr, e->atoms->atom_null) == 0) { + } else if(enif_compare(curr, e->atoms->atom_null) == 0 + || (e->use_nil && enif_compare(curr, e->atoms->atom_nil) == 0)) { if(!enc_literal(e, "null", 4)) { ret = enc_error(e, "null"); goto done; - } + } } else if(enif_compare(curr, e->atoms->atom_true) == 0) { if(!enc_literal(e, "true", 4)) { ret = enc_error(e, "true"); http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/2dbf89f5/c_src/jiffy.c ---------------------------------------------------------------------- diff --git a/c_src/jiffy.c b/c_src/jiffy.c index b3b4ba4..205de91 100644 --- a/c_src/jiffy.c +++ b/c_src/jiffy.c @@ -26,6 +26,8 @@ load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) st->atom_iter = make_atom(env, "iter"); st->atom_bytes_per_iter = make_atom(env, "bytes_per_iter"); st->atom_return_maps = make_atom(env, "return_maps"); + st->atom_nil = make_atom(env, "nil"); + st->atom_use_nil = make_atom(env, "use_nil"); // Markers used in encoding st->ref_object = make_atom(env, "$object_ref$"); http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/2dbf89f5/c_src/jiffy.h ---------------------------------------------------------------------- diff --git a/c_src/jiffy.h b/c_src/jiffy.h index 90f364c..34dff75 100644 --- a/c_src/jiffy.h +++ b/c_src/jiffy.h @@ -28,6 +28,8 @@ typedef struct { ERL_NIF_TERM atom_iter; ERL_NIF_TERM atom_bytes_per_iter; ERL_NIF_TERM atom_return_maps; + ERL_NIF_TERM atom_nil; + ERL_NIF_TERM atom_use_nil; ERL_NIF_TERM ref_object; ERL_NIF_TERM ref_array; http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/2dbf89f5/test/jiffy_02_literal_tests.erl ---------------------------------------------------------------------- diff --git a/test/jiffy_02_literal_tests.erl b/test/jiffy_02_literal_tests.erl index 4c50a34..a5ff576 100644 --- a/test/jiffy_02_literal_tests.erl +++ b/test/jiffy_02_literal_tests.erl @@ -26,3 +26,9 @@ null_test_() -> {"Decode", ?_assertEqual(null, jiffy:decode(<<"null">>))}, {"Encode", ?_assertEqual(<<"null">>, jiffy:encode(null))} ]}. + +nil_test_() -> + {"null", [ + {"Decode", ?_assertEqual(nil, jiffy:decode(<<"null">>, [use_nil]))}, + {"Encode", ?_assertEqual(<<"null">>, jiffy:encode(nil, [use_nil]))} + ]}.
