diff --git a/src/dump.c b/src/dump.c index 5bd5140..7a566d9 100644 --- a/src/dump.c +++ b/src/dump.c @@ -106,12 +106,26 @@ static int do_dump(const json_t *json, uint32_t flags, int depth, case JSON_FALSE: return dump("false", 5, data); - case JSON_NUMBER: + case JSON_INTEGER: { char *buffer; int size, ret; - size = asprintf(&buffer, "%.17f", json_number_value(json)); + size = asprintf(&buffer, "%d", json_integer_value(json)); + if(size == -1) + return -1; + + ret = dump(buffer, size, data); + free(buffer); + return ret; + } + + case JSON_REAL: + { + char *buffer; + int size, ret; + + size = asprintf(&buffer, "%.17f", json_real_value(json)); if(size == -1) return -1; diff --git a/src/jansson.h b/src/jansson.h index e6ece0c..395f479 100644 --- a/src/jansson.h +++ b/src/jansson.h @@ -10,7 +10,8 @@ typedef enum { JSON_OBJECT, JSON_ARRAY, JSON_STRING, - JSON_NUMBER, + JSON_INTEGER, + JSON_REAL, JSON_TRUE, JSON_FALSE, JSON_NULL @@ -25,7 +26,9 @@ typedef struct { #define json_is_object(json) (json && json_typeof(json) == JSON_OBJECT) #define json_is_array(json) (json && json_typeof(json) == JSON_ARRAY) #define json_is_string(json) (json && json_typeof(json) == JSON_STRING) -#define json_is_number(json) (json && json_typeof(json) == JSON_NUMBER) +#define json_is_integer(json) (json && json_typeof(json) == JSON_INTEGER) +#define json_is_real(json) (json && json_typeof(json) == JSON_REAL) +#define json_is_number(json) (json_is_integer(json) || json_is_real(json)) #define json_is_true(json) (json && json_typeof(json) == JSON_TRUE) #define json_is_false(json) (json && json_typeof(json) == JSON_FALSE) #define json_is_null(json) (json && json_typeof(json) == JSON_NULL) @@ -35,7 +38,8 @@ typedef struct { json_t *json_object(void); json_t *json_array(void); json_t *json_string(const char *value); -json_t *json_number(double value); +json_t *json_integer(int value); +json_t *json_real(double value); json_t *json_true(void); json_t *json_false(void); json_t *json_null(void); @@ -75,6 +79,8 @@ int json_array_set(json_t *array, unsigned int index, json_t *value); int json_array_append(json_t *array, json_t *value); const char *json_string_value(const json_t *json); +int json_integer_value(const json_t *json); +double json_real_value(const json_t *json); double json_number_value(const json_t *json); diff --git a/src/load.c b/src/load.c index 27779e8..9317521 100644 --- a/src/load.c +++ b/src/load.c @@ -15,10 +15,11 @@ #define JSON_TOKEN_INVALID -1 #define JSON_TOKEN_EOF 0 #define JSON_TOKEN_STRING 256 -#define JSON_TOKEN_NUMBER 257 -#define JSON_TOKEN_TRUE 258 -#define JSON_TOKEN_FALSE 259 -#define JSON_TOKEN_NULL 260 +#define JSON_TOKEN_INTEGER 257 +#define JSON_TOKEN_REAL 258 +#define JSON_TOKEN_TRUE 259 +#define JSON_TOKEN_FALSE 260 +#define JSON_TOKEN_NULL 261 typedef struct { const char *input; @@ -27,7 +28,8 @@ typedef struct { int line, column; union { char *string; - double number; + int integer; + double real; } value; } json_lex; @@ -176,7 +178,16 @@ static void json_scan_number(json_lex *lex) p++; } - if(*p == '.') { + if(*p != '.') { + lex->token = JSON_TOKEN_INTEGER; + + lex->value.integer = strtol(lex->start, &end, 10); + assert(end == p); + + lex->input = p; + return; + } + else /* *p == '.' */ { p++; if(!isdigit(*(p++))) goto out; @@ -197,9 +208,9 @@ static void json_scan_number(json_lex *lex) p++; } - lex->token = JSON_TOKEN_NUMBER; + lex->token = JSON_TOKEN_REAL; - lex->value.number = strtod(lex->start, &end); + lex->value.real = strtod(lex->start, &end); assert(end == p); out: @@ -402,8 +413,13 @@ static json_t *json_parse(json_lex *lex, json_error_t *error) break; } - case JSON_TOKEN_NUMBER: { - json = json_number(lex->value.number); + case JSON_TOKEN_INTEGER: { + json = json_integer(lex->value.integer); + break; + } + + case JSON_TOKEN_REAL: { + json = json_real(lex->value.real); break; } diff --git a/src/value.c b/src/value.c index 998446c..00501d5 100644 --- a/src/value.c +++ b/src/value.c @@ -29,12 +29,18 @@ typedef struct { typedef struct { json_t json; double value; -} json_number_t; +} json_real_t; + +typedef struct { + json_t json; + int value; +} json_integer_t; #define json_to_object(json_) container_of(json_, json_object_t, json) #define json_to_array(json_) container_of(json_, json_array_t, json) #define json_to_string(json_) container_of(json_, json_string_t, json) -#define json_to_number(json_) container_of(json_, json_number_t, json) +#define json_to_real(json_) container_of(json_, json_real_t, json) +#define json_to_integer(json_) container_of(json_, json_integer_t, json) static inline void json_init(json_t *json, json_type type) { @@ -274,15 +280,58 @@ static void json_delete_string(json_string_t *string) free(string); } -json_t *json_number(double value) -{ - json_number_t *number = malloc(sizeof(json_number_t)); - if(!number) - return NULL; - json_init(&number->json, JSON_NUMBER); - number->value = value; - return &number->json; +/*** integer ***/ + +json_t *json_integer(int value) +{ + json_integer_t *integer = malloc(sizeof(json_integer_t)); + if(!integer) + return NULL; + json_init(&integer->json, JSON_INTEGER); + + integer->value = value; + return &integer->json; +} + +int json_integer_value(const json_t *json) +{ + if(!json_is_integer(json)) + return 0; + + return json_to_integer(json)->value; +} + +static void json_delete_integer(json_integer_t *integer) +{ + free(integer); +} + + +/*** real ***/ + +json_t *json_real(double value) +{ + json_real_t *real = malloc(sizeof(json_real_t)); + if(!real) + return NULL; + json_init(&real->json, JSON_REAL); + + real->value = value; + return &real->json; +} + +double json_real_value(const json_t *json) +{ + if(!json_is_real(json)) + return 0; + + return json_to_real(json)->value; +} + +static void json_delete_real (json_real_t *real) +{ + free(real); } @@ -290,15 +339,12 @@ json_t *json_number(double value) double json_number_value(const json_t *json) { - if(!json_is_number(json)) + if(json_is_integer(json)) + return json_integer_value(json); + else if(json_is_real(json)) + return json_real_value(json); + else return 0.0; - - return json_to_number(json)->value; -} - -static void json_delete_number(json_number_t *number) -{ - free(number); } @@ -347,8 +393,11 @@ void json_delete(json_t *json) else if(json_is_string(json)) json_delete_string(json_to_string(json)); - else if(json_is_number(json)) - json_delete_number(json_to_number(json)); + else if(json_is_integer(json)) + json_delete_integer(json_to_integer(json)); + + else if(json_is_real(json)) + json_delete_real(json_to_real(json)); /* json_delete is not called for true, false or null */ }