瀏覽代碼

Merge pull request #93 from ratelle/master

Add replace_undefined and escape_forward_slashes
pull/67/merge
Paul J. Davis 9 年之前
父節點
當前提交
b403e4ab5b
共有 7 個文件被更改,包括 80 次插入5 次删除
  1. +6
    -4
      c_src/decoder.c
  2. +17
    -0
      c_src/encoder.c
  3. +2
    -0
      c_src/jiffy.c
  4. +3
    -0
      c_src/jiffy.h
  5. +28
    -0
      c_src/util.c
  6. +11
    -0
      test/jiffy_02_literal_tests.erl
  7. +13
    -1
      test/jiffy_04_string_tests.erl

+ 6
- 4
c_src/decoder.c 查看文件

@ -52,7 +52,7 @@ typedef struct {
size_t bytes_per_iter;
int is_partial;
int return_maps;
int use_nil;
ERL_NIF_TERM null_term;
char* p;
unsigned char* u;
@ -80,7 +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->null_term = d->atoms->atom_null;
d->p = NULL;
d->u = NULL;
@ -711,7 +711,9 @@ 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) {
d->use_nil = 1;
d->null_term = d->atoms->atom_nil;
} else if(get_null_term(env, val, &(d->null_term))) {
continue;
} else {
return enif_make_badarg(env);
}
@ -783,7 +785,7 @@ 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;
val = d->null_term;
dec_pop(d, st_value);
d->i += 4;
break;

+ 17
- 0
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) {

+ 2
- 0
c_src/jiffy.c 查看文件

@ -28,6 +28,8 @@ 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_null_term = make_atom(env, "null_term");
st->atom_escape_forward_slashes = make_atom(env, "escape_forward_slashes");
// Markers used in encoding
st->ref_object = make_atom(env, "$object_ref$");

+ 3
- 0
c_src/jiffy.h 查看文件

@ -30,6 +30,8 @@ typedef struct {
ERL_NIF_TERM atom_return_maps;
ERL_NIF_TERM atom_nil;
ERL_NIF_TERM atom_use_nil;
ERL_NIF_TERM atom_null_term;
ERL_NIF_TERM atom_escape_forward_slashes;
ERL_NIF_TERM ref_object;
ERL_NIF_TERM ref_array;
@ -44,6 +46,7 @@ ERL_NIF_TERM make_error(jiffy_st* st, ErlNifEnv* env, const char* error);
ERL_NIF_TERM make_obj_error(jiffy_st* st, ErlNifEnv* env, const char* error,
ERL_NIF_TERM obj);
int get_bytes_per_iter(ErlNifEnv* env, ERL_NIF_TERM val, size_t* bpi);
int get_null_term(ErlNifEnv* env, ERL_NIF_TERM val, ERL_NIF_TERM *null_term);
int should_yield(size_t used, size_t limit);
int consume_timeslice(ErlNifEnv* env, size_t used, size_t limit);

+ 28
- 0
c_src/util.c 查看文件

@ -62,6 +62,34 @@ get_bytes_per_iter(ErlNifEnv* env, ERL_NIF_TERM val, size_t* bpi)
return 1;
}
int
get_null_term(ErlNifEnv* env, ERL_NIF_TERM val, ERL_NIF_TERM *null_term)
{
jiffy_st* st = (jiffy_st*) enif_priv_data(env);
const ERL_NIF_TERM* tuple;
int arity;
if(!enif_get_tuple(env, val, &arity, &tuple)) {
return 0;
}
if(arity != 2) {
return 0;
}
if(enif_compare(tuple[0], st->atom_null_term) != 0) {
return 0;
}
if(!enif_is_atom(env, tuple[1])) {
return 0;
}
*null_term = tuple[1];
return 1;
}
int
should_yield(size_t used, size_t limit)
{

+ 11
- 0
test/jiffy_02_literal_tests.erl 查看文件

@ -31,3 +31,14 @@ nil_test_() ->
{"Decode", ?_assertEqual(nil, jiffy:decode(<<"null">>, [use_nil]))},
{"Encode", ?_assertEqual(<<"null">>, jiffy:encode(nil, [use_nil]))}
]}.
null_term_test_() ->
T = [
{undefined, [{null_term, undefined}]},
{whatever, [{null_term, whatever}]},
{undefined, [use_nil, {null_term, undefined}]},
{nil, [{null_term, undefined}, use_nil]},
{whatever, [{null_term, undefined}, {null_term, whatever}]}
],
{"null_term",
[?_assertEqual(R, jiffy:decode(<<"null">>, O)) || {R, O} <- T]}.

+ 13
- 1
test/jiffy_04_string_tests.erl 查看文件

@ -23,6 +23,8 @@ string_error_test_() ->
string_utf8_test_() ->
[gen(utf8, Case) || Case <- cases(utf8)].
string_escaped_slashes_test_() ->
[gen(escaped_slashes, Case) || Case <- cases(escaped_slashes)].
gen(ok, {J, E}) ->
gen(ok, {J, E, J});
@ -50,8 +52,13 @@ gen(utf8, {Case, Fixed}) ->
?_assertThrow({error, {invalid_string, _}}, jiffy:encode(Case)),
?_assertEqual(Fixed2, jiffy:encode(Case, [force_utf8])),
?_assertThrow({error, {_, invalid_string}}, jiffy:decode(Case2))
]}.
]};
gen(escaped_slashes, {J, E}) ->
{msg("escaped_slashes - ~s", [J]), [
{"Decode", ?_assertEqual(E, dec(J))},
{"Encode", ?_assertEqual(J, enc(E, [escape_forward_slashes]))}
]}.
cases(ok) ->
[
@ -143,4 +150,9 @@ cases(utf8) ->
{<<16#F8, 16#84, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
{<<16#FC, 16#80, 16#80, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>},
{<<16#FC, 16#82, 16#80, 16#80, 16#80, 16#80>>, <<16#EF, 16#BF, 16#BD>>}
];
cases(escaped_slashes) ->
[
{<<"\"\\/\"">>, <<"/">>}
].

Loading…
取消
儲存