krb5 commit: Clarify and improve k5_json_object_set
Greg Hudson
ghudson at MIT.EDU
Wed Jul 17 12:24:20 EDT 2013
https://github.com/krb5/krb5/commit/ea29df4d93b1b7b384c15f39a4ee20be3e0991ac
commit ea29df4d93b1b7b384c15f39a4ee20be3e0991ac
Author: Greg Hudson <ghudson at mit.edu>
Date: Tue Jul 16 18:09:55 2013 -0400
Clarify and improve k5_json_object_set
Document that k5_json_object_set can be used to overwrite an existing
key, and make it possible to remove a key by setting it to NULL.
src/include/k5-json.h | 6 +++++-
src/util/support/json.c | 19 ++++++++++++++++---
src/util/support/t_json.c | 9 +++++++++
3 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/src/include/k5-json.h b/src/include/k5-json.h
index b01b8b8..8b22cd3 100644
--- a/src/include/k5-json.h
+++ b/src/include/k5-json.h
@@ -168,7 +168,11 @@ void k5_json_object_iterate(k5_json_object obj,
/* Return the number of mappings in an object. */
size_t k5_json_object_count(k5_json_object obj);
-/* Store val into object at key, incrementing val's reference count. */
+/*
+ * Store val into object at key, incrementing val's reference count and
+ * releasing any previous value at key. If val is NULL, key is removed from
+ * obj if it exists, and obj remains unchanged if it does not.
+ */
int k5_json_object_set(k5_json_object obj, const char *key, k5_json_value val);
/* Get an alias to the object's value for key, without incrementing the
diff --git a/src/util/support/json.c b/src/util/support/json.c
index b2dd133..b99fabd 100644
--- a/src/util/support/json.c
+++ b/src/util/support/json.c
@@ -429,15 +429,28 @@ int
k5_json_object_set(k5_json_object obj, const char *key, k5_json_value val)
{
struct entry *ent, *ptr;
- size_t new_alloc;
+ size_t new_alloc, i;
ent = object_search(obj, key);
- if (ent) {
+ if (ent != NULL) {
k5_json_release(ent->value);
- ent->value = k5_json_retain(val);
+ if (val == NULL) {
+ /* Remove this key. */
+ free(ent->key);
+ for (i = ent - obj->entries; i < obj->len - 1; i++)
+ obj->entries[i] = obj->entries[i + 1];
+ obj->len--;
+ } else {
+ /* Overwrite this key's value with the new one. */
+ ent->value = k5_json_retain(val);
+ }
return 0;
}
+ /* If didn't find a key the caller asked to remove, do nothing. */
+ if (val == NULL)
+ return 0;
+
if (obj->len >= obj->allocated) {
/* Increase the number of slots by 50% (16 slots minimum). */
new_alloc = obj->len + 1 + (obj->len >> 1);
diff --git a/src/util/support/t_json.c b/src/util/support/t_json.c
index 040a85a..1f22924 100644
--- a/src/util/support/t_json.c
+++ b/src/util/support/t_json.c
@@ -165,6 +165,15 @@ test_object(void)
if (strcmp(k5_json_string_utf8(s), "hejsan") != 0)
err("Retrieving key2 from object failed");
+ check(k5_json_object_get(object, "key3") == NULL,
+ "object nonexistent key");
+
+ k5_json_object_set(object, "key1", NULL);
+ check(k5_json_object_get(object, "key1") == NULL,
+ "object removed key");
+ check(k5_json_object_get(object, "key2") != NULL,
+ "object remaining key");
+
k5_json_release(v1);
k5_json_release(v2);
k5_json_release(object);
More information about the cvs-krb5
mailing list