Merge branch '1.2'
authorPetri Lehtinen <petri@digip.org>
Tue, 23 Mar 2010 06:15:19 +0000 (08:15 +0200)
committerPetri Lehtinen <petri@digip.org>
Tue, 23 Mar 2010 06:15:19 +0000 (08:15 +0200)
1  2 
configure.ac
src/dump.c
src/value.c

diff --combined configure.ac
@@@ -1,5 -1,5 +1,5 @@@
  AC_PREREQ([2.59])
 -AC_INIT([jansson], [1.2], [petri@digip.org])
 +AC_INIT([jansson], [1.2+], [petri@digip.org])
  
  AM_INIT_AUTOMAKE([1.10 foreign])
  
@@@ -8,7 -8,6 +8,7 @@@ AC_CONFIG_HEADERS([config.h]
  
  # Checks for programs.
  AC_PROG_CC
 +AC_PROG_CXX
  AC_PROG_LIBTOOL
  
  # Checks for libraries.
@@@ -16,6 -15,7 +16,7 @@@
  # Checks for header files.
  
  # Checks for typedefs, structures, and compiler characteristics.
+ AC_TYPE_INT32_T
  
  # Checks for library functions.
  
diff --combined src/dump.c
@@@ -9,7 -9,6 +9,6 @@@
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
- #include <stdint.h>
  #include <assert.h>
  
  #include <jansson.h>
@@@ -154,16 -153,9 +153,16 @@@ static int dump_string(const char *str
      return dump("\"", 1, data);
  }
  
 -static int object_key_cmp(const void *key1, const void *key2)
 +static int object_key_compare_keys(const void *key1, const void *key2)
  {
 -    return strcmp(*(const char **)key1, *(const char **)key2);
 +    return strcmp((*(const object_key_t **)key1)->key,
 +                  (*(const object_key_t **)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;
  }
  
  static int do_dump(const json_t *json, unsigned long flags, int depth,
              if(dump_indent(flags, depth + 1, 0, dump, data))
                  return -1;
  
 -            if(flags & JSON_SORT_KEYS)
 +            if(flags & JSON_SORT_KEYS || flags & JSON_PRESERVE_ORDER)
              {
 -                /* Sort keys */
 -
 -                const char **keys;
 +                const object_key_t **keys;
                  unsigned int size;
                  unsigned int i;
 +                int (*cmp_func)(const void *, const void *);
  
                  size = json_object_size(json);
 -                keys = malloc(size * sizeof(const char *));
 +                keys = malloc(size * sizeof(object_key_t *));
                  if(!keys)
                      return -1;
  
                  i = 0;
                  while(iter)
                  {
 -                    keys[i] = json_object_iter_key(iter);
 +                    keys[i] = jsonp_object_iter_fullkey(iter);
                      iter = json_object_iter_next((json_t *)json, iter);
                      i++;
                  }
                  assert(i == size);
  
 -                qsort(keys, size, sizeof(const char *), object_key_cmp);
 +                if(flags & JSON_SORT_KEYS)
 +                    cmp_func = object_key_compare_keys;
 +                else
 +                    cmp_func = object_key_compare_serials;
 +
 +                qsort(keys, size, sizeof(object_key_t *), cmp_func);
  
                  for(i = 0; i < size; i++)
                  {
                      const char *key;
                      json_t *value;
  
 -                    key = keys[i];
 +                    key = keys[i]->key;
                      value = json_object_get(json, key);
                      assert(value);
  
diff --combined src/value.c
@@@ -25,16 -25,9 +25,16 @@@ static inline void json_init(json_t *js
  
  /*** object ***/
  
 -static unsigned int hash_string(const void *key)
 +/* This macro just returns a pointer that's a few bytes backwards from
 +   string. This makes it possible to pass a pointer to object_key_t
 +   when only the string inside it is used, without actually creating
 +   an object_key_t instance. */
 +#define string_to_key(string)  container_of(string, object_key_t, key)
 +
 +static unsigned int hash_key(const void *ptr)
  {
 -    const char *str = (const char *)key;
 +    const char *str = ((const object_key_t *)ptr)->key;
 +
      unsigned int hash = 5381;
      unsigned int c;
  
      return hash;
  }
  
 -static int string_equal(const void *key1, const void *key2)
 +static int key_equal(const void *ptr1, const void *ptr2)
  {
 -    return strcmp((const char *)key1, (const char *)key2) == 0;
 +    return strcmp(((const object_key_t *)ptr1)->key,
 +                  ((const object_key_t *)ptr2)->key) == 0;
  }
  
  static void value_decref(void *value)
@@@ -65,14 -57,13 +65,14 @@@ json_t *json_object(void
          return NULL;
      json_init(&object->json, JSON_OBJECT);
  
 -    if(hashtable_init(&object->hashtable, hash_string, string_equal,
 +    if(hashtable_init(&object->hashtable, hash_key, key_equal,
                        free, value_decref))
      {
          free(object);
          return NULL;
      }
  
 +    object->serial = 0;
      object->visited = 0;
  
      return &object->json;
@@@ -103,13 -94,12 +103,13 @@@ json_t *json_object_get(const json_t *j
          return NULL;
  
      object = json_to_object(json);
 -    return hashtable_get(&object->hashtable, key);
 +    return hashtable_get(&object->hashtable, string_to_key(key));
  }
  
  int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)
  {
      json_object_t *object;
 +    object_key_t *k;
  
      if(!key || !value)
          return -1;
      }
      object = json_to_object(json);
  
 -    if(hashtable_set(&object->hashtable, strdup(key), value))
 +    k = malloc(sizeof(object_key_t) + strlen(key) + 1);
 +    if(!k)
 +        return -1;
 +
 +    k->serial = object->serial++;
 +    strcpy(k->key, key);
 +
 +    if(hashtable_set(&object->hashtable, k, value))
      {
          json_decref(value);
          return -1;
@@@ -156,7 -139,7 +156,7 @@@ int json_object_del(json_t *json, cons
          return -1;
  
      object = json_to_object(json);
 -    return hashtable_del(&object->hashtable, key);
 +    return hashtable_del(&object->hashtable, string_to_key(key));
  }
  
  int json_object_clear(json_t *json)
@@@ -207,17 -190,6 +207,17 @@@ void *json_object_iter(json_t *json
      return hashtable_iter(&object->hashtable);
  }
  
 +void *json_object_iter_at(json_t *json, const char *key)
 +{
 +    json_object_t *object;
 +
 +    if(!key || !json_is_object(json))
 +        return NULL;
 +
 +    object = json_to_object(json);
 +    return hashtable_iter_at(&object->hashtable, string_to_key(key));
 +}
 +
  void *json_object_iter_next(json_t *json, void *iter)
  {
      json_object_t *object;
      return hashtable_iter_next(&object->hashtable, iter);
  }
  
 +const object_key_t *jsonp_object_iter_fullkey(void *iter)
 +{
 +    if(!iter)
 +        return NULL;
 +
 +    return hashtable_iter_key(iter);
 +}
 +
  const char *json_object_iter_key(void *iter)
  {
      if(!iter)
          return NULL;
  
 -    return (const char *)hashtable_iter_key(iter);
 +    return jsonp_object_iter_fullkey(iter)->key;
  }
  
  json_t *json_object_iter_value(void *iter)
      return (json_t *)hashtable_iter_value(iter);
  }
  
 +int json_object_iter_set_new(json_t *json, void *iter, json_t *value)
 +{
 +    json_object_t *object;
 +
 +    if(!json_is_object(json) || !iter || !value)
 +        return -1;
 +
 +    object = json_to_object(json);
 +    hashtable_iter_set(&object->hashtable, iter, value);
 +
 +    return 0;
 +}
 +
  static int json_object_equal(json_t *object1, json_t *object2)
  {
      void *iter;
@@@ -833,7 -784,7 +833,7 @@@ json_t *json_true(void
  {
      static json_t the_true = {
          .type = JSON_TRUE,
-         .refcount = (unsigned int)1
+         .refcount = (unsigned int)-1
      };
      return &the_true;
  }
@@@ -843,7 -794,7 +843,7 @@@ json_t *json_false(void
  {
      static json_t the_false = {
          .type = JSON_FALSE,
-         .refcount = (unsigned int)1
+         .refcount = (unsigned int)-1
      };
      return &the_false;
  }
@@@ -853,7 -804,7 +853,7 @@@ json_t *json_null(void
  {
      static json_t the_null = {
          .type = JSON_NULL,
-         .refcount = (unsigned int)1
+         .refcount = (unsigned int)-1
      };
      return &the_null;
  }