introduce new fixed-size key API

This commit added functions working with fixed-size strings (non null-terminated also).
It's helpful for the following cases:
* getting key from substring without copying to separate buffer (better perfomance)
* using pure UTF-8 keys for the objets
* hack: set binary structs as the keys (see test_binary_keys)

added functions:
 * json_object_getn
 * json_object_setn
 * json_object_setn_nocheck
 * json_object_setn_new
 * json_object_setn_new_nocheck
 * json_object_deln
 * json_object_iter_key_len

added iterators:
 * json_object_keylen_foreach
 * json_object_keylen_foreach_safe

Signed-off-by: Maxim Zhukov <mussitantesmortem@gmail.com>
This commit is contained in:
Maxim Zhukov
2020-01-09 22:18:41 +03:00
parent ba4503804b
commit ca6775dee4
9 changed files with 459 additions and 8 deletions

View File

@@ -322,6 +322,11 @@ void *hashtable_iter_key(void *iter) {
return pair->key;
}
size_t hashtable_iter_key_len(void *iter) {
pair_t *pair = ordered_list_to_pair((list_t *)iter);
return pair->key_len;
}
void *hashtable_iter_value(void *iter) {
pair_t *pair = ordered_list_to_pair((list_t *)iter);
return pair->value;

View File

@@ -161,6 +161,13 @@ void *hashtable_iter_next(hashtable_t *hashtable, void *iter);
*/
void *hashtable_iter_key(void *iter);
/**
* hashtable_iter_key_len - Retrieve the key length pointed by an iterator
*
* @iter: The iterator
*/
size_t hashtable_iter_key_len(void *iter);
/**
* hashtable_iter_value - Retrieve the value pointed by an iterator
*

View File

@@ -34,9 +34,13 @@ EXPORTS
json_object
json_object_size
json_object_get
json_object_getn
json_object_set_new
json_object_setn_new
json_object_set_new_nocheck
json_object_setn_new_nocheck
json_object_del
json_object_deln
json_object_clear
json_object_update
json_object_update_existing
@@ -46,6 +50,7 @@ EXPORTS
json_object_iter_at
json_object_iter_next
json_object_iter_key
json_object_iter_key_len
json_object_iter_value
json_object_iter_set_new
json_object_key_to_iter

View File

@@ -188,9 +188,15 @@ void json_object_seed(size_t seed);
size_t json_object_size(const json_t *object);
json_t *json_object_get(const json_t *object, const char *key)
JANSSON_ATTRS((warn_unused_result));
json_t *json_object_getn(const json_t *object, const char *key, size_t key_len)
JANSSON_ATTRS((warn_unused_result));
int json_object_set_new(json_t *object, const char *key, json_t *value);
int json_object_setn_new(json_t *object, const char *key, size_t key_len, json_t *value);
int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value);
int json_object_setn_new_nocheck(json_t *object, const char *key, size_t key_len,
json_t *value);
int json_object_del(json_t *object, const char *key);
int json_object_deln(json_t *object, const char *key, size_t key_len);
int json_object_clear(json_t *object);
int json_object_update(json_t *object, json_t *other);
int json_object_update_existing(json_t *object, json_t *other);
@@ -201,6 +207,7 @@ void *json_object_iter_at(json_t *object, const char *key);
void *json_object_key_to_iter(const char *key);
void *json_object_iter_next(json_t *object, void *iter);
const char *json_object_iter_key(void *iter);
size_t json_object_iter_key_len(void *iter);
json_t *json_object_iter_value(void *iter);
int json_object_iter_set_new(json_t *object, void *iter, json_t *value);
@@ -210,6 +217,14 @@ int json_object_iter_set_new(json_t *object, void *iter, json_t *value);
key = json_object_iter_key( \
json_object_iter_next(object, json_object_key_to_iter(key))))
#define json_object_keylen_foreach(object, key, key_len, value) \
for (key = json_object_iter_key(json_object_iter(object)), \
key_len = json_object_iter_key_len(json_object_key_to_iter(key)); \
key && (value = json_object_iter_value(json_object_key_to_iter(key))); \
key = json_object_iter_key( \
json_object_iter_next(object, json_object_key_to_iter(key))), \
key_len = json_object_iter_key_len(json_object_key_to_iter(key)))
#define json_object_foreach_safe(object, n, key, value) \
for (key = json_object_iter_key(json_object_iter(object)), \
n = json_object_iter_next(object, json_object_key_to_iter(key)); \
@@ -217,6 +232,14 @@ int json_object_iter_set_new(json_t *object, void *iter, json_t *value);
key = json_object_iter_key(n), \
n = json_object_iter_next(object, json_object_key_to_iter(key)))
#define json_object_keylen_foreach_safe(object, n, key, key_len, value) \
for (key = json_object_iter_key(json_object_iter(object)), \
n = json_object_iter_next(object, json_object_key_to_iter(key)), \
key_len = json_object_iter_key_len(json_object_key_to_iter(key)); \
key && (value = json_object_iter_value(json_object_key_to_iter(key))); \
key = json_object_iter_key(n), key_len = json_object_iter_key_len(n), \
n = json_object_iter_next(object, json_object_key_to_iter(key)))
#define json_array_foreach(array, index, value) \
for (index = 0; \
index < json_array_size(array) && (value = json_array_get(array, index)); \
@@ -226,11 +249,21 @@ static JSON_INLINE int json_object_set(json_t *object, const char *key, json_t *
return json_object_set_new(object, key, json_incref(value));
}
static JSON_INLINE int json_object_setn(json_t *object, const char *key, size_t key_len,
json_t *value) {
return json_object_setn_new(object, key, key_len, json_incref(value));
}
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 JSON_INLINE int json_object_setn_nocheck(json_t *object, const char *key,
size_t key_len, json_t *value) {
return json_object_setn_new_nocheck(object, key, key_len, json_incref(value));
}
static JSON_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));
}

View File

@@ -94,16 +94,32 @@ size_t json_object_size(const json_t *json) {
}
json_t *json_object_get(const json_t *json, const char *key) {
if (!key)
return NULL;
return json_object_getn(json, key, strlen(key));
}
json_t *json_object_getn(const json_t *json, const char *key, size_t key_len) {
json_object_t *object;
if (!key || !json_is_object(json))
return NULL;
object = json_to_object(json);
return hashtable_get(&object->hashtable, key, strlen(key));
return hashtable_get(&object->hashtable, key, key_len);
}
int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value) {
if (!key) {
json_decref(value);
return -1;
}
return json_object_setn_new_nocheck(json, key, strlen(key), value);
}
int json_object_setn_new_nocheck(json_t *json, const char *key, size_t key_len,
json_t *value) {
json_object_t *object;
if (!value)
@@ -115,7 +131,7 @@ int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value) {
}
object = json_to_object(json);
if (hashtable_set(&object->hashtable, key, strlen(key), value)) {
if (hashtable_set(&object->hashtable, key, key_len, value)) {
json_decref(value);
return -1;
}
@@ -124,22 +140,38 @@ int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value) {
}
int json_object_set_new(json_t *json, const char *key, json_t *value) {
if (!key || !utf8_check_string(key, strlen(key))) {
if (!key) {
json_decref(value);
return -1;
}
return json_object_set_new_nocheck(json, key, value);
return json_object_setn_new(json, key, strlen(key), value);
}
int json_object_setn_new(json_t *json, const char *key, size_t key_len, json_t *value) {
if (!key || !utf8_check_string(key, key_len)) {
json_decref(value);
return -1;
}
return json_object_setn_new_nocheck(json, key, key_len, value);
}
int json_object_del(json_t *json, const char *key) {
if (!key)
return -1;
return json_object_deln(json, key, strlen(key));
}
int json_object_deln(json_t *json, const char *key, size_t key_len) {
json_object_t *object;
if (!key || !json_is_object(json))
return -1;
object = json_to_object(json);
return hashtable_del(&object->hashtable, key, strlen(key));
return hashtable_del(&object->hashtable, key, key_len);
}
int json_object_clear(json_t *json) {
@@ -281,6 +313,13 @@ const char *json_object_iter_key(void *iter) {
return hashtable_iter_key(iter);
}
size_t json_object_iter_key_len(void *iter) {
if (!iter)
return 0;
return hashtable_iter_key_len(iter);
}
json_t *json_object_iter_value(void *iter) {
if (!iter)
return NULL;