diff options
author | Graham Leggett <minfrin@apache.org> | 2018-08-31 09:24:04 +0000 |
---|---|---|
committer | Graham Leggett <minfrin@apache.org> | 2018-08-31 09:24:04 +0000 |
commit | 719b2402ac7cf476e71a96779273067278372895 (patch) | |
tree | 6dab73d3d4304233d9073577306add95d3888959 /json/apr_json.c | |
parent | 1efbb3f540509c6c72654254a491303af6f43449 (diff) | |
download | apr-719b2402ac7cf476e71a96779273067278372895.tar.gz |
Make it possible to iterate through JSON arrays as well as JSON objects.
As a side effect, this removes the need for the temporary pool
during JSON decoding.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1839735 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'json/apr_json.c')
-rw-r--r-- | json/apr_json.c | 81 |
1 files changed, 78 insertions, 3 deletions
diff --git a/json/apr_json.c b/json/apr_json.c index 8a4c91d60..b8b55fc9a 100644 --- a/json/apr_json.c +++ b/json/apr_json.c @@ -25,6 +25,12 @@ APR_RING_CHECK_CONSISTENCY(&(o)->list, apr_json_kv_t, link); \ } while (0) +#define APR_JSON_ARRAY_INSERT_TAIL(o, e) do { \ + apr_json_value_t *ap__b = (e); \ + APR_RING_INSERT_TAIL(&(o)->list, ap__b, apr_json_value_t, link); \ + APR_RING_CHECK_CONSISTENCY(&(o)->list, apr_json_value_t, link); \ + } while (0) + apr_json_value_t *apr_json_value_create(apr_pool_t *pool) { return apr_pcalloc(pool, sizeof(apr_json_value_t)); @@ -67,7 +73,9 @@ apr_json_value_t *apr_json_array_create(apr_pool_t *pool, int nelts) if (json) { json->type = APR_JSON_ARRAY; - json->value.array = apr_array_make(pool, nelts, + json->value.array = apr_pcalloc(pool, sizeof(apr_json_array_t)); + APR_RING_INIT(&json->value.array->list, apr_json_value_t, link); + json->value.array->array = apr_array_make(pool, nelts, sizeof(apr_json_value_t *)); } @@ -159,8 +167,7 @@ apr_status_t apr_json_object_set(apr_json_value_t *object, apr_json_value_t *key return APR_SUCCESS; } -apr_json_kv_t *apr_json_object_get(apr_json_value_t *object, const char *key, - apr_ssize_t klen) +apr_json_kv_t *apr_json_object_get(apr_json_value_t *object, const char *key, apr_ssize_t klen) { if (object->type != APR_JSON_OBJECT) { return NULL; @@ -205,6 +212,74 @@ apr_json_kv_t *apr_json_object_next(apr_json_value_t *obj, apr_json_kv_t *kv) } } +apr_status_t apr_json_array_add(apr_json_value_t *arr, + apr_json_value_t *val, apr_pool_t *pool) +{ + apr_array_header_t *array; + + if (arr->type != APR_JSON_ARRAY) { + return APR_EINVAL; + } + + APR_RING_ELEM_INIT(val, link); + APR_JSON_ARRAY_INSERT_TAIL(arr->value.array, val); + + array = arr->value.array->array; + if (array) { + *((apr_json_value_t **) (apr_array_push(array))) = val; + } + + return APR_SUCCESS; +} + +apr_json_value_t *apr_json_array_get(apr_json_value_t *arr, int index) +{ + if (arr->type != APR_JSON_ARRAY) { + return NULL; + } + + return APR_ARRAY_IDX(arr->value.array->array, index, apr_json_value_t *); +} + +apr_json_value_t *apr_json_array_first(const apr_json_value_t *arr) +{ + apr_json_value_t *val; + + if (arr->type != APR_JSON_ARRAY) { + return NULL; + } + + val = APR_RING_FIRST(&(arr->value.array)->list); + + if (val + != APR_RING_SENTINEL(&(arr->value.object)->list, apr_json_value_t, + link)) { + return val; + } else { + return NULL; + } +} + +apr_json_value_t *apr_json_array_next(const apr_json_value_t *arr, + const apr_json_value_t *val) +{ + apr_json_value_t *next; + + if (arr->type != APR_JSON_ARRAY) { + return NULL; + } + + next = APR_RING_NEXT((val), link); + + if (next + != APR_RING_SENTINEL(&(arr->value.array)->list, apr_json_value_t, + link)) { + return next; + } else { + return NULL; + } +} + apr_json_value_t *apr_json_overlay(apr_pool_t *p, apr_json_value_t *overlay, apr_json_value_t *base, int flags) |