Apache Portable Runtime
apr_json.h
Go to the documentation of this file.
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements. See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 /**
17  * @file apr_json.h
18  * @brief APR-UTIL JSON Library
19  */
20 #ifndef APR_JSON_H
21 #define APR_JSON_H
22 
23 /**
24  * @defgroup APR_Util_JSON JSON Encoding and Decoding
25  * @ingroup APR_Util
26  * @{
27  */
28 #include "apr.h"
29 #include "apr_pools.h"
30 #include "apr_tables.h"
31 #include "apr_hash.h"
32 #include "apr_strings.h"
33 #include "apr_buckets.h"
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 /**
40  * @package Apache JSON library
41  *
42  * RFC8259 compliant JSON encoding and decoding library.
43  *
44  * https://tools.ietf.org/html/rfc8259
45  *
46  * This API generates UTF-8 encoded JSON, and writes it to the
47  * bucket brigade specified. All strings are verified as valid UTF-8
48  * before processing, with invalid UTF-8 characters replaced.
49  *
50  * This API parses UTF-8 encoded JSON, and returns the result as
51  * a set of structures. All JSON strings are unescaped. Any bad
52  * characters or formatting will cause parsing to be terminated
53  * and an error returned, along with the offset of the error.
54  *
55  * Whitespace may be optionally preserved or ignored as required
56  * during generation and parsing.
57  *
58  * The ordering of object keys is preserved, allowing the decode and
59  * encode process to reproduce an identical result. This maintains
60  * stable behaviour during unit tests.
61  */
62 
63 /**
64  * When passing a string to one of the encode functions, this value can be
65  * passed to indicate a string-valued key, and have the length computed
66  * automatically.
67  */
68 #define APR_JSON_VALUE_STRING (-1)
69 
70 /**
71  * Flag indicating no special processing.
72  */
73 #define APR_JSON_FLAGS_NONE 0
74 
75 /**
76  * Flag indicating include whitespace.
77  */
78 #define APR_JSON_FLAGS_WHITESPACE 1
79 
80 /**
81  * Flag indicating strict overlay.
82  */
83 #define APR_JSON_FLAGS_STRICT 2
84 
85 /**
86  * A structure to hold a JSON object.
87  */
89 
90 /**
91  * A structure to hold a JSON array.
92  */
93 typedef struct apr_json_array_t apr_json_array_t;
94 
95 /**
96  * Enum that represents the type of the given JSON value.
97  */
98 typedef enum apr_json_type_e {
99  APR_JSON_OBJECT,
100  APR_JSON_ARRAY,
101  APR_JSON_STRING,
102  APR_JSON_LONG,
103  APR_JSON_DOUBLE,
104  APR_JSON_BOOLEAN,
105  APR_JSON_NULL
107 
108 /**
109  * A structure to hold a UTF-8 encoded JSON string.
110  */
111 typedef struct apr_json_string_t {
112  /** pointer to the string */
113  const char *p;
114  /** string length, or APR_JSON_VALUE_STRING to compute length automatically */
115  apr_ssize_t len;
117 
118 /**
119  * A structure that holds a JSON value.
120  *
121  * Use apr_json_value_create() to allocate.
122  */
123 typedef struct apr_json_value_t {
124  /** Links to the rest of the values if in an array */
126  /** preceding whitespace, if any */
127  const char *pre;
128  /** trailing whitespace, if any */
129  const char *post;
130  /** type of the value */
132  /** actual value. which member is valid depends on type. */
133  union {
134  /** JSON object */
136  /** JSON array */
138  /** JSON floating point value */
139  double dnumber;
140  /** JSON long integer value */
141  apr_int64_t lnumber;
142  /** JSON UTF-8 encoded string value */
144  /** JSON boolean value */
145  int boolean;
146  } value;
148 
149 /**
150  * A structure to hold a JSON object key value pair.
151  *
152  * Use apr_json_object_set() to allocate.
153  */
154 typedef struct apr_json_kv_t {
155  /** Links to the rest of the kv pairs */
157  /** the key */
159  /** the value */
162 
163 /**
164  * A structure to hold a JSON object.
165  *
166  * Use apr_json_object_create() to allocate.
167  */
169  /** The key value pairs in the object are in this list */
170  APR_RING_HEAD(apr_json_object_list_t, apr_json_kv_t) list;
171  /** JSON object */
173 };
174 
175 /**
176  * A structure to hold a JSON array.
177  *
178  * Use apr_json_array_create() to allocate.
179  */
181  /** The key value pairs in the object are in this list */
182  APR_RING_HEAD(apr_json_array_list_t, apr_json_value_t) list;
183  /** Array of JSON objects */
185 };
186 
187 /**
188  * Allocate and return a apr_json_value_t structure.
189  *
190  * @param pool The pool to allocate from.
191  * @return The apr_json_value_t structure.
192  */
194  __attribute__((nonnull(1)));
195 
196 /**
197  * Allocate and return a JSON string with the given value.
198  *
199  * @param pool The pool to allocate from.
200  * @param val The UTF-8 encoded string value.
201  * @param len The length of the string, or APR_JSON_VALUE_STRING.
202  * @return The apr_json_value_t structure.
203  */
205  apr_json_string_create(apr_pool_t *pool, const char *val,
206  apr_ssize_t len) __attribute__((nonnull(1)));
207 
208 /**
209  * Allocate and return a JSON array.
210  *
211  * @param pool The pool to allocate from.
212  * @param nelts the number of elements in the initial array
213  * @return The apr_json_value_t structure.
214  */
217  __attribute__((nonnull(1)));
218 
219 /**
220  * Allocate and return a JSON object.
221  *
222  * @param pool The pool to allocate from.
223  * @return The apr_json_value_t structure.
224  */
226  __attribute__((nonnull(1)));
227 
228 /**
229  * Allocate and return a JSON long.
230  *
231  * @param pool The pool to allocate from.
232  * @param lnumber The long value.
233  * @return The apr_json_value_t structure.
234  */
236  apr_json_long_create(apr_pool_t *pool, apr_int64_t lnumber)
237  __attribute__((nonnull(1)));
238 
239 /**
240  * Allocate and return a JSON double.
241  *
242  * @param pool The pool to allocate from.
243  * @param dnumber The double value.
244  * @return The apr_json_value_t structure.
245  */
247  apr_json_double_create(apr_pool_t *pool, double dnumber)
248  __attribute__((nonnull(1)));
249 
250 /**
251  * Allocate and return a JSON boolean.
252  *
253  * @param pool The pool to allocate from.
254  * @param boolean The boolean value.
255  * @return The apr_json_value_t structure.
256  */
259  __attribute__((nonnull(1)));
260 
261 /**
262  * Allocate and return a JSON null.
263  *
264  * @param pool The pool to allocate from.
265  * @return The apr_json_value_t structure.
266  */
269  __attribute__((nonnull(1)));
270 
271 /**
272  * Associate a value with a key in a JSON object.
273  * @param obj The JSON object.
274  * @param key Pointer to the key string.
275  * @param klen Length of the key, or APR_JSON_VALUE_STRING if NUL
276  * terminated.
277  * @param val Value to associate with the key.
278  * @param pool Pool to use.
279  * @return APR_SUCCESS on success, APR_EINVAL if the key is
280  * NULL or not a string, or the object is not an APR_JSON_OBJECT.
281  * @remark If the value is NULL the key value pair is deleted.
282  */
284  const char *key, apr_ssize_t klen, apr_json_value_t *val,
285  apr_pool_t *pool) __attribute__((nonnull(1, 2, 5)));
286 
287 /**
288  * Associate a value with a key in a JSON object, preserving whitespace.
289  * @param obj The JSON object.
290  * @param key Pointer to the key string, including any whitespace
291  * required.
292  * @param val Value to associate with the key.
293  * @param pool Pool to use.
294  * @return APR_SUCCESS on success, APR_EINVAL if the key is
295  * NULL or not a string, or the object is not an APR_JSON_OBJECT.
296  * @remark If the value is NULL the key value pair is deleted.
297  */
300  apr_pool_t *pool) __attribute__((nonnull(1, 2, 4)));
301 
302 /**
303  * Look up the value associated with a key in a JSON object.
304  * @param obj The JSON object.
305  * @param key Pointer to the key.
306  * @param klen Length of the key, or APR_JSON_VALUE_STRING if NUL
307  * terminated.
308  * @return Returns NULL if the key is not present.
309  */
311  apr_json_object_get(apr_json_value_t *obj, const char *key,
312  apr_ssize_t klen)
313  __attribute__((nonnull(1, 2)));
314 
315 /**
316  * Get the first value associated with an object.
317  *
318  * If the value is an object, this function returns the first key value pair.
319  * @param obj The JSON object.
320  * @return Returns the first value, or NULL if not an object, or the object is
321  * empty.
322  */
324  __attribute__((nonnull(1)));;
325 
326 /**
327  * Get the next value associated with an object.
328  *
329  * This function returns the next key value pair, or NULL if no more pairs
330  * are present.
331  * @param obj The JSON object.
332  * @param kv The previous JSON key value pair.
333  * @return Returns the next key value pair, or NULL if not an object, or
334  * the object is empty.
335  */
337  apr_json_kv_t *kv)
338  __attribute__((nonnull(1, 2)));;
339 
340 /**
341  * Add the value to the end of this array.
342  * @param arr The JSON array.
343  * @param val Value to add to the array.
344  * @return APR_SUCCESS on success, APR_EINVAL if the array value is not
345  * an APR_JSON_ARRAY.
346  */
348  apr_json_value_t *val)
349  __attribute__((nonnull(1, 2)));
350 
351 /**
352  * Look up the value associated with a key in a JSON object.
353  * @param arr The JSON array.
354  * @param index The index of the element in the array.
355  * @return Returns NULL if the element is out of bounds.
356  */
359  __attribute__((nonnull(1)));
360 
361 /**
362  * Get the first value associated with an array.
363  *
364  * If the value is an array, this function returns the first value.
365  * @param arr The JSON array.
366  * @return Returns the first value, or NULL if not an array, or the array is
367  * empty.
368  */
370  __attribute__((nonnull(1)));;
371 
372 /**
373  * Get the next value associated with an array.
374  *
375  * This function returns the next value in the array, or NULL if no more
376  * values are present.
377  * @param arr The JSON array.
378  * @param val The previous element of the array.
379  * @return Returns the next value in the array, or NULL if not an array, or
380  * we have reached the end of the array.
381  */
383  const apr_json_value_t *val)
384  __attribute__((nonnull(1, 2)));;
385 
386 /**
387  * Decode utf8-encoded JSON string into apr_json_value_t.
388  * @param retval the result
389  * @param injson utf8-encoded JSON string.
390  * @param size length of the input string.
391  * @param offset number of characters processed.
392  * @param flags set to APR_JSON_FLAGS_WHITESPACE to preserve whitespace,
393  * or APR_JSON_FLAGS_NONE to filter whitespace.
394  * @param level maximum nesting level we are prepared to decode.
395  * @param pool pool used to allocate the result from.
396  * @return APR_SUCCESS on success, APR_EOF if the JSON text is truncated.
397  * APR_BADCH when a decoding error has occurred (the location of the error
398  * is at offset), APR_EINVAL if the level has been exceeded, or
399  * APR_ENOTIMPL on platforms where not implemented.
400  */
402  const char *injson, apr_ssize_t size, apr_off_t * offset,
403  int flags, int level, apr_pool_t * pool)
404  __attribute__((nonnull(1, 2, 7)));
405 
406 /**
407  * Encode data represented as apr_json_value_t to utf8-encoded JSON string
408  * and append it to the specified brigade.
409  *
410  * All JSON strings are checked for invalid UTF-8 character sequences,
411  * and if found invalid sequences are replaced with the replacement
412  * character "�" (U+FFFD).
413  *
414  * @param brigade brigade the result will be appended to.
415  * @param flush optional flush function for the brigade. Can be NULL.
416  * @param ctx optional contaxt for the flush function. Can be NULL.
417  * @param json the JSON data.
418  * @param flags set to APR_JSON_FLAGS_WHITESPACE to preserve whitespace,
419  * or APR_JSON_FLAGS_NONE to filter whitespace.
420  * @param pool pool used to allocate the buckets from.
421  * @return APR_SUCCESS on success, or APR_ENOTIMPL on platforms where not
422  * implemented.
423  */
425  apr_brigade_flush flush, void *ctx, const apr_json_value_t * json,
426  int flags, apr_pool_t * pool) __attribute__((nonnull(1, 4, 6)));
427 
428 /**
429  * Overlay one JSON value over a second JSON value.
430  *
431  * If the values are objects, a new object will be returned containing
432  * all keys from the overlay superimposed on the base.
433  *
434  * Keys that appear in the overlay will replace keys in the base, unless
435  * APR_JSON_FLAGS_STRICT is specified, in which case NULL will be returned.
436  *
437  * If either the base or the overlay are not objects, overlay will be
438  * returned.
439  * @param p pool to use
440  * @param overlay the JSON object to overlay on top of base. If NULL, the
441  * base will be returned.
442  * @param base the base JSON object. If NULL, the overlay will be returned.
443  * @param flags set to APR_JSON_FLAGS_STRICT to fail if object keys are not
444  * unique, or APR_JSON_FLAGS_NONE to replace keys in base with overlay.
445  * @return A new object containing the result. If APR_JSON_FLAGS_STRICT was
446  * specified and a key was present in overlay that was also present in base,
447  * NULL will be returned.
448  */
450  apr_json_value_t *overlay, apr_json_value_t *base,
451  int flags) __attribute__((nonnull(1)));;
452 
453 #ifdef __cplusplus
454 }
455 #endif
456 /** @} */
457 #endif /* APR_JSON_H */
APR Platform Definitions.
APR-UTIL Buckets/Bucket Brigades.
APR Hash Tables.
APR memory allocation.
APR Strings library.
APR Table library.
apr_status_t(* apr_brigade_flush)(apr_bucket_brigade *bb, void *ctx)
Definition: apr_buckets.h:287
struct apr_json_string_t apr_json_string_t
apr_status_t apr_json_encode(apr_bucket_brigade *brigade, apr_brigade_flush flush, void *ctx, const apr_json_value_t *json, int flags, apr_pool_t *pool)
apr_json_value_t * apr_json_boolean_create(apr_pool_t *pool, int boolean)
apr_json_type_e
Definition: apr_json.h:98
apr_json_kv_t * apr_json_object_first(apr_json_value_t *obj)
apr_status_t apr_json_object_set_ex(apr_json_value_t *obj, apr_json_value_t *key, apr_json_value_t *val, apr_pool_t *pool)
apr_json_value_t * apr_json_array_next(const apr_json_value_t *arr, const apr_json_value_t *val)
struct apr_json_value_t apr_json_value_t
apr_json_value_t * apr_json_long_create(apr_pool_t *pool, apr_int64_t lnumber)
apr_json_value_t * apr_json_value_create(apr_pool_t *pool)
apr_json_value_t * apr_json_array_first(const apr_json_value_t *arr)
apr_json_kv_t * apr_json_object_get(apr_json_value_t *obj, const char *key, apr_ssize_t klen)
apr_json_value_t * apr_json_double_create(apr_pool_t *pool, double dnumber)
apr_json_value_t * apr_json_object_create(apr_pool_t *pool)
apr_status_t apr_json_decode(apr_json_value_t **retval, const char *injson, apr_ssize_t size, apr_off_t *offset, int flags, int level, apr_pool_t *pool)
apr_json_kv_t * apr_json_object_next(apr_json_value_t *obj, apr_json_kv_t *kv)
apr_json_value_t * apr_json_null_create(apr_pool_t *pool)
apr_status_t apr_json_array_add(apr_json_value_t *arr, apr_json_value_t *val)
apr_status_t apr_json_object_set(apr_json_value_t *obj, const char *key, apr_ssize_t klen, apr_json_value_t *val, apr_pool_t *pool)
apr_json_value_t * apr_json_string_create(apr_pool_t *pool, const char *val, apr_ssize_t len)
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 * apr_json_array_get(apr_json_value_t *arr, int index)
apr_json_value_t * apr_json_array_create(apr_pool_t *pool, int nelts)
struct apr_json_kv_t apr_json_kv_t
int apr_status_t
Definition: apr_errno.h:44
struct apr_hash_t apr_hash_t
Definition: apr_hash.h:52
#define APR_DECLARE(type)
Definition: apr.h:516
struct apr_pool_t apr_pool_t
Definition: apr_pools.h:60
Definition: apr_tables.h:62
Definition: apr_buckets.h:263
Definition: apr_json.h:180
APR_RING_HEAD(apr_json_array_list_t, apr_json_value_t) list
apr_array_header_t * array
Definition: apr_json.h:184
Definition: apr_json.h:154
apr_json_value_t * v
Definition: apr_json.h:160
apr_json_value_t * k
Definition: apr_json.h:158
APR_RING_ENTRY(apr_json_kv_t) link
Definition: apr_json.h:168
apr_hash_t * hash
Definition: apr_json.h:172
APR_RING_HEAD(apr_json_object_list_t, apr_json_kv_t) list
Definition: apr_json.h:111
apr_ssize_t len
Definition: apr_json.h:115
const char * p
Definition: apr_json.h:113
Definition: apr_json.h:123
apr_json_type_e type
Definition: apr_json.h:131
const char * post
Definition: apr_json.h:129
apr_json_string_t string
Definition: apr_json.h:143
apr_json_object_t * object
Definition: apr_json.h:135
APR_RING_ENTRY(apr_json_value_t) link
union apr_json_value_t::@5 value
apr_int64_t lnumber
Definition: apr_json.h:141
int boolean
Definition: apr_json.h:145
apr_json_array_t * array
Definition: apr_json.h:137
double dnumber
Definition: apr_json.h:139
const char * pre
Definition: apr_json.h:127