diff options
author | Graham Leggett <minfrin@apache.org> | 2018-08-03 16:29:59 +0000 |
---|---|---|
committer | Graham Leggett <minfrin@apache.org> | 2018-08-03 16:29:59 +0000 |
commit | eef861372d3a97677ba51bd2cb690f2eebe62621 (patch) | |
tree | c7aee6f718349d10e9d89cf66f367a5cb2714354 /json | |
parent | 576f576b525477d154ee8369a60d7de2e31b0c71 (diff) | |
download | apr-eef861372d3a97677ba51bd2cb690f2eebe62621.tar.gz |
Add the ability to overlay one JSON object over another.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1837383 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'json')
-rw-r--r-- | json/apr_json.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/json/apr_json.c b/json/apr_json.c index b035c435f..4d671d1cd 100644 --- a/json/apr_json.c +++ b/json/apr_json.c @@ -167,3 +167,59 @@ apr_json_kv_t *apr_json_object_get(apr_json_value_t *object, const char *key) return apr_hash_get(object->value.object->hash, key, APR_HASH_KEY_STRING); } + +apr_json_value_t *apr_json_overlay(apr_pool_t *p, + apr_json_value_t *overlay, apr_json_value_t *base, + int flags) +{ + apr_json_value_t *res; + apr_json_kv_t *kv; + int oc, bc; + + if (!base || base->type != APR_JSON_OBJECT) { + return overlay; + } + if (!overlay) { + return base; + } + if (overlay->type != APR_JSON_OBJECT) { + return overlay; + } + + oc = apr_hash_count(overlay->value.object->hash); + if (!oc) { + return base; + } + bc = apr_hash_count(base->value.object->hash); + if (!bc) { + return overlay; + } + + res = apr_json_object_create(p); + + for (kv = APR_RING_FIRST(&(base->value.object)->list); + kv != APR_RING_SENTINEL(&(base->value.object)->list, apr_json_kv_t, link); + kv = APR_RING_NEXT((kv), link)) { + + if (!apr_hash_get(overlay->value.object->hash, kv->k->value.string.p, + kv->k->value.string.len)) { + + apr_json_object_set(res, kv->k, kv->v, p); + + } + else if (APR_JSON_FLAGS_STRICT & flags) { + return NULL; + } + + } + + for (kv = APR_RING_FIRST(&(overlay->value.object)->list); + kv != APR_RING_SENTINEL(&(overlay->value.object)->list, apr_json_kv_t, link); + kv = APR_RING_NEXT((kv), link)) { + + apr_json_object_set(res, kv->k, kv->v, p); + + } + + return res; +} |