소스 검색

Add return_truncated decode flag

pull/158/head
Sargun Dhillon 7 년 전
부모
커밋
66797a92a3
No known key found for this signature in database GPG 키 ID: 93CC882F8A89DFE6
6개의 변경된 파일45개의 추가작업 그리고 2개의 파일을 삭제
  1. +3
    -0
      README.md
  2. +10
    -1
      c_src/decoder.c
  3. +2
    -0
      c_src/jiffy.c
  4. +2
    -0
      c_src/jiffy.h
  5. +3
    -1
      src/jiffy.erl
  6. +25
    -0
      test/jiffy_18_return_truncated_tests.erl

+ 3
- 0
README.md 파일 보기

@ -48,6 +48,9 @@ The options for decode are:
JSON term is decoded the return value of decode/2 becomes
`{has_trailer, FirstTerm, RestData::iodata()}`. This is useful to
decode multiple terms in a single binary.
* `return_truncated` - If the JSON passed to the decoder is incomplete
return `{truncated, Pos}`, where `Pos`, is the length of JSON read
before hitting the end of the interpretable term.
* `dedupe_keys` - If a key is repeated in a JSON object this flag
will ensure that the parsed object only contains a single entry
containing the last value seen. This mirrors the parsing beahvior

+ 10
- 1
c_src/decoder.c 파일 보기

@ -52,6 +52,7 @@ typedef struct {
size_t bytes_per_red;
int is_partial;
int return_maps;
int return_truncated;
int return_trailer;
int dedupe_keys;
int copy_strings;
@ -84,6 +85,7 @@ dec_new(ErlNifEnv* env)
d->is_partial = 0;
d->return_maps = 0;
d->return_trailer = 0;
d->return_truncated = 0;
d->dedupe_keys = 0;
d->copy_strings = 0;
d->null_term = d->atoms->atom_null;
@ -689,6 +691,8 @@ decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
#endif
} else if(enif_compare(val, d->atoms->atom_return_trailer) == 0) {
d->return_trailer = 1;
} else if(enif_compare(val, d->atoms->atom_return_truncated) == 0) {
d->return_truncated = 1;
} else if(enif_compare(val, d->atoms->atom_dedupe_keys) == 0) {
d->dedupe_keys = 1;
} else if(enif_compare(val, d->atoms->atom_copy_strings) == 0) {
@ -1035,7 +1039,12 @@ decode_done:
}
if(dec_curr(d) != st_done) {
ret = dec_error(d, "truncated_json");
if (d->return_truncated) {
ret = enif_make_tuple2(env, d->atoms->atom_truncated,
enif_make_int(d->env, d->i+1));
} else {
ret = dec_error(d, "truncated_json");
}
} else if(d->is_partial) {
ret = enif_make_tuple2(env, d->atoms->atom_partial, val);
} else {

+ 2
- 0
c_src/jiffy.c 파일 보기

@ -24,9 +24,11 @@ load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
st->atom_pretty = make_atom(env, "pretty");
st->atom_force_utf8 = make_atom(env, "force_utf8");
st->atom_iter = make_atom(env, "iter");
st->atom_truncated = make_atom(env, "truncated");
st->atom_bytes_per_iter = make_atom(env, "bytes_per_iter");
st->atom_return_maps = make_atom(env, "return_maps");
st->atom_return_trailer = make_atom(env, "return_trailer");
st->atom_return_truncated = make_atom(env, "return_truncated");
st->atom_has_trailer = make_atom(env, "has_trailer");
st->atom_nil = make_atom(env, "nil");
st->atom_use_nil = make_atom(env, "use_nil");

+ 2
- 0
c_src/jiffy.h 파일 보기

@ -27,9 +27,11 @@ typedef struct {
ERL_NIF_TERM atom_pretty;
ERL_NIF_TERM atom_force_utf8;
ERL_NIF_TERM atom_iter;
ERL_NIF_TERM atom_truncated;
ERL_NIF_TERM atom_bytes_per_iter;
ERL_NIF_TERM atom_return_maps;
ERL_NIF_TERM atom_return_trailer;
ERL_NIF_TERM atom_return_truncated;
ERL_NIF_TERM atom_has_trailer;
ERL_NIF_TERM atom_nil;
ERL_NIF_TERM atom_use_nil;

+ 3
- 1
src/jiffy.erl 파일 보기

@ -34,11 +34,13 @@
-endif.
-type jiffy_decode_result() :: json_value()
| {has_trailer, json_value(), binary()}.
| {has_trailer, json_value(), binary()}
| {truncated, non_neg_integer()}.
-type decode_option() :: return_maps
| use_nil
| return_trailer
| return_truncated
| dedupe_keys
| {null_term, any()}
| {bytes_per_iter, non_neg_integer()}

+ 25
- 0
test/jiffy_18_return_truncated_tests.erl 파일 보기

@ -0,0 +1,25 @@
% This file is part of Jiffy released under the MIT license.
% See the LICENSE file for more information.
-module(jiffy_18_return_truncated_tests).
-include_lib("eunit/include/eunit.hrl").
cases() ->
[
{<<"">>, 1},
{<<"{">>, 2}
].
return_truncated_test_() ->
Opts = [return_truncated],
{"Test return_truncated", lists:map(fun({Data, Pos}) ->
?_assertEqual({truncated, Pos}, jiffy:decode(Data, Opts))
end, cases())}.
error_truncated_test_() ->
Opts = [],
{"Test truncated error case", lists:map(fun({Data, Pos}) ->
Error = {error, {Pos, truncated_json}},
?_assertException(throw, Error, jiffy:decode(Data, Opts))
end, cases())}.

불러오는 중...
취소
저장