Separate integers and real numbers
authorPetri Lehtinen <petri@digip.org>
Mon, 22 Jun 2009 21:14:28 +0000 (00:14 +0300)
committerPetri Lehtinen <petri@digip.org>
Sat, 4 Jul 2009 10:19:25 +0000 (13:19 +0300)
src/dump.c
src/jansson.h
src/load.c
src/value.c

index 5bd5140..7a566d9 100644 (file)
@@ -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;
 
index e6ece0c..395f479 100644 (file)
@@ -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);
 
 
index 27779e8..9317521 100644 (file)
 #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;
         }
 
index 998446c..00501d5 100644 (file)
@@ -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,31 +280,71 @@ static void json_delete_string(json_string_t *string)
     free(string);
 }
 
-json_t *json_number(double value)
+
+/*** integer ***/
+
+json_t *json_integer(int value)
 {
-    json_number_t *number = malloc(sizeof(json_number_t));
-    if(!number)
+    json_integer_t *integer = malloc(sizeof(json_integer_t));
+    if(!integer)
        return NULL;
-    json_init(&number->json, JSON_NUMBER);
+    json_init(&integer->json, JSON_INTEGER);
 
-    number->value = value;
-    return &number->json;
+    integer->value = value;
+    return &integer->json;
 }
 
+int json_integer_value(const json_t *json)
+{
+    if(!json_is_integer(json))
+        return 0;
 
-/*** number ***/
+    return json_to_integer(json)->value;
+}
 
-double json_number_value(const json_t *json)
+static void json_delete_integer(json_integer_t *integer)
 {
-    if(!json_is_number(json))
-        return 0.0;
+    free(integer);
+}
 
-    return json_to_number(json)->value;
+
+/*** 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_number(json_number_t *number)
+static void json_delete_real (json_real_t *real)
 {
-    free(number);
+    free(real);
+}
+
+
+/*** number ***/
+
+double json_number_value(const json_t *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;
 }
 
 
@@ -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 */
 }