@ -1,8 +1,8 @@
/*
/*
SPDX - License - Identifier : MIT
SPDX - License - Identifier : MIT
Parson 1.0 .2 ( http : //kgabis.github.com/parson/ )
Parson 1.1 .0 ( http : //kgabis.github.com/parson/ )
Copyright ( c ) 2012 - 2019 Krzysztof Gabis
Copyright ( c ) 2012 - 2020 Krzysztof Gabis
Permission is hereby granted , free of charge , to any person obtaining a copy
Permission is hereby granted , free of charge , to any person obtaining a copy
of this software and associated documentation files ( the " Software " ) , to deal
of this software and associated documentation files ( the " Software " ) , to deal
@ -68,9 +68,14 @@ static int parson_escape_slashes = 1;
# define IS_CONT(b) (((unsigned char)(b) & 0xC0) == 0x80) /* is utf-8 continuation byte */
# define IS_CONT(b) (((unsigned char)(b) & 0xC0) == 0x80) /* is utf-8 continuation byte */
typedef struct json_string {
char * chars ;
size_t length ;
} JSON_String ;
/* Type definitions */
/* Type definitions */
typedef union json_value_value {
typedef union json_value_value {
char * string ;
JSON_String string ;
double number ;
double number ;
JSON_Object * object ;
JSON_Object * object ;
JSON_Array * array ;
JSON_Array * array ;
@ -128,13 +133,14 @@ static JSON_Status json_array_resize(JSON_Array *array, size_t new_capacity);
static void json_array_free ( JSON_Array * array ) ;
static void json_array_free ( JSON_Array * array ) ;
/* JSON Value */
/* JSON Value */
static JSON_Value * json_value_init_string_no_copy ( char * string ) ;
static JSON_Value * json_value_init_string_no_copy ( char * string , size_t length ) ;
static const JSON_String * json_value_get_string_desc ( const JSON_Value * value ) ;
/* Parser */
/* Parser */
static JSON_Status skip_quotes ( const char * * string ) ;
static JSON_Status skip_quotes ( const char * * string ) ;
static int parse_utf16 ( const char * * unprocessed , char * * processed ) ;
static int parse_utf16 ( const char * * unprocessed , char * * processed ) ;
static char * process_string ( const char * input , size_t len ) ;
static char * process_string ( const char * input , size_t input_len , size_t * output_ len) ;
static char * get_quoted_string ( const char * * string ) ;
static char * get_quoted_string ( const char * * string , size_t * output_string_len ) ;
static JSON_Value * parse_object_value ( const char * * string , size_t nesting ) ;
static JSON_Value * parse_object_value ( const char * * string , size_t nesting ) ;
static JSON_Value * parse_array_value ( const char * * string , size_t nesting ) ;
static JSON_Value * parse_array_value ( const char * * string , size_t nesting ) ;
static JSON_Value * parse_string_value ( const char * * string ) ;
static JSON_Value * parse_string_value ( const char * * string ) ;
@ -145,12 +151,13 @@ static JSON_Value * parse_value(const char **string, size_t nesting);
/* Serialization */
/* Serialization */
static int json_serialize_to_buffer_r ( const JSON_Value * value , char * buf , int level , int is_pretty , char * num_buf ) ;
static int json_serialize_to_buffer_r ( const JSON_Value * value , char * buf , int level , int is_pretty , char * num_buf ) ;
static int json_serialize_string ( const char * string , char * buf ) ;
static int json_serialize_string ( const char * string , size_t len , char * buf ) ;
static int append_indent ( char * buf , int level ) ;
static int append_indent ( char * buf , int level ) ;
static int append_string ( char * buf , const char * string ) ;
static int append_string ( char * buf , const char * string ) ;
/* Various */
/* Various */
static char * parson_strndup ( const char * string , size_t n ) {
static char * parson_strndup ( const char * string , size_t n ) {
/* We expect the caller has validated that 'n' fits within the input buffer. */
char * output_string = ( char * ) parson_malloc ( n + 1 ) ;
char * output_string = ( char * ) parson_malloc ( n + 1 ) ;
if ( ! output_string ) {
if ( ! output_string ) {
return NULL ;
return NULL ;
@ -536,14 +543,15 @@ static void json_array_free(JSON_Array *array) {
}
}
/* JSON Value */
/* JSON Value */
static JSON_Value * json_value_init_string_no_copy ( char * string ) {
static JSON_Value * json_value_init_string_no_copy ( char * string , size_t length ) {
JSON_Value * new_value = ( JSON_Value * ) parson_malloc ( sizeof ( JSON_Value ) ) ;
JSON_Value * new_value = ( JSON_Value * ) parson_malloc ( sizeof ( JSON_Value ) ) ;
if ( ! new_value ) {
if ( ! new_value ) {
return NULL ;
return NULL ;
}
}
new_value - > parent = NULL ;
new_value - > parent = NULL ;
new_value - > type = JSONString ;
new_value - > type = JSONString ;
new_value - > value . string = string ;
new_value - > value . string . chars = string ;
new_value - > value . string . length = length ;
return new_value ;
return new_value ;
}
}
@ -617,9 +625,9 @@ static int parse_utf16(const char **unprocessed, char **processed) {
/* Copies and processes passed string up to supplied length.
/* Copies and processes passed string up to supplied length.
Example : " \u006C orem ipsum " - > lorem ipsum */
Example : " \u006C orem ipsum " - > lorem ipsum */
static char * process_string ( const char * input , size_t len ) {
static char * process_string ( const char * input , size_t input_len , size_t * output_ len) {
const char * input_ptr = input ;
const char * input_ptr = input ;
size_t initial_size = ( len + 1 ) * sizeof ( char ) ;
size_t initial_size = ( input_ len + 1 ) * sizeof ( char ) ;
size_t final_size = 0 ;
size_t final_size = 0 ;
char * output = NULL , * output_ptr = NULL , * resized_output = NULL ;
char * output = NULL , * output_ptr = NULL , * resized_output = NULL ;
output = ( char * ) parson_malloc ( initial_size ) ;
output = ( char * ) parson_malloc ( initial_size ) ;
@ -627,7 +635,7 @@ static char* process_string(const char *input, size_t len) {
goto error ;
goto error ;
}
}
output_ptr = output ;
output_ptr = output ;
while ( ( * input_ptr ! = ' \0 ' ) & & ( size_t ) ( input_ptr - input ) < len ) {
while ( ( * input_ptr ! = ' \0 ' ) & & ( size_t ) ( input_ptr - input ) < input_ len) {
if ( * input_ptr = = ' \\ ' ) {
if ( * input_ptr = = ' \\ ' ) {
input_ptr + + ;
input_ptr + + ;
switch ( * input_ptr ) {
switch ( * input_ptr ) {
@ -664,6 +672,7 @@ static char* process_string(const char *input, size_t len) {
goto error ;
goto error ;
}
}
memcpy ( resized_output , output , final_size ) ;
memcpy ( resized_output , output , final_size ) ;
* output_len = final_size - 1 ;
parson_free ( output ) ;
parson_free ( output ) ;
return resized_output ;
return resized_output ;
error :
error :
@ -673,15 +682,15 @@ error:
/* Return processed contents of a string between quotes and
/* Return processed contents of a string between quotes and
skips passed argument to a matching quote . */
skips passed argument to a matching quote . */
static char * get_quoted_string ( const char * * string ) {
static char * get_quoted_string ( const char * * string , size_t * output_string_len ) {
const char * string_start = * string ;
const char * string_start = * string ;
size_t string_len = 0 ;
size_t input_ string_len = 0 ;
JSON_Status status = skip_quotes ( string ) ;
JSON_Status status = skip_quotes ( string ) ;
if ( status ! = JSONSuccess ) {
if ( status ! = JSONSuccess ) {
return NULL ;
return NULL ;
}
}
string_len = * string - string_start - 2 ; /* length without quotes */
input_ string_len = * string - string_start - 2 ; /* length without quotes */
return process_string ( string_start + 1 , string_len ) ;
return process_string ( string_start + 1 , input_string_len , output_ string_len) ;
}
}
static JSON_Value * parse_value ( const char * * string , size_t nesting ) {
static JSON_Value * parse_value ( const char * * string , size_t nesting ) {
@ -729,8 +738,10 @@ static JSON_Value * parse_object_value(const char **string, size_t nesting) {
return output_value ;
return output_value ;
}
}
while ( * * string ! = ' \0 ' ) {
while ( * * string ! = ' \0 ' ) {
new_key = get_quoted_string ( string ) ;
size_t key_len = 0 ;
if ( new_key = = NULL ) {
new_key = get_quoted_string ( string , & key_len ) ;
/* We do not support key names with embedded \0 chars */
if ( new_key = = NULL | | key_len ! = strlen ( new_key ) ) {
json_value_free ( output_value ) ;
json_value_free ( output_value ) ;
return NULL ;
return NULL ;
}
}
@ -819,11 +830,12 @@ static JSON_Value * parse_array_value(const char **string, size_t nesting) {
static JSON_Value * parse_string_value ( const char * * string ) {
static JSON_Value * parse_string_value ( const char * * string ) {
JSON_Value * value = NULL ;
JSON_Value * value = NULL ;
char * new_string = get_quoted_string ( string ) ;
size_t new_string_len = 0 ;
char * new_string = get_quoted_string ( string , & new_string_len ) ;
if ( new_string = = NULL ) {
if ( new_string = = NULL ) {
return NULL ;
return NULL ;
}
}
value = json_value_init_string_no_copy ( new_string ) ;
value = json_value_init_string_no_copy ( new_string , new_string_len ) ;
if ( value = = NULL ) {
if ( value = = NULL ) {
parson_free ( new_string ) ;
parson_free ( new_string ) ;
return NULL ;
return NULL ;
@ -885,6 +897,7 @@ static int json_serialize_to_buffer_r(const JSON_Value *value, char *buf, int le
size_t i = 0 , count = 0 ;
size_t i = 0 , count = 0 ;
double num = 0.0 ;
double num = 0.0 ;
int written = - 1 , written_total = 0 ;
int written = - 1 , written_total = 0 ;
size_t len = 0 ;
switch ( json_value_get_type ( value ) ) {
switch ( json_value_get_type ( value ) ) {
case JSONArray :
case JSONArray :
@ -934,7 +947,8 @@ static int json_serialize_to_buffer_r(const JSON_Value *value, char *buf, int le
if ( is_pretty ) {
if ( is_pretty ) {
APPEND_INDENT ( level + 1 ) ;
APPEND_INDENT ( level + 1 ) ;
}
}
written = json_serialize_string ( key , buf ) ;
/* We do not support key names with embedded \0 chars */
written = json_serialize_string ( key , strlen ( key ) , buf ) ;
if ( written < 0 ) {
if ( written < 0 ) {
return - 1 ;
return - 1 ;
}
}
@ -972,7 +986,8 @@ static int json_serialize_to_buffer_r(const JSON_Value *value, char *buf, int le
if ( string = = NULL ) {
if ( string = = NULL ) {
return - 1 ;
return - 1 ;
}
}
written = json_serialize_string ( string , buf ) ;
len = json_value_get_string_len ( value ) ;
written = json_serialize_string ( string , len , buf ) ;
if ( written < 0 ) {
if ( written < 0 ) {
return - 1 ;
return - 1 ;
}
}
@ -1012,8 +1027,8 @@ static int json_serialize_to_buffer_r(const JSON_Value *value, char *buf, int le
}
}
}
}
static int json_serialize_string ( const char * string , char * buf ) {
static int json_serialize_string ( const char * string , size_t len , char * buf ) {
size_t i = 0 , len = strlen ( string ) ;
size_t i = 0 ;
char c = ' \0 ' ;
char c = ' \0 ' ;
int written = - 1 , written_total = 0 ;
int written = - 1 , written_total = 0 ;
APPEND_STRING ( " \" " ) ;
APPEND_STRING ( " \" " ) ;
@ -1159,6 +1174,10 @@ const char * json_object_get_string(const JSON_Object *object, const char *name)
return json_value_get_string ( json_object_get_value ( object , name ) ) ;
return json_value_get_string ( json_object_get_value ( object , name ) ) ;
}
}
size_t json_object_get_string_len ( const JSON_Object * object , const char * name ) {
return json_value_get_string_len ( json_object_get_value ( object , name ) ) ;
}
double json_object_get_number ( const JSON_Object * object , const char * name ) {
double json_object_get_number ( const JSON_Object * object , const char * name ) {
return json_value_get_number ( json_object_get_value ( object , name ) ) ;
return json_value_get_number ( json_object_get_value ( object , name ) ) ;
}
}
@ -1188,6 +1207,10 @@ const char * json_object_dotget_string(const JSON_Object *object, const char *na
return json_value_get_string ( json_object_dotget_value ( object , name ) ) ;
return json_value_get_string ( json_object_dotget_value ( object , name ) ) ;
}
}
size_t json_object_dotget_string_len ( const JSON_Object * object , const char * name ) {
return json_value_get_string_len ( json_object_dotget_value ( object , name ) ) ;
}
double json_object_dotget_number ( const JSON_Object * object , const char * name ) {
double json_object_dotget_number ( const JSON_Object * object , const char * name ) {
return json_value_get_number ( json_object_dotget_value ( object , name ) ) ;
return json_value_get_number ( json_object_dotget_value ( object , name ) ) ;
}
}
@ -1256,6 +1279,10 @@ const char * json_array_get_string(const JSON_Array *array, size_t index) {
return json_value_get_string ( json_array_get_value ( array , index ) ) ;
return json_value_get_string ( json_array_get_value ( array , index ) ) ;
}
}
size_t json_array_get_string_len ( const JSON_Array * array , size_t index ) {
return json_value_get_string_len ( json_array_get_value ( array , index ) ) ;
}
double json_array_get_number ( const JSON_Array * array , size_t index ) {
double json_array_get_number ( const JSON_Array * array , size_t index ) {
return json_value_get_number ( json_array_get_value ( array , index ) ) ;
return json_value_get_number ( json_array_get_value ( array , index ) ) ;
}
}
@ -1293,8 +1320,18 @@ JSON_Array * json_value_get_array(const JSON_Value *value) {
return json_value_get_type ( value ) = = JSONArray ? value - > value . array : NULL ;
return json_value_get_type ( value ) = = JSONArray ? value - > value . array : NULL ;
}
}
static const JSON_String * json_value_get_string_desc ( const JSON_Value * value ) {
return json_value_get_type ( value ) = = JSONString ? & value - > value . string : NULL ;
}
const char * json_value_get_string ( const JSON_Value * value ) {
const char * json_value_get_string ( const JSON_Value * value ) {
return json_value_get_type ( value ) = = JSONString ? value - > value . string : NULL ;
const JSON_String * str = json_value_get_string_desc ( value ) ;
return str ? str - > chars : NULL ;
}
size_t json_value_get_string_len ( const JSON_Value * value ) {
const JSON_String * str = json_value_get_string_desc ( value ) ;
return str ? str - > length : 0 ;
}
}
double json_value_get_number ( const JSON_Value * value ) {
double json_value_get_number ( const JSON_Value * value ) {
@ -1315,7 +1352,7 @@ void json_value_free(JSON_Value *value) {
json_object_free ( value - > value . object ) ;
json_object_free ( value - > value . object ) ;
break ;
break ;
case JSONString :
case JSONString :
parson_free ( value - > value . string ) ;
parson_free ( value - > value . string . chars ) ;
break ;
break ;
case JSONArray :
case JSONArray :
json_array_free ( value - > value . array ) ;
json_array_free ( value - > value . array ) ;
@ -1357,21 +1394,26 @@ JSON_Value * json_value_init_array(void) {
}
}
JSON_Value * json_value_init_string ( const char * string ) {
JSON_Value * json_value_init_string ( const char * string ) {
if ( string = = NULL ) {
return NULL ;
}
return json_value_init_string_with_len ( string , strlen ( string ) ) ;
}
JSON_Value * json_value_init_string_with_len ( const char * string , size_t length ) {
char * copy = NULL ;
char * copy = NULL ;
JSON_Value * value ;
JSON_Value * value ;
size_t string_len = 0 ;
if ( string = = NULL ) {
if ( string = = NULL ) {
return NULL ;
return NULL ;
}
}
string_len = strlen ( string ) ;
if ( ! is_valid_utf8 ( string , length ) ) {
if ( ! is_valid_utf8 ( string , string_len ) ) {
return NULL ;
return NULL ;
}
}
copy = parson_strndup ( string , string_ len) ;
copy = parson_strndup ( string , length ) ;
if ( copy = = NULL ) {
if ( copy = = NULL ) {
return NULL ;
return NULL ;
}
}
value = json_value_init_string_no_copy ( copy ) ;
value = json_value_init_string_no_copy ( copy , length ) ;
if ( value = = NULL ) {
if ( value = = NULL ) {
parson_free ( copy ) ;
parson_free ( copy ) ;
}
}
@ -1417,7 +1459,8 @@ JSON_Value * json_value_init_null(void) {
JSON_Value * json_value_deep_copy ( const JSON_Value * value ) {
JSON_Value * json_value_deep_copy ( const JSON_Value * value ) {
size_t i = 0 ;
size_t i = 0 ;
JSON_Value * return_value = NULL , * temp_value_copy = NULL , * temp_value = NULL ;
JSON_Value * return_value = NULL , * temp_value_copy = NULL , * temp_value = NULL ;
const char * temp_string = NULL , * temp_key = NULL ;
const JSON_String * temp_string = NULL ;
const char * temp_key = NULL ;
char * temp_string_copy = NULL ;
char * temp_string_copy = NULL ;
JSON_Array * temp_array = NULL , * temp_array_copy = NULL ;
JSON_Array * temp_array = NULL , * temp_array_copy = NULL ;
JSON_Object * temp_object = NULL , * temp_object_copy = NULL ;
JSON_Object * temp_object = NULL , * temp_object_copy = NULL ;
@ -1471,15 +1514,15 @@ JSON_Value * json_value_deep_copy(const JSON_Value *value) {
case JSONNumber :
case JSONNumber :
return json_value_init_number ( json_value_get_number ( value ) ) ;
return json_value_init_number ( json_value_get_number ( value ) ) ;
case JSONString :
case JSONString :
temp_string = json_value_get_string ( value ) ;
temp_string = json_value_get_string_desc ( value ) ;
if ( temp_string = = NULL ) {
if ( temp_string = = NULL ) {
return NULL ;
return NULL ;
}
}
temp_string_copy = parson_strdup ( temp_string ) ;
temp_string_copy = parson_strn dup ( temp_string - > chars , temp_string - > length ) ;
if ( temp_string_copy = = NULL ) {
if ( temp_string_copy = = NULL ) {
return NULL ;
return NULL ;
}
}
return_value = json_value_init_string_no_copy ( temp_string_copy ) ;
return_value = json_value_init_string_no_copy ( temp_string_copy , temp_string - > length ) ;
if ( return_value = = NULL ) {
if ( return_value = = NULL ) {
parson_free ( temp_string_copy ) ;
parson_free ( temp_string_copy ) ;
}
}
@ -1651,6 +1694,18 @@ JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char* s
return JSONSuccess ;
return JSONSuccess ;
}
}
JSON_Status json_array_replace_string_with_len ( JSON_Array * array , size_t i , const char * string , size_t len ) {
JSON_Value * value = json_value_init_string_with_len ( string , len ) ;
if ( value = = NULL ) {
return JSONFailure ;
}
if ( json_array_replace_value ( array , i , value ) = = JSONFailure ) {
json_value_free ( value ) ;
return JSONFailure ;
}
return JSONSuccess ;
}
JSON_Status json_array_replace_number ( JSON_Array * array , size_t i , double number ) {
JSON_Status json_array_replace_number ( JSON_Array * array , size_t i , double number ) {
JSON_Value * value = json_value_init_number ( number ) ;
JSON_Value * value = json_value_init_number ( number ) ;
if ( value = = NULL ) {
if ( value = = NULL ) {
@ -1718,6 +1773,18 @@ JSON_Status json_array_append_string(JSON_Array *array, const char *string) {
return JSONSuccess ;
return JSONSuccess ;
}
}
JSON_Status json_array_append_string_with_len ( JSON_Array * array , const char * string , size_t len ) {
JSON_Value * value = json_value_init_string_with_len ( string , len ) ;
if ( value = = NULL ) {
return JSONFailure ;
}
if ( json_array_append_value ( array , value ) = = JSONFailure ) {
json_value_free ( value ) ;
return JSONFailure ;
}
return JSONSuccess ;
}
JSON_Status json_array_append_number ( JSON_Array * array , double number ) {
JSON_Status json_array_append_number ( JSON_Array * array , double number ) {
JSON_Value * value = json_value_init_number ( number ) ;
JSON_Value * value = json_value_init_number ( number ) ;
if ( value = = NULL ) {
if ( value = = NULL ) {
@ -1784,6 +1851,15 @@ JSON_Status json_object_set_string(JSON_Object *object, const char *name, const
return status ;
return status ;
}
}
JSON_Status json_object_set_string_with_len ( JSON_Object * object , const char * name , const char * string , size_t len ) {
JSON_Value * value = json_value_init_string_with_len ( string , len ) ;
JSON_Status status = json_object_set_value ( object , name , value ) ;
if ( status = = JSONFailure ) {
json_value_free ( value ) ;
}
return status ;
}
JSON_Status json_object_set_number ( JSON_Object * object , const char * name , double number ) {
JSON_Status json_object_set_number ( JSON_Object * object , const char * name , double number ) {
JSON_Value * value = json_value_init_number ( number ) ;
JSON_Value * value = json_value_init_number ( number ) ;
JSON_Status status = json_object_set_value ( object , name , value ) ;
JSON_Status status = json_object_set_value ( object , name , value ) ;
@ -1865,6 +1941,18 @@ JSON_Status json_object_dotset_string(JSON_Object *object, const char *name, con
return JSONSuccess ;
return JSONSuccess ;
}
}
JSON_Status json_object_dotset_string_with_len ( JSON_Object * object , const char * name , const char * string , size_t len ) {
JSON_Value * value = json_value_init_string_with_len ( string , len ) ;
if ( value = = NULL ) {
return JSONFailure ;
}
if ( json_object_dotset_value ( object , name , value ) = = JSONFailure ) {
json_value_free ( value ) ;
return JSONFailure ;
}
return JSONSuccess ;
}
JSON_Status json_object_dotset_number ( JSON_Object * object , const char * name , double number ) {
JSON_Status json_object_dotset_number ( JSON_Object * object , const char * name , double number ) {
JSON_Value * value = json_value_init_number ( number ) ;
JSON_Value * value = json_value_init_number ( number ) ;
if ( value = = NULL ) {
if ( value = = NULL ) {
@ -1985,7 +2073,7 @@ JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value) {
int json_value_equals ( const JSON_Value * a , const JSON_Value * b ) {
int json_value_equals ( const JSON_Value * a , const JSON_Value * b ) {
JSON_Object * a_object = NULL , * b_object = NULL ;
JSON_Object * a_object = NULL , * b_object = NULL ;
JSON_Array * a_array = NULL , * b_array = NULL ;
JSON_Array * a_array = NULL , * b_array = NULL ;
const char * a_string = NULL , * b_string = NULL ;
const JSON_String * a_string = NULL , * b_string = NULL ;
const char * key = NULL ;
const char * key = NULL ;
size_t a_count = 0 , b_count = 0 , i = 0 ;
size_t a_count = 0 , b_count = 0 , i = 0 ;
JSON_Value_Type a_type , b_type ;
JSON_Value_Type a_type , b_type ;
@ -2027,12 +2115,13 @@ int json_value_equals(const JSON_Value *a, const JSON_Value *b) {
}
}
return 1 ;
return 1 ;
case JSONString :
case JSONString :
a_string = json_value_get_string ( a ) ;
a_string = json_value_get_string_desc ( a ) ;
b_string = json_value_get_string ( b ) ;
b_string = json_value_get_string_desc ( b ) ;
if ( a_string = = NULL | | b_string = = NULL ) {
if ( a_string = = NULL | | b_string = = NULL ) {
return 0 ; /* shouldn't happen */
return 0 ; /* shouldn't happen */
}
}
return strcmp ( a_string , b_string ) = = 0 ;
return a_string - > length = = b_string - > length & &
memcmp ( a_string - > chars , b_string - > chars , a_string - > length ) = = 0 ;
case JSONBoolean :
case JSONBoolean :
return json_value_get_boolean ( a ) = = json_value_get_boolean ( b ) ;
return json_value_get_boolean ( a ) = = json_value_get_boolean ( b ) ;
case JSONNumber :
case JSONNumber :
@ -2062,6 +2151,10 @@ const char * json_string (const JSON_Value *value) {
return json_value_get_string ( value ) ;
return json_value_get_string ( value ) ;
}
}
size_t json_string_len ( const JSON_Value * value ) {
return json_value_get_string_len ( value ) ;
}
double json_number ( const JSON_Value * value ) {
double json_number ( const JSON_Value * value ) {
return json_value_get_number ( value ) ;
return json_value_get_number ( value ) ;
}
}