aboutsummaryrefslogtreecommitdiff
path: root/src/value.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/value.c')
-rw-r--r--src/value.c92
1 files changed, 70 insertions, 22 deletions
diff --git a/src/value.c b/src/value.c
index c85a0b4..07af087 100644
--- a/src/value.c
+++ b/src/value.c
@@ -44,13 +44,17 @@ static JSON_INLINE void json_init(json_t *json, json_type type) {
json->refcount = 1;
}
-int jsonp_loop_check(hashtable_t *parents, const json_t *json, char *key,
- size_t key_size) {
- snprintf(key, key_size, "%p", json);
- if (hashtable_get(parents, key))
+int jsonp_loop_check(hashtable_t *parents, const json_t *json, char *key, size_t key_size,
+ size_t *key_len_out) {
+ size_t key_len = snprintf(key, key_size, "%p", json);
+
+ if (key_len_out)
+ *key_len_out = key_len;
+
+ if (hashtable_get(parents, key, key_len))
return -1;
- return hashtable_set(parents, key, json_null());
+ return hashtable_set(parents, key, key_len, json_null());
}
/*** object ***/
@@ -93,16 +97,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);
+ 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)
@@ -114,7 +134,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, value)) {
+ if (hashtable_set(&object->hashtable, key, key_len, value)) {
json_decref(value);
return -1;
}
@@ -123,22 +143,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);
+ return hashtable_del(&object->hashtable, key, key_len);
}
int json_object_clear(json_t *json) {
@@ -170,14 +206,15 @@ int json_object_update(json_t *object, json_t *other) {
int json_object_update_existing(json_t *object, json_t *other) {
const char *key;
+ size_t key_len;
json_t *value;
if (!json_is_object(object) || !json_is_object(other))
return -1;
- json_object_foreach(other, key, value) {
- if (json_object_get(object, key))
- json_object_set_nocheck(object, key, value);
+ json_object_keylen_foreach(other, key, key_len, value) {
+ if (json_object_getn(object, key, key_len))
+ json_object_setn_nocheck(object, key, key_len, value);
}
return 0;
@@ -200,17 +237,19 @@ int json_object_update_missing(json_t *object, json_t *other) {
int do_object_update_recursive(json_t *object, json_t *other, hashtable_t *parents) {
const char *key;
+ size_t key_len;
json_t *value;
char loop_key[LOOP_KEY_LEN];
int res = 0;
+ size_t loop_key_len;
if (!json_is_object(object) || !json_is_object(other))
return -1;
- if (jsonp_loop_check(parents, other, loop_key, sizeof(loop_key)))
+ if (jsonp_loop_check(parents, other, loop_key, sizeof(loop_key), &loop_key_len))
return -1;
- json_object_foreach(other, key, value) {
+ json_object_keylen_foreach(other, key, key_len, value) {
json_t *v = json_object_get(object, key);
if (json_is_object(v) && json_is_object(value)) {
@@ -219,14 +258,14 @@ int do_object_update_recursive(json_t *object, json_t *other, hashtable_t *paren
break;
}
} else {
- if (json_object_set_nocheck(object, key, value)) {
+ if (json_object_setn_nocheck(object, key, key_len, value)) {
res = -1;
break;
}
}
}
- hashtable_del(parents, loop_key);
+ hashtable_del(parents, loop_key, loop_key_len);
return res;
}
@@ -260,7 +299,7 @@ void *json_object_iter_at(json_t *json, const char *key) {
return NULL;
object = json_to_object(json);
- return hashtable_iter_at(&object->hashtable, key);
+ return hashtable_iter_at(&object->hashtable, key, strlen(key));
}
void *json_object_iter_next(json_t *json, void *iter) {
@@ -280,6 +319,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;
@@ -340,8 +386,9 @@ static json_t *json_object_deep_copy(const json_t *object, hashtable_t *parents)
json_t *result;
void *iter;
char loop_key[LOOP_KEY_LEN];
+ size_t loop_key_len;
- if (jsonp_loop_check(parents, object, loop_key, sizeof(loop_key)))
+ if (jsonp_loop_check(parents, object, loop_key, sizeof(loop_key), &loop_key_len))
return NULL;
result = json_object();
@@ -366,7 +413,7 @@ static json_t *json_object_deep_copy(const json_t *object, hashtable_t *parents)
}
out:
- hashtable_del(parents, loop_key);
+ hashtable_del(parents, loop_key, loop_key_len);
return result;
}
@@ -633,8 +680,9 @@ static json_t *json_array_deep_copy(const json_t *array, hashtable_t *parents) {
json_t *result;
size_t i;
char loop_key[LOOP_KEY_LEN];
+ size_t loop_key_len;
- if (jsonp_loop_check(parents, array, loop_key, sizeof(loop_key)))
+ if (jsonp_loop_check(parents, array, loop_key, sizeof(loop_key), &loop_key_len))
return NULL;
result = json_array();
@@ -651,7 +699,7 @@ static json_t *json_array_deep_copy(const json_t *array, hashtable_t *parents) {
}
out:
- hashtable_del(parents, loop_key);
+ hashtable_del(parents, loop_key, loop_key_len);
return result;
}