From 862bfd6d738c60488b22464c6f438bea0968c6ae Mon Sep 17 00:00:00 2001 From: Jeremie Lasalle Ratelle Date: Fri, 24 Apr 2015 12:35:32 -0400 Subject: [PATCH 1/2] Add use_undefined option to turn null into undefined --- c_src/decoder.c | 20 ++++++++++++++++++-- c_src/jiffy.c | 2 ++ c_src/jiffy.h | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/c_src/decoder.c b/c_src/decoder.c index ad3e8d3..f815db2 100644 --- a/c_src/decoder.c +++ b/c_src/decoder.c @@ -53,6 +53,7 @@ typedef struct { int is_partial; int return_maps; int use_nil; + int use_undefined; char* p; unsigned char* u; @@ -81,6 +82,7 @@ dec_new(ErlNifEnv* env) d->is_partial = 0; d->return_maps = 0; d->use_nil = 0; + d->use_undefined = 0; d->p = NULL; d->u = NULL; @@ -711,8 +713,16 @@ decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) return enif_make_badarg(env); #endif } else if(enif_compare(val, d->atoms->atom_use_nil) == 0) { + /* use_nil and use_undefined are mutually exclusive */ + if (d->use_undefined) + return enif_make_badarg(env); d->use_nil = 1; - } else { + } else if(enif_compare(val, d->atoms->atom_use_undefined) == 0) { + if (d->use_nil) + return enif_make_badarg(env); + d->use_undefined = 1; + } + else { return enif_make_badarg(env); } } @@ -783,7 +793,13 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) ret = dec_error(d, "invalid_literal"); goto done; } - val = d->use_nil ? d->atoms->atom_nil : d->atoms->atom_null; + if(d->use_nil) { + val = d->atoms->atom_nil; + } else if(d->use_undefined) { + val = d->atoms->atom_undefined; + } else { + val = d->atoms->atom_null; + } dec_pop(d, st_value); d->i += 4; break; diff --git a/c_src/jiffy.c b/c_src/jiffy.c index 31aa854..c4fe484 100644 --- a/c_src/jiffy.c +++ b/c_src/jiffy.c @@ -14,6 +14,7 @@ load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) st->atom_ok = make_atom(env, "ok"); st->atom_error = make_atom(env, "error"); st->atom_null = make_atom(env, "null"); + st->atom_undefined = make_atom(env, "undefined"); st->atom_true = make_atom(env, "true"); st->atom_false = make_atom(env, "false"); st->atom_bignum = make_atom(env, "bignum"); @@ -28,6 +29,7 @@ load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) 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"); + st->atom_use_undefined = make_atom(env, "use_undefined"); // Markers used in encoding st->ref_object = make_atom(env, "$object_ref$"); diff --git a/c_src/jiffy.h b/c_src/jiffy.h index 6d869a5..5dfe8a3 100644 --- a/c_src/jiffy.h +++ b/c_src/jiffy.h @@ -16,6 +16,7 @@ typedef struct { ERL_NIF_TERM atom_ok; ERL_NIF_TERM atom_error; ERL_NIF_TERM atom_null; + ERL_NIF_TERM atom_undefined; ERL_NIF_TERM atom_true; ERL_NIF_TERM atom_false; ERL_NIF_TERM atom_bignum; @@ -30,6 +31,7 @@ typedef struct { ERL_NIF_TERM atom_return_maps; ERL_NIF_TERM atom_nil; ERL_NIF_TERM atom_use_nil; + ERL_NIF_TERM atom_use_undefined; ERL_NIF_TERM ref_object; ERL_NIF_TERM ref_array; From dec739b287a8d47415c48142db9070f61f7b3c9e Mon Sep 17 00:00:00 2001 From: Jeremie Lasalle Ratelle Date: Wed, 20 May 2015 18:20:17 -0400 Subject: [PATCH 2/2] Add escape forward slashes --- c_src/encoder.c | 17 +++++++++++++++++ c_src/jiffy.c | 1 + c_src/jiffy.h | 1 + 3 files changed, 19 insertions(+) diff --git a/c_src/encoder.c b/c_src/encoder.c index 471cfcc..59b1b52 100644 --- a/c_src/encoder.c +++ b/c_src/encoder.c @@ -34,6 +34,7 @@ typedef struct { int uescape; int pretty; int use_nil; + int escape_forward_slashes; int shiftcnt; int count; @@ -77,6 +78,7 @@ enc_new(ErlNifEnv* env) e->uescape = 0; e->pretty = 0; e->use_nil = 0; + e->escape_forward_slashes = 0; e->shiftcnt = 0; e->count = 0; @@ -281,6 +283,12 @@ enc_string(Encoder* e, ERL_NIF_TERM val) esc_extra += 1; i++; continue; + case '/': + if(e->escape_forward_slashes) { + esc_extra += 1; + i++; + continue; + } default: if(data[i] < 0x20) { esc_extra += 5; @@ -348,6 +356,13 @@ enc_string(Encoder* e, ERL_NIF_TERM val) e->p[e->i++] = 't'; i++; continue; + case '/': + if(e->escape_forward_slashes) { + e->p[e->i++] = '\\'; + e->u[e->i++] = data[i]; + i++; + continue; + } default: if(data[i] < 0x20) { ulen = unicode_uescape(data[i], &(e->p[e->i])); @@ -591,6 +606,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_escape_forward_slashes) == 0) { + e->escape_forward_slashes = 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) { diff --git a/c_src/jiffy.c b/c_src/jiffy.c index c4fe484..2080f46 100644 --- a/c_src/jiffy.c +++ b/c_src/jiffy.c @@ -30,6 +30,7 @@ load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) st->atom_nil = make_atom(env, "nil"); st->atom_use_nil = make_atom(env, "use_nil"); st->atom_use_undefined = make_atom(env, "use_undefined"); + st->atom_escape_forward_slashes = make_atom(env, "escape_forward_slashes"); // Markers used in encoding st->ref_object = make_atom(env, "$object_ref$"); diff --git a/c_src/jiffy.h b/c_src/jiffy.h index 5dfe8a3..60a9ed4 100644 --- a/c_src/jiffy.h +++ b/c_src/jiffy.h @@ -32,6 +32,7 @@ typedef struct { ERL_NIF_TERM atom_nil; ERL_NIF_TERM atom_use_nil; ERL_NIF_TERM atom_use_undefined; + ERL_NIF_TERM atom_escape_forward_slashes; ERL_NIF_TERM ref_object; ERL_NIF_TERM ref_array;