@ -49,9 +49,10 @@ typedef struct {
ERL_NIF_TERM arg ;
ERL_NIF_TERM arg ;
ErlNifBinary bin ;
ErlNifBinary bin ;
size_t bytes_per_iter ;
size_t bytes_per_red ;
int is_partial ;
int is_partial ;
int return_maps ;
int return_maps ;
int return_trailer ;
ERL_NIF_TERM null_term ;
ERL_NIF_TERM null_term ;
char * p ;
char * p ;
@ -77,9 +78,10 @@ dec_new(ErlNifEnv* env)
d - > atoms = st ;
d - > atoms = st ;
d - > bytes_per_iter = DEFAULT_BYTES_PER_ITER ;
d - > bytes_per_red = DEFAULT_BYTES_PER_REDUCTION ;
d - > is_partial = 0 ;
d - > is_partial = 0 ;
d - > return_maps = 0 ;
d - > return_maps = 0 ;
d - > return_trailer = 0 ;
d - > null_term = d - > atoms - > atom_null ;
d - > null_term = d - > atoms - > atom_null ;
d - > p = NULL ;
d - > p = NULL ;
@ -702,7 +704,9 @@ decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
}
}
while ( enif_get_list_cell ( env , opts , & val , & opts ) ) {
while ( enif_get_list_cell ( env , opts , & val , & opts ) ) {
if ( get_bytes_per_iter ( env , val , & ( d - > bytes_per_iter ) ) ) {
if ( get_bytes_per_iter ( env , val , & ( d - > bytes_per_red ) ) ) {
continue ;
} else if ( get_bytes_per_red ( env , val , & ( d - > bytes_per_red ) ) ) {
continue ;
continue ;
} else if ( enif_compare ( val , d - > atoms - > atom_return_maps ) = = 0 ) {
} else if ( enif_compare ( val , d - > atoms - > atom_return_maps ) = = 0 ) {
# if MAP_TYPE_PRESENT
# if MAP_TYPE_PRESENT
@ -710,6 +714,8 @@ decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
# else
# else
return enif_make_badarg ( env ) ;
return enif_make_badarg ( env ) ;
# endif
# endif
} else if ( enif_compare ( val , d - > atoms - > atom_return_trailer ) = = 0 ) {
d - > return_trailer = 1 ;
} else if ( enif_compare ( val , d - > atoms - > atom_use_nil ) = = 0 ) {
} else if ( enif_compare ( val , d - > atoms - > atom_use_nil ) = = 0 ) {
d - > null_term = d - > atoms - > atom_nil ;
d - > null_term = d - > atoms - > atom_nil ;
} else if ( get_null_term ( env , val , & ( d - > null_term ) ) ) {
} else if ( get_null_term ( env , val , & ( d - > null_term ) ) ) {
@ -733,8 +739,9 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ERL_NIF_TERM objs ;
ERL_NIF_TERM objs ;
ERL_NIF_TERM curr ;
ERL_NIF_TERM curr ;
ERL_NIF_TERM val = argv [ 2 ] ;
ERL_NIF_TERM val = argv [ 2 ] ;
ERL_NIF_TERM trailer ;
ERL_NIF_TERM ret ;
ERL_NIF_TERM ret ;
size_t start ;
size_t bytes_read = 0 ;
if ( argc ! = 5 ) {
if ( argc ! = 5 ) {
return enif_make_badarg ( env ) ;
return enif_make_badarg ( env ) ;
@ -753,11 +760,10 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
curr = argv [ 4 ] ;
curr = argv [ 4 ] ;
/ / fprintf ( stderr , " Parsing: \r \n " ) ;
/ / fprintf ( stderr , " Parsing: \r \n " ) ;
start = d - > i ;
while ( d - > i < bin . size ) {
while ( d - > i < bin . size ) {
/ / fprintf ( stderr , " state: %d \r \n " , dec_curr ( d ) ) ;
/ / fprintf ( stderr , " state: %d \r \n " , dec_curr ( d ) ) ;
if ( should_yield ( d - > i - start , d - > bytes_per_iter ) ) {
consume_timeslice ( env , d - > i - start , d - > bytes_per_iter ) ;
if ( should_yield ( env , & bytes_read , d - > bytes_per_red ) ) {
return enif_make_tuple5 (
return enif_make_tuple5 (
env ,
env ,
st - > atom_iter ,
st - > atom_iter ,
@ -767,6 +773,9 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
curr
curr
) ;
) ;
}
}
bytes_read + = 1 ;
switch ( dec_curr ( d ) ) {
switch ( dec_curr ( d ) ) {
case st_value :
case st_value :
switch ( d - > p [ d - > i ] ) {
switch ( d - > p [ d - > i ] ) {
@ -1030,8 +1039,7 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
d - > i + + ;
d - > i + + ;
break ;
break ;
default :
default :
ret = dec_error ( d , " invalid_trailing_data " ) ;
goto done ;
goto decode_done ;
}
}
break ;
break ;
@ -1041,6 +1049,16 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
}
}
}
}
decode_done :
if ( d - > i < bin . size & & d - > return_trailer ) {
trailer = enif_make_sub_binary ( env , argv [ 0 ] , d - > i , bin . size - d - > i ) ;
val = enif_make_tuple3 ( env , d - > atoms - > atom_has_trailer , val , trailer ) ;
} else if ( d - > i < bin . size ) {
ret = dec_error ( d , " invalid_trailing_data " ) ;
goto done ;
}
if ( dec_curr ( d ) ! = st_done ) {
if ( dec_curr ( d ) ! = st_done ) {
ret = dec_error ( d , " truncated_json " ) ;
ret = dec_error ( d , " truncated_json " ) ;
} else if ( d - > is_partial ) {
} else if ( d - > is_partial ) {
@ -1050,6 +1068,5 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
}
}
done :
done :
consume_timeslice ( env , d - > i - start , d - > bytes_per_iter ) ;
return ret ;
return ret ;
}
}