summaryrefslogtreecommitdiff
path: root/json
diff options
context:
space:
mode:
authorGraham Leggett <minfrin@apache.org>2018-08-03 16:29:59 +0000
committerGraham Leggett <minfrin@apache.org>2018-08-03 16:29:59 +0000
commiteef861372d3a97677ba51bd2cb690f2eebe62621 (patch)
treec7aee6f718349d10e9d89cf66f367a5cb2714354 /json
parent576f576b525477d154ee8369a60d7de2e31b0c71 (diff)
downloadapr-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.c56
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;
+}