RaspberrPi project source code
guowenxue
2024-03-12 c5e9e88eb8c6039cd2a4d2b3fdae0b1e3d8aea40
commit | author | age
d6b4a7 1 /*
G 2  * coreJSON v3.2.0
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 /**
26  * @file core_json.h
27  * @brief Include this header file to use coreJSON in your application.
28  */
29
30 #ifndef CORE_JSON_H_
31 #define CORE_JSON_H_
32
33 #include <stdbool.h>
34 #include <stddef.h>
35
36 /* *INDENT-OFF* */
37 #ifdef __cplusplus
38     extern "C" {
39 #endif
40 /* *INDENT-ON* */
41
42 /**
43  * @ingroup json_enum_types
44  * @brief Return codes from coreJSON library functions.
45  */
46 typedef enum
47 {
48     JSONPartial = 0,      /**< @brief JSON document is valid so far but incomplete. */
49     JSONSuccess,          /**< @brief JSON document is valid and complete. */
50     JSONIllegalDocument,  /**< @brief JSON document is invalid or malformed. */
51     JSONMaxDepthExceeded, /**< @brief JSON document has nesting that exceeds JSON_MAX_DEPTH. */
52     JSONNotFound,         /**< @brief Query key could not be found in the JSON document. */
53     JSONNullParameter,    /**< @brief Pointer parameter passed to a function is NULL. */
54     JSONBadParameter      /**< @brief Query key is empty, or any subpart is empty, or max is 0. */
55 } JSONStatus_t;
56
57 /**
58  * @brief Parse a buffer to determine if it contains a valid JSON document.
59  *
60  * @param[in] buf  The buffer to parse.
61  * @param[in] max  The size of the buffer.
62  *
63  * @note The maximum nesting depth may be specified by defining the macro
64  * JSON_MAX_DEPTH.  The default is 32 of sizeof(char).
65  *
66  * @note By default, a valid JSON document may contain a single element
67  * (e.g., string, boolean, number).  To require that a valid document
68  * contain an object or array, define JSON_VALIDATE_COLLECTIONS_ONLY.
69  *
70  * @return #JSONSuccess if the buffer contents are valid JSON;
71  * #JSONNullParameter if buf is NULL;
72  * #JSONBadParameter if max is 0;
73  * #JSONIllegalDocument if the buffer contents are NOT valid JSON;
74  * #JSONMaxDepthExceeded if object and array nesting exceeds a threshold;
75  * #JSONPartial if the buffer contents are potentially valid but incomplete.
76  *
77  * <b>Example</b>
78  * @code{c}
79  *     // Variables used in this example.
80  *     JSONStatus_t result;
81  *     char buffer[] = "{\"foo\":\"abc\",\"bar\":{\"foo\":\"xyz\"}}";
82  *     size_t bufferLength = sizeof( buffer ) - 1;
83  *
84  *     result = JSON_Validate( buffer, bufferLength );
85  *
86  *     // JSON document is valid.
87  *     assert( result == JSONSuccess );
88  * @endcode
89  */
90 /* @[declare_json_validate] */
91 JSONStatus_t JSON_Validate( const char * buf,
92                             size_t max );
93 /* @[declare_json_validate] */
94
95 /**
96  * @brief Find a key or array index in a JSON document and output the
97  * pointer @p outValue to its value.
98  *
99  * Any value may also be an object or an array to a maximum depth.  A search
100  * may descend through nested objects or arrays when the query contains matching
101  * key strings or array indexes joined by a separator.
102  *
103  * For example, if the provided buffer contains <code>{"foo":"abc","bar":{"foo":"xyz"}}</code>,
104  * then a search for 'foo' would output <code>abc</code>, 'bar' would output
105  * <code>{"foo":"xyz"}</code>, and a search for 'bar.foo' would output
106  * <code>xyz</code>.
107  *
108  * If the provided buffer contains <code>[123,456,{"foo":"abc","bar":[88,99]}]</code>,
109  * then a search for '[1]' would output <code>456</code>, '[2].foo' would output
110  * <code>abc</code>, and '[2].bar[0]' would output <code>88</code>.
111  *
112  * On success, the pointer @p outValue points to a location in buf.  No null
113  * termination is done for the value.  For valid JSON it is safe to place
114  * a null character at the end of the value, so long as the character
115  * replaced is put back before running another search.
116  *
117  * @param[in] buf  The buffer to search.
118  * @param[in] max  size of the buffer.
119  * @param[in] query  The object keys and array indexes to search for.
120  * @param[in] queryLength  Length of the key.
121  * @param[out] outValue  A pointer to receive the address of the value found.
122  * @param[out] outValueLength  A pointer to receive the length of the value found.
123  *
124  * @note The maximum nesting depth may be specified by defining the macro
125  * JSON_MAX_DEPTH.  The default is 32 of sizeof(char).
126  *
127  * @note JSON_Search() performs validation, but stops upon finding a matching
128  * key and its value. To validate the entire JSON document, use JSON_Validate().
129  *
130  * @return #JSONSuccess if the query is matched and the value output;
131  * #JSONNullParameter if any pointer parameters are NULL;
132  * #JSONBadParameter if the query is empty, or the portion after a separator is empty,
133  * or max is 0, or an index is too large to convert to a signed 32-bit integer;
134  * #JSONNotFound if the query has no match.
135  *
136  * <b>Example</b>
137  * @code{c}
138  *     // Variables used in this example.
139  *     JSONStatus_t result;
140  *     char buffer[] = "{\"foo\":\"abc\",\"bar\":{\"foo\":\"xyz\"}}";
141  *     size_t bufferLength = sizeof( buffer ) - 1;
142  *     char query[] = "bar.foo";
143  *     size_t queryLength = sizeof( query ) - 1;
144  *     char * value;
145  *     size_t valueLength;
146  *
147  *     // Calling JSON_Validate() is not necessary if the document is guaranteed to be valid.
148  *     result = JSON_Validate( buffer, bufferLength );
149  *
150  *     if( result == JSONSuccess )
151  *     {
152  *         result = JSON_Search( buffer, bufferLength, query, queryLength,
153  *                               &value, &valueLength );
154  *     }
155  *
156  *     if( result == JSONSuccess )
157  *     {
158  *         // The pointer "value" will point to a location in the "buffer".
159  *         char save = value[ valueLength ];
160  *         // After saving the character, set it to a null byte for printing.
161  *         value[ valueLength ] = '\0';
162  *         // "Found: bar.foo -> xyz" will be printed.
163  *         printf( "Found: %s -> %s\n", query, value );
164  *         // Restore the original character.
165  *         value[ valueLength ] = save;
166  *     }
167  * @endcode
168  *
169  * @note The maximum index value is ~2 billion ( 2^31 - 9 ).
170  */
171 /* @[declare_json_search] */
172 #define JSON_Search( buf, max, query, queryLength, outValue, outValueLength ) \
173     JSON_SearchT( buf, max, query, queryLength, outValue, outValueLength, NULL )
174 /* @[declare_json_search] */
175
176 /**
177  * @brief The largest value usable as an array index in a query
178  * for JSON_Search(), ~2 billion.
179  */
180 #define MAX_INDEX_VALUE    ( 0x7FFFFFF7 )   /* 2^31 - 9 */
181
182 /**
183  * @ingroup json_enum_types
184  * @brief Value types from the JSON standard.
185  */
186 typedef enum
187 {
188     JSONInvalid = 0, /**< @brief Not a valid JSON type. */
189     JSONString,      /**< @brief A quote delimited sequence of Unicode characters. */
190     JSONNumber,      /**< @brief A rational number. */
191     JSONTrue,        /**< @brief The literal value true. */
192     JSONFalse,       /**< @brief The literal value false. */
193     JSONNull,        /**< @brief The literal value null. */
194     JSONObject,      /**< @brief A collection of zero or more key-value pairs. */
195     JSONArray        /**< @brief A collection of zero or more values. */
196 } JSONTypes_t;
197
198 /**
199  * @brief Same as JSON_Search(), but also outputs a type for the value found
200  *
201  * See @ref JSON_Search for documentation of common behavior.
202  *
203  * @param[in] buf  The buffer to search.
204  * @param[in] max  size of the buffer.
205  * @param[in] query  The object keys and array indexes to search for.
206  * @param[in] queryLength  Length of the key.
207  * @param[out] outValue  A pointer to receive the address of the value found.
208  * @param[out] outValueLength  A pointer to receive the length of the value found.
209  * @param[out] outType  An enum indicating the JSON-specific type of the value.
210  */
211 /* @[declare_json_searcht] */
212 JSONStatus_t JSON_SearchT( char * buf,
213                            size_t max,
214                            const char * query,
215                            size_t queryLength,
216                            char ** outValue,
217                            size_t * outValueLength,
218                            JSONTypes_t * outType );
219 /* @[declare_json_searcht] */
220
221 /**
222  * @brief Same as JSON_SearchT(), but with const qualified buf and outValue arguments.
223  *
224  * See @ref JSON_Search for documentation of common behavior.
225  *
226  * @param[in] buf  The buffer to search.
227  * @param[in] max  size of the buffer.
228  * @param[in] query  The object keys and array indexes to search for.
229  * @param[in] queryLength  Length of the key.
230  * @param[out] outValue  A pointer to receive the address of the value found.
231  * @param[out] outValueLength  A pointer to receive the length of the value found.
232  * @param[out] outType  An enum indicating the JSON-specific type of the value.
233  */
234 /* @[declare_json_searchconst] */
235 JSONStatus_t JSON_SearchConst( const char * buf,
236                                size_t max,
237                                const char * query,
238                                size_t queryLength,
239                                const char ** outValue,
240                                size_t * outValueLength,
241                                JSONTypes_t * outType );
242 /* @[declare_json_searchconst] */
243
244 /**
245  * @ingroup json_struct_types
246  * @brief Structure to represent a key-value pair.
247  */
248 typedef struct
249 {
250     const char * key;     /**< @brief Pointer to the code point sequence for key. */
251     size_t keyLength;     /**< @brief Length of the code point sequence for key. */
252     const char * value;   /**< @brief Pointer to the code point sequence for value. */
253     size_t valueLength;   /**< @brief Length of the code point sequence for value. */
254     JSONTypes_t jsonType; /**< @brief JSON-specific type of the value. */
255 } JSONPair_t;
256
257 /**
258  * @brief Output the next key-value pair or value from a collection.
259  *
260  * This function may be used in a loop to output each key-value pair from an object,
261  * or each value from an array.  For the first invocation, the integers pointed to by
262  * start and next should be initialized to 0.  These will be updated by the function.
263  * If another key-value pair or value is present, the output structure is populated
264  * and #JSONSuccess is returned; otherwise the structure is unchanged and #JSONNotFound
265  * is returned.
266  *
267  * @param[in] buf  The buffer to search.
268  * @param[in] max  size of the buffer.
269  * @param[in,out] start  The index at which the collection begins.
270  * @param[in,out] next  The index at which to seek the next value.
271  * @param[out] outPair  A pointer to receive the next key-value pair.
272  *
273  * @note This function expects a valid JSON document; run JSON_Validate() first.
274  *
275  * @note For an object, the outPair structure will reference a key and its value.
276  * For an array, only the value will be referenced (i.e., outPair.key will be NULL).
277  *
278  * @return #JSONSuccess if a value is output;
279  * #JSONIllegalDocument if the buffer does not contain a collection;
280  * #JSONNotFound if there are no further values in the collection.
281  *
282  * <b>Example</b>
283  * @code{c}
284  *     // Variables used in this example.
285  *     static char * json_types[] =
286  *     {
287  *         "invalid",
288  *         "string",
289  *         "number",
290  *         "true",
291  *         "false",
292  *         "null",
293  *         "object",
294  *         "array"
295  *     };
296  *
297  *     void show( const char * json,
298  *                size_t length )
299  *     {
300  *         size_t start = 0, next = 0;
301  *         JSONPair_t pair = { 0 };
302  *         JSONStatus_t result;
303  *
304  *         result = JSON_Validate( json, length );
305  *         if( result == JSONSuccess )
306  *         {
307  *             result = JSON_Iterate( json, length, &start, &next, &pair );
308  *         }
309  *
310  *         while( result == JSONSuccess )
311  *         {
312  *             if( pair.key != NULL )
313  *             {
314  *                 printf( "key: %.*s\t", ( int ) pair.keyLength, pair.key );
315  *             }
316  *
317  *             printf( "value: (%s) %.*s\n", json_types[ pair.jsonType ],
318  *                     ( int ) pair.valueLength, pair.value );
319  *
320  *             result = JSON_Iterate( json, length, &start, &next, &pair );
321  *         }
322  *     }
323  * @endcode
324  */
325 /* @[declare_json_iterate] */
326 JSONStatus_t JSON_Iterate( const char * buf,
327                            size_t max,
328                            size_t * start,
329                            size_t * next,
330                            JSONPair_t * outPair );
331 /* @[declare_json_iterate] */
332
333 /* *INDENT-OFF* */
334 #ifdef __cplusplus
335     }
336 #endif
337 /* *INDENT-ON* */
338
339 #endif /* ifndef CORE_JSON_H_ */