@ -150,7 +150,8 @@ dec_error(Decoder* d, const char* atom)
char
char
dec_curr ( Decoder * d )
dec_curr ( Decoder * d )
{
{
return d - > st_data [ d - > st_top - 1 ] ;
assert ( d - > st_top > 0 ) ;
return d - > st_data [ d - > st_top - 1 ] ;
}
}
int
int
@ -178,12 +179,25 @@ dec_push(Decoder* d, char val)
d - > st_data [ d - > st_top + + ] = val ;
d - > st_data [ d - > st_top + + ] = val ;
}
}
char
dec_pop ( Decoder * d ) {
char current = st_invalid ;
if ( d - > st_top > 0 ) {
current = d - > st_data [ d - > st_top - 1 ] ;
d - > st_data [ d - > st_top - 1 ] = st_invalid ;
d - > st_top - - ;
}
return current ;
}
void
void
dec_pop ( Decoder * d , char val )
dec_pop_assert ( Decoder * d , char val )
{
{
assert ( d - > st_data [ d - > st_top - 1 ] = = val & & " popped invalid state. " ) ;
d - > st_data [ d - > st_top - 1 ] = st_invalid ;
d - > st_top - - ;
char current = dec_pop ( d ) ;
assert ( current = = val & & " popped invalid state. " ) ;
( void ) current ;
}
}
int
int
@ -777,7 +791,7 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
goto done ;
goto done ;
}
}
val = d - > null_term ;
val = d - > null_term ;
dec_pop ( d , st_value ) ;
dec_pop_assert ( d , st_value ) ;
d - > i + = 4 ;
d - > i + = 4 ;
break ;
break ;
case ' t ' :
case ' t ' :
@ -790,7 +804,7 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
goto done ;
goto done ;
}
}
val = d - > atoms - > atom_true ;
val = d - > atoms - > atom_true ;
dec_pop ( d , st_value ) ;
dec_pop_assert ( d , st_value ) ;
d - > i + = 4 ;
d - > i + = 4 ;
break ;
break ;
case ' f ' :
case ' f ' :
@ -803,7 +817,7 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
goto done ;
goto done ;
}
}
val = d - > atoms - > atom_false ;
val = d - > atoms - > atom_false ;
dec_pop ( d , st_value ) ;
dec_pop_assert ( d , st_value ) ;
d - > i + = 5 ;
d - > i + = 5 ;
break ;
break ;
case ' \" ' :
case ' \" ' :
@ -811,7 +825,7 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ret = dec_error ( d , " invalid_string " ) ;
ret = dec_error ( d , " invalid_string " ) ;
goto done ;
goto done ;
}
}
dec_pop ( d , st_value ) ;
dec_pop_assert ( d , st_value ) ;
break ;
break ;
case ' - ' :
case ' - ' :
case ' 0 ' :
case ' 0 ' :
@ -828,7 +842,7 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ret = dec_error ( d , " invalid_number " ) ;
ret = dec_error ( d , " invalid_number " ) ;
goto done ;
goto done ;
}
}
dec_pop ( d , st_value ) ;
dec_pop_assert ( d , st_value ) ;
break ;
break ;
case ' { ' :
case ' { ' :
dec_push ( d , st_object ) ;
dec_push ( d , st_object ) ;
@ -849,13 +863,12 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ret = dec_error ( d , " invalid_json " ) ;
ret = dec_error ( d , " invalid_json " ) ;
goto done ;
goto done ;
}
}
dec_pop ( d , st_value ) ;
if ( dec_curr ( d ) ! = st_array ) {
dec_pop_assert ( d , st_value ) ;
if ( dec_pop ( d ) ! = st_array ) {
ret = dec_error ( d , " invalid_json " ) ;
ret = dec_error ( d , " invalid_json " ) ;
goto done ;
goto done ;
}
}
dec_pop ( d , st_array ) ;
dec_pop ( d , st_value ) ;
dec_pop_assert ( d , st_value ) ;
val = curr ; / / curr is [ ]
val = curr ; / / curr is [ ]
if ( ! enif_get_list_cell ( env , objs , & curr , & objs ) ) {
if ( ! enif_get_list_cell ( env , objs , & curr , & objs ) ) {
ret = dec_error ( d , " internal_error " ) ;
ret = dec_error ( d , " internal_error " ) ;
@ -888,7 +901,7 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ret = dec_error ( d , " invalid_string " ) ;
ret = dec_error ( d , " invalid_string " ) ;
goto done ;
goto done ;
}
}
dec_pop ( d , st_key ) ;
dec_pop_assert ( d , st_key ) ;
dec_push ( d , st_colon ) ;
dec_push ( d , st_colon ) ;
curr = enif_make_list_cell ( env , val , curr ) ;
curr = enif_make_list_cell ( env , val , curr ) ;
break ;
break ;
@ -897,9 +910,9 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ret = dec_error ( d , " invalid_json " ) ;
ret = dec_error ( d , " invalid_json " ) ;
goto done ;
goto done ;
}
}
dec_pop ( d , st_key ) ;
dec_pop ( d , st_object ) ;
dec_pop ( d , st_value ) ;
dec_pop_assert ( d , st_key ) ;
dec_pop_assert ( d , st_object ) ;
dec_pop_assert ( d , st_value ) ;
val = make_empty_object ( env , d - > return_maps ) ;
val = make_empty_object ( env , d - > return_maps ) ;
if ( ! enif_get_list_cell ( env , objs , & curr , & objs ) ) {
if ( ! enif_get_list_cell ( env , objs , & curr , & objs ) ) {
ret = dec_error ( d , " internal_error " ) ;
ret = dec_error ( d , " internal_error " ) ;
@ -928,7 +941,7 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
d - > i + + ;
d - > i + + ;
break ;
break ;
case ' : ' :
case ' : ' :
dec_pop ( d , st_colon ) ;
dec_pop_assert ( d , st_colon ) ;
dec_push ( d , st_value ) ;
dec_push ( d , st_value ) ;
d - > i + + ;
d - > i + + ;
break ;
break ;
@ -947,7 +960,7 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
d - > i + + ;
d - > i + + ;
break ;
break ;
case ' , ' :
case ' , ' :
dec_pop ( d , st_comma ) ;
dec_pop_assert ( d , st_comma ) ;
switch ( dec_curr ( d ) ) {
switch ( dec_curr ( d ) ) {
case st_object :
case st_object :
dec_push ( d , st_key ) ;
dec_push ( d , st_key ) ;
@ -962,13 +975,12 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
d - > i + + ;
d - > i + + ;
break ;
break ;
case ' } ' :
case ' } ' :
dec_pop ( d , st_comma ) ;
if ( dec_curr ( d ) ! = st_object ) {
dec_pop_assert ( d , st_comma ) ;
if ( dec_pop ( d ) ! = st_object ) {
ret = dec_error ( d , " invalid_json " ) ;
ret = dec_error ( d , " invalid_json " ) ;
goto done ;
goto done ;
}
}
dec_pop ( d , st_object ) ;
dec_pop ( d , st_value ) ;
dec_pop_assert ( d , st_value ) ;
if ( ! make_object ( env , curr , & val ,
if ( ! make_object ( env , curr , & val ,
d - > return_maps , d - > dedupe_keys ) ) {
d - > return_maps , d - > dedupe_keys ) ) {
ret = dec_error ( d , " internal_object_error " ) ;
ret = dec_error ( d , " internal_object_error " ) ;
@ -987,13 +999,12 @@ decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
d - > i + + ;
d - > i + + ;
break ;
break ;
case ' ] ' :
case ' ] ' :
dec_pop ( d , st_comma ) ;
if ( dec_curr ( d ) ! = st_array ) {
dec_pop_assert ( d , st_comma ) ;
if ( dec_pop ( d ) ! = st_array ) {
ret = dec_error ( d , " invalid_json " ) ;
ret = dec_error ( d , " invalid_json " ) ;
goto done ;
goto done ;
}
}
dec_pop ( d , st_array ) ;
dec_pop ( d , st_value ) ;
dec_pop_assert ( d , st_value ) ;
val = make_array ( env , curr ) ;
val = make_array ( env , curr ) ;
if ( ! enif_get_list_cell ( env , objs , & curr , & objs ) ) {
if ( ! enif_get_list_cell ( env , objs , & curr , & objs ) ) {
ret = dec_error ( d , " internal_error " ) ;
ret = dec_error ( d , " internal_error " ) ;
@ -1042,7 +1053,7 @@ decode_done:
goto done ;
goto done ;
}
}
if ( dec_curr ( d ) ! = st_done ) {
if ( dec_pop ( 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 ) {
ret = enif_make_tuple2 ( env , d - > atoms - > atom_partial , val ) ;
ret = enif_make_tuple2 ( env , d - > atoms - > atom_partial , val ) ;