diff --git a/json_object.h b/json_object.h index 70ebcef..bc08554 100644 --- a/json_object.h +++ b/json_object.h @@ -632,14 +632,61 @@ JSON_EXPORT int json_object_object_del_key(struct json_object *obj, const struct * new value IS allowed. * * @param obj the json_object instance - * @param key the local name for the char* key variable defined in the body - * @param val the local name for the json_object* object variable defined in + * @param key the local name for the `char *` key variable defined in the body + * @param val the local name for the `json_object *` object variable defined in * the body */ #if defined(__GNUC__) && !defined(__STRICT_ANSI__) && \ (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) -#define json_object_object_foreach(obj, key, val) \ +#define json_object_object_foreach(obj, key, val) \ + const char *key = NULL; \ + struct json_object *val __attribute__((__unused__)) = NULL; \ + for (struct lh_entry *entry##key = json_object_get_object(obj)->head, \ + *entry_next##key = NULL; \ + ({ \ + if (entry##key) \ + { \ + key = json_key_data((struct json_key *)lh_entry_k(entry##key)); \ + val = (struct json_object *)lh_entry_v(entry##key); \ + entry_next##key = entry##key->next; \ + }; \ + entry##key; \ + }); \ + entry##key = entry_next##key) + +#else /* ANSI C or MSC */ + +#define json_object_object_foreach(obj, key, val) \ + const char *key = NULL; \ + struct json_object *val = NULL; \ + struct lh_entry *entry##key; \ + struct lh_entry *entry_next##key = NULL; \ + for (entry##key = json_object_get_object(obj)->head; \ + (entry##key ? (key = json_key_data((struct json_key *)lh_entry_k(entry##key)), \ + val = (struct json_object *)lh_entry_v(entry##key), \ + entry_next##key = entry##key->next, entry##key) \ + : 0); \ + entry##key = entry_next##key) + +#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) */ +/** + * @brief Iterate through all keys and values of an object. + * + * Adding keys to the object while iterating is NOT allowed. + * + * Deleting an existing key, or replacing an existing key with a + * new value IS allowed. + * + * @param obj the json_object instance + * @param key the local name for the `struct json_key *` key variable defined in the body + * @param val the local name for the `json_object *` object variable defined in + * the body + */ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && \ + (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) + +#define json_object_object_foreach_len(obj, key, val) \ struct json_key *key = NULL; \ struct json_object *val __attribute__((__unused__)) = NULL; \ for (struct lh_entry *entry##key = json_object_get_object(obj)->head, \ @@ -657,7 +704,7 @@ JSON_EXPORT int json_object_object_del_key(struct json_object *obj, const struct #else /* ANSI C or MSC */ -#define json_object_object_foreach(obj, key, val) \ +#define json_object_object_foreach_len(obj, key, val) \ struct json_key *key = NULL; \ struct json_object *val = NULL; \ struct lh_entry *entry##key; \ diff --git a/json_visit.c b/json_visit.c index 63dc797..41d0a47 100644 --- a/json_visit.c +++ b/json_visit.c @@ -57,7 +57,7 @@ static int _json_c_visit(json_object *jso, json_object *parent_jso, const struct case json_type_object: { - json_object_object_foreach(jso, key, child) + json_object_object_foreach_len(jso, key, child) { userret = _json_c_visit(child, jso, key, NULL, userfunc, userarg); if (userret == JSON_C_VISIT_RETURN_POP) diff --git a/tests/test1.c b/tests/test1.c index f061961..66f5709 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -304,7 +304,7 @@ int main(int argc, char **argv) /*json_object_object_add(my_object, "arr", my_array);*/ printf("my_object=\n"); - json_object_object_foreach(my_object, key, val) + json_object_object_foreach_len(my_object, key, val) { putchar('\t'); fwrite(json_key_data(key), json_key_size(key), 1, stdout); diff --git a/tests/testReplaceExisting.c b/tests/testReplaceExisting.c index 70369d3..7e05d80 100644 --- a/tests/testReplaceExisting.c +++ b/tests/testReplaceExisting.c @@ -24,11 +24,10 @@ int main(int argc, char **argv) int orig_count = 0; json_object_object_foreach(my_object, key0, val0) { - printf("Key at index %d is [%s] %d", orig_count, json_key_data(key0), - (val0 == NULL)); - if (strcmp(json_key_data(key0), "deleteme") == 0) + printf("Key at index %d is [%s] %d", orig_count, key0, (val0 == NULL)); + if (strcmp(key0, "deleteme") == 0) { - json_object_object_del(my_object, json_key_data(key0)); + json_object_object_del(my_object, key0); printf(" (deleted)\n"); } else @@ -40,7 +39,7 @@ int main(int argc, char **argv) const struct json_key *original_key = NULL; orig_count = 0; - json_object_object_foreach(my_object, key, val) + json_object_object_foreach_len(my_object, key, val) { printf("Key at index %d is [%s] %d\n", orig_count, json_key_data(key), (val == NULL)); @@ -49,7 +48,7 @@ int main(int argc, char **argv) continue; printf("replacing value for key [%s]\n", json_key_data(key)); original_key = key; - json_object_object_add(my_object, json_key_data(key0), + json_object_object_add(my_object, json_key_data(key), json_object_new_string("zzz")); } @@ -57,7 +56,7 @@ int main(int argc, char **argv) int new_count = 0; int retval = 0; - json_object_object_foreach(my_object, key2, val2) + json_object_object_foreach_len(my_object, key2, val2) { printf("Key at index %d is [%s] %d\n", new_count, json_key_data(key2), (val2 == NULL)); diff --git a/tests/test_null_keys_add.c b/tests/test_null_keys_add.c index 51a21d8..06debb2 100644 --- a/tests/test_null_keys_add.c +++ b/tests/test_null_keys_add.c @@ -111,7 +111,7 @@ int main(void) printf("Have three keys, but don't have the right value in \"%s\" (error!)\n", toadd_key_printable); printf("Keys :\n"); - json_object_object_foreach(parsed, key, val) + json_object_object_foreach_len(parsed, key, val) { putchar('\"'); fwrite(json_key_data(key), json_key_size(key), 1, stdout);