Make hashtable less generic
[jansson.git] / src / dump.c
index 344670a..aec535b 100644 (file)
 #define MAX_INTEGER_STR_LENGTH  100
 #define MAX_REAL_STR_LENGTH     100
 
-struct string
-{
-    char *buffer;
-    int length;
-    int size;
+struct object_key {
+    size_t serial;
+    const char *key;
 };
 
 static int dump_to_strbuffer(const char *buffer, size_t size, void *data)
@@ -153,14 +151,16 @@ static int dump_string(const char *str, int ascii, json_dump_callback_t dump, vo
 
 static int object_key_compare_keys(const void *key1, const void *key2)
 {
-    return strcmp((*(const object_key_t **)key1)->key,
-                  (*(const object_key_t **)key2)->key);
+    return strcmp(((const struct object_key *)key1)->key,
+                  ((const struct object_key *)key2)->key);
 }
 
 static int object_key_compare_serials(const void *key1, const void *key2)
 {
-    return (*(const object_key_t **)key1)->serial -
-           (*(const object_key_t **)key2)->serial;
+    size_t a = ((const struct object_key *)key1)->serial;
+    size_t b = ((const struct object_key *)key2)->serial;
+
+    return a < b ? -1 : a == b ? 0 : 1;
 }
 
 static int do_dump(const json_t *json, size_t flags, int depth,
@@ -196,26 +196,12 @@ static int do_dump(const json_t *json, size_t flags, int depth,
         {
             char buffer[MAX_REAL_STR_LENGTH];
             int size;
+            double value = json_real_value(json);
 
-            size = snprintf(buffer, MAX_REAL_STR_LENGTH, "%.17g",
-                            json_real_value(json));
-            if(size >= MAX_REAL_STR_LENGTH)
+            size = jsonp_dtostr(buffer, MAX_REAL_STR_LENGTH, value);
+            if(size < 0)
                 return -1;
 
-            /* Make sure there's a dot or 'e' in the output. Otherwise
-               a real is converted to an integer when decoding */
-            if(strchr(buffer, '.') == NULL &&
-               strchr(buffer, 'e') == NULL)
-            {
-                if(size + 2 >= MAX_REAL_STR_LENGTH) {
-                    /* No space to append ".0" */
-                    return -1;
-                }
-                buffer[size] = '.';
-                buffer[size + 1] = '0';
-                size += 2;
-            }
-
             return dump(buffer, size, data);
         }
 
@@ -306,19 +292,20 @@ static int do_dump(const json_t *json, size_t flags, int depth,
 
             if(flags & JSON_SORT_KEYS || flags & JSON_PRESERVE_ORDER)
             {
-                const object_key_t **keys;
+                struct object_key *keys;
                 size_t size, i;
                 int (*cmp_func)(const void *, const void *);
 
                 size = json_object_size(json);
-                keys = jsonp_malloc(size * sizeof(object_key_t *));
+                keys = jsonp_malloc(size * sizeof(struct object_key));
                 if(!keys)
                     goto object_error;
 
                 i = 0;
                 while(iter)
                 {
-                    keys[i] = jsonp_object_iter_fullkey(iter);
+                    keys[i].serial = hashtable_iter_serial(iter);
+                    keys[i].key = json_object_iter_key(iter);
                     iter = json_object_iter_next((json_t *)json, iter);
                     i++;
                 }
@@ -329,14 +316,14 @@ static int do_dump(const json_t *json, size_t flags, int depth,
                 else
                     cmp_func = object_key_compare_serials;
 
-                qsort(keys, size, sizeof(object_key_t *), cmp_func);
+                qsort(keys, size, sizeof(struct object_key), cmp_func);
 
                 for(i = 0; i < size; i++)
                 {
                     const char *key;
                     json_t *value;
 
-                    key = keys[i]->key;
+                    key = keys[i].key;
                     value = json_object_get(json, key);
                     assert(value);
 
@@ -413,39 +400,26 @@ static int do_dump(const json_t *json, size_t flags, int depth,
     }
 }
 
-
 char *json_dumps(const json_t *json, size_t flags)
 {
     strbuffer_t strbuff;
     char *result;
 
-    if(!(flags & JSON_ENCODE_ANY)) {
-        if(!json_is_array(json) && !json_is_object(json))
-           return NULL;
-    }
-
     if(strbuffer_init(&strbuff))
         return NULL;
 
-    if(do_dump(json, flags, 0, dump_to_strbuffer, (void *)&strbuff)) {
-        strbuffer_close(&strbuff);
-        return NULL;
-    }
+    if(json_dump_callback(json, dump_to_strbuffer, (void *)&strbuff, flags))
+        result = NULL;
+    else
+        result = jsonp_strdup(strbuffer_value(&strbuff));
 
-    result = jsonp_strdup(strbuffer_value(&strbuff));
     strbuffer_close(&strbuff);
-
     return result;
 }
 
 int json_dumpf(const json_t *json, FILE *output, size_t flags)
 {
-    if(!(flags & JSON_ENCODE_ANY)) {
-        if(!json_is_array(json) && !json_is_object(json))
-           return -1;
-    }
-
-    return do_dump(json, flags, 0, dump_to_file, (void *)output);
+    return json_dump_callback(json, dump_to_file, (void *)output, flags);
 }
 
 int json_dump_file(const json_t *json, const char *path, size_t flags)