+*~
*.o
*.a
.libs
stamp-h1
*.pyc
*.pc
+ /src/jansson.h
- AC_PREREQ([2.59])
+ AC_PREREQ([2.60])
-AC_INIT([jansson], [1.2], [petri@digip.org])
+AC_INIT([jansson], [1.2+], [petri@digip.org])
AM_INIT_AUTOMAKE([1.10 foreign])
# Checks for programs.
AC_PROG_CC
+AC_PROG_CXX
AC_PROG_LIBTOOL
# Checks for libraries.
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_INT32_T
+ AC_C_INLINE
+ case $ac_cv_c_inline in
+ yes) json_inline=inline;;
+ no) json_inline=;;
+ *) json_inline=$ac_cv_c_inline;;
+ esac
+ AC_SUBST([json_inline])
+
# Checks for library functions.
AC_CONFIG_FILES([
Makefile
doc/Makefile
src/Makefile
+ src/jansson.h
test/Makefile
test/bin/Makefile
test/suites/Makefile
* it under the terms of the MIT license. See LICENSE for details.
*/
+ #include <config.h>
+
#include <stdlib.h>
#include "hashtable.h"
bucket_t *bucket;
unsigned int hash, index;
- hash = hashtable->hash_key(key);
-
- /* if the key already exists, delete it */
- hashtable_do_del(hashtable, key, hash);
-
/* rehash if the load ratio exceeds 1 */
if(hashtable->size >= num_buckets(hashtable))
if(hashtable_do_rehash(hashtable))
return -1;
- pair = malloc(sizeof(pair_t));
- if(!pair)
- return -1;
-
- pair->key = key;
- pair->value = value;
- pair->hash = hash;
- list_init(&pair->list);
-
+ hash = hashtable->hash_key(key);
index = hash % num_buckets(hashtable);
bucket = &hashtable->buckets[index];
+ pair = hashtable_find_pair(hashtable, bucket, key, hash);
+
+ if(pair)
+ {
+ if(hashtable->free_key)
+ hashtable->free_key(key);
+ if(hashtable->free_value)
+ hashtable->free_value(pair->value);
+ pair->value = value;
+ }
+ else
+ {
+ pair = malloc(sizeof(pair_t));
+ if(!pair)
+ return -1;
+
+ pair->key = key;
+ pair->value = value;
+ pair->hash = hash;
+ list_init(&pair->list);
- insert_to_bucket(hashtable, bucket, &pair->list);
+ insert_to_bucket(hashtable, bucket, &pair->list);
- hashtable->size++;
+ hashtable->size++;
+ }
return 0;
}
return hashtable_iter_next(hashtable, &hashtable->list);
}
+void *hashtable_iter_at(hashtable_t *hashtable, const void *key)
+{
+ pair_t *pair;
+ unsigned int hash;
+ bucket_t *bucket;
+
+ hash = hashtable->hash_key(key);
+ bucket = &hashtable->buckets[hash % num_buckets(hashtable)];
+
+ pair = hashtable_find_pair(hashtable, bucket, key, hash);
+ if(!pair)
+ return NULL;
+
+ return &pair->list;
+}
+
void *hashtable_iter_next(hashtable_t *hashtable, void *iter)
{
list_t *list = (list_t *)iter;
pair_t *pair = list_to_pair((list_t *)iter);
return pair->value;
}
+
+void hashtable_iter_set(hashtable_t *hashtable, void *iter, void *value)
+{
+ pair_t *pair = list_to_pair((list_t *)iter);
+
+ if(hashtable->free_value)
+ hashtable->free_value(pair->value);
+
+ pair->value = value;
+}
#include <stdio.h>
- #ifdef __cplusplus
+ #ifndef __cplusplus
+ #define JSON_INLINE @json_inline@
+ #else
+ #define JSON_INLINE inline
extern "C" {
#endif
json_t *json_false(void);
json_t *json_null(void);
- static inline json_t *json_incref(json_t *json)
+ static JSON_INLINE
+ json_t *json_incref(json_t *json)
{
if(json && json->refcount != (unsigned int)-1)
++json->refcount;
/* do not call json_delete directly */
void json_delete(json_t *json);
- static inline void json_decref(json_t *json)
+ static JSON_INLINE
+ void json_decref(json_t *json)
{
if(json && json->refcount != (unsigned int)-1 && --json->refcount == 0)
json_delete(json);
int json_object_clear(json_t *object);
int json_object_update(json_t *object, json_t *other);
void *json_object_iter(json_t *object);
+void *json_object_iter_at(json_t *object, const char *key);
void *json_object_iter_next(json_t *object, void *iter);
const char *json_object_iter_key(void *iter);
json_t *json_object_iter_value(void *iter);
+int json_object_iter_set_new(json_t *object, void *iter, json_t *value);
- static inline
+ static JSON_INLINE
int json_object_set(json_t *object, const char *key, json_t *value)
{
return json_object_set_new(object, key, json_incref(value));
}
- static inline
+ static JSON_INLINE
int json_object_set_nocheck(json_t *object, const char *key, json_t *value)
{
return json_object_set_new_nocheck(object, key, json_incref(value));
}
+static inline
+int json_object_iter_set(json_t *object, void *iter, json_t *value)
+{
+ return json_object_iter_set_new(object, iter, json_incref(value));
+}
+
unsigned int json_array_size(const json_t *array);
json_t *json_array_get(const json_t *array, unsigned int index);
int json_array_set_new(json_t *array, unsigned int index, json_t *value);
int json_array_clear(json_t *array);
int json_array_extend(json_t *array, json_t *other);
- static inline
+ static JSON_INLINE
int json_array_set(json_t *array, unsigned int index, json_t *value)
{
return json_array_set_new(array, index, json_incref(value));
}
- static inline
+ static JSON_INLINE
int json_array_append(json_t *array, json_t *value)
{
return json_array_append_new(array, json_incref(value));
}
- static inline
+ static JSON_INLINE
int json_array_insert(json_t *array, unsigned int index, json_t *value)
{
return json_array_insert_new(array, index, json_incref(value));
#define JSON_COMPACT 0x100
#define JSON_ENSURE_ASCII 0x200
#define JSON_SORT_KEYS 0x400
+#define JSON_PRESERVE_ORDER 0x800
char *json_dumps(const json_t *json, unsigned long flags);
int json_dumpf(const json_t *json, FILE *output, unsigned long flags);
*/
#define _GNU_SOURCE
+
+ #include <config.h>
+
#include <stdlib.h>
#include <string.h>
/*** 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)
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;
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;
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)
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;