#define json_to_real(json_) container_of(json_, json_real_t, json)
#define json_to_integer(json_) container_of(json_, json_integer_t, json)
-size_t jsonp_hash_key(const void *ptr);
-int jsonp_key_equal(const void *ptr1, const void *ptr2);
+size_t jsonp_hash_str(const void *ptr);
+int jsonp_str_equal(const void *ptr1, const void *ptr2);
typedef struct {
size_t serial;
*/
hashtable_t key_set;
- if(hashtable_init(&key_set, jsonp_hash_key, jsonp_key_equal, NULL, NULL)) {
+ if(hashtable_init(&key_set, jsonp_hash_str, jsonp_str_equal, NULL, NULL)) {
set_error(s, "<internal>", "Out of memory");
return -1;
}
/*** object ***/
-/* 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)
-
-size_t jsonp_hash_key(const void *ptr)
+/* From http://www.cse.yorku.ca/~oz/hash.html */
+size_t jsonp_hash_str(const void *ptr)
{
- const char *str = ((const object_key_t *)ptr)->key;
+ const char *str = (const char *)ptr;
size_t hash = 5381;
size_t c;
return hash;
}
-int jsonp_key_equal(const void *ptr1, const void *ptr2)
+int jsonp_str_equal(const void *ptr1, const void *ptr2)
+{
+ return strcmp((const char *)ptr1, (const char *)ptr2) == 0;
+}
+
+/* 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 size_t hash_key(const void *ptr)
+{
+ return jsonp_hash_str(((const object_key_t *)ptr)->key);
+}
+
+static int key_equal(const void *ptr1, const void *ptr2)
{
- return strcmp(((const object_key_t *)ptr1)->key,
- ((const object_key_t *)ptr2)->key) == 0;
+ return jsonp_str_equal(((const object_key_t *)ptr1)->key,
+ ((const object_key_t *)ptr2)->key);
}
static void value_decref(void *value)
json_init(&object->json, JSON_OBJECT);
if(hashtable_init(&object->hashtable,
- jsonp_hash_key, jsonp_key_equal,
+ hash_key, key_equal,
jsonp_free, value_decref))
{
jsonp_free(object);
fail("json_unpack simple array failed");
json_decref(j);
+ /* object with many items & strict checking */
+ j = json_pack("{s:i, s:i, s:i}", "a", 1, "b", 2, "c", 3);
+ rv = json_unpack(j, "{s:i, s:i, s:i}", "a", &i1, "b", &i2, "c", &i3);
+ if(rv || i1 != 1 || i2 != 2 || i3 != 3)
+ fail("json_unpack object with many items failed");
+ json_decref(j);
+
/*
* Invalid cases
*/
/* Unpack the same item twice */
j = json_pack("{s:s, s:i}", "foo", "bar", "baz", 42);
if(!json_unpack_ex(j, &error, 0, "{s:s,s:s!}", "foo", &s, "foo", &s))
- fail("json_unpack object with strict validation failed");
+ fail("json_unpack object with strict validation failed");
check_error("1 object item(s) left unpacked", "<validation>", 1, 10, 10);
json_decref(j);