summaryrefslogtreecommitdiff
path: root/json/apr_json.c
diff options
context:
space:
mode:
authorGraham Leggett <minfrin@apache.org>2018-08-31 09:24:04 +0000
committerGraham Leggett <minfrin@apache.org>2018-08-31 09:24:04 +0000
commit719b2402ac7cf476e71a96779273067278372895 (patch)
tree6dab73d3d4304233d9073577306add95d3888959 /json/apr_json.c
parent1efbb3f540509c6c72654254a491303af6f43449 (diff)
downloadapr-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.c81
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)