GitHub Merge Button hace 13 años
padre
commit
b75b8372ee
Se han modificado 4 ficheros con 66 adiciones y 6 borrados
  1. +57
    -6
      c_src/encoder.c
  2. +1
    -0
      c_src/jiffy.c
  3. +1
    -0
      c_src/jiffy.h
  4. +7
    -0
      test/jiffy_tests.erl

+ 57
- 6
c_src/encoder.c Ver fichero

@ -10,12 +10,18 @@
#define BIN_INC_SIZE 2048
#define COUNT_OF(x) (sizeof(x)/sizeof(x[0]))
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
#define MAYBE_PRETTY_INDENT(e) ( e->pretty ? enc_shift(e) : 1 )
typedef struct {
ErlNifEnv* env;
jiffy_st* atoms;
int uescape;
int pretty;
int shiftcnt;
int count;
int iolen;
@ -36,6 +42,8 @@ enc_init(Encoder* e, ErlNifEnv* env, ERL_NIF_TERM opts, ErlNifBinary* bin)
e->env = env;
e->atoms = enif_priv_data(env);
e->uescape = 0;
e->pretty = 0;
e->shiftcnt = 0;
e->count = 0;
if(!enif_is_list(env, opts)) {
@ -45,6 +53,8 @@ enc_init(Encoder* e, ErlNifEnv* env, ERL_NIF_TERM opts, ErlNifBinary* bin)
while(enif_get_list_cell(env, opts, &val, &opts)) {
if(enif_compare(val, e->atoms->atom_uescape) == 0) {
e->uescape = 1;
} else if(enif_compare(val, e->atoms->atom_pretty) == 0) {
e->pretty = 1;
} else {
return 0;
}
@ -376,42 +386,83 @@ enc_char(Encoder* e, char c)
return 1;
}
static int
enc_shift(Encoder* e) {
// Don't call this function directly.
// Use macro MAYBE_PRETTY_INDENT(e).
// Compile-time initialized array of indent strings.
// Every string starts with its length.
static char* shifts[] = {
"\x01\n",
"\x03\n ",
"\x05\n ",
"\x07\n ",
"\x09\n ",
"\x0b\n ",
"\x0d\n ",
"\x0f\n "
};
int cnt = COUNT_OF(shifts) - 1;
char *shift = shifts[ MIN(e->shiftcnt, cnt) ];
if (!enc_literal(e, shift + 1, *shift)) {
return 0;
}
for (; cnt < e->shiftcnt; ++cnt) {
if (!enc_literal(e, " ", 2)) {
return 0;
}
}
return 1;
}
static inline int
enc_start_object(Encoder* e)
{
e->count++;
return enc_char(e, '{');
e->shiftcnt++;
return enc_char(e, '{') && MAYBE_PRETTY_INDENT(e);
}
static inline int
enc_end_object(Encoder* e)
{
return enc_char(e, '}');
if (!e->shiftcnt--)
return 0;
return MAYBE_PRETTY_INDENT(e) && enc_char(e, '}');
}
static inline int
enc_start_array(Encoder* e)
{
e->count++;
return enc_char(e, '[');
e->shiftcnt++;
return enc_char(e, '[') && MAYBE_PRETTY_INDENT(e);
}
static inline int
enc_end_array(Encoder* e)
{
return enc_char(e, ']');
if (!e->shiftcnt--)
return 0;
return MAYBE_PRETTY_INDENT(e) && enc_char(e, ']');
}
static inline int
enc_colon(Encoder* e)
{
return enc_char(e, ':');
if (!e->pretty)
return enc_char(e, ':');
return enc_literal(e, " : ", 3);
}
static inline int
enc_comma(Encoder* e)
{
return enc_char(e, ',');
return enc_char(e, ',') && MAYBE_PRETTY_INDENT(e);
}
ERL_NIF_TERM

+ 1
- 0
c_src/jiffy.c Ver fichero

@ -21,6 +21,7 @@ load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
st->atom_bigdbl = make_atom(env, "bigdbl");
st->atom_partial = make_atom(env, "partial");
st->atom_uescape = make_atom(env, "uescape");
st->atom_pretty = make_atom(env, "pretty");
// Markers used in encoding
st->ref_object = make_atom(env, "$object_ref$");

+ 1
- 0
c_src/jiffy.h Ver fichero

@ -17,6 +17,7 @@ typedef struct {
ERL_NIF_TERM atom_bigdbl;
ERL_NIF_TERM atom_partial;
ERL_NIF_TERM atom_uescape;
ERL_NIF_TERM atom_pretty;
ERL_NIF_TERM ref_object;
ERL_NIF_TERM ref_array;

+ 7
- 0
test/jiffy_tests.erl Ver fichero

@ -24,6 +24,13 @@ prop_encode_decode() ->
end
).
prop_encode_decode_pretty() ->
?FORALL(Data, json(),
begin
Data == jiffy:decode(jiffy:encode(Data, [pretty]))
end
).
prop_encode_not_crash() ->
?FORALL(Data, any(), begin catch jiffy:encode(Data), true end).

Cargando…
Cancelar
Guardar