| 21 CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value); |
21 CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value); |
| 22 |
22 |
| 23 void cxJsonDestroy(CxJson *json); |
23 void cxJsonDestroy(CxJson *json); |
| 24 ``` |
24 ``` |
| 25 |
25 |
| 26 <warning> |
26 The first step is to initialize a `CxJson` structure with a call to `cxJsonInit()`, |
| 27 TODO: document |
27 specifying the allocator that shall be used for allocating values of type `CxJsonValue`. |
| 28 </warning> |
28 |
| |
29 Specifying `NULL` as `allocator` is allowed, in which case the `cxDefaultAllocator` will be used. |
| |
30 |
| |
31 The actual parsing is an interleaving invocation of the `cxJsonFill()` (or `cxJsonFilln()`) and `cxJsonNext()` functions. |
| |
32 The `cxJsonFill()` function is a convenience function, that accepts UCX strings and normal zero-terminated C strings. |
| |
33 |
| |
34 Calling `cxJsonNext()` will return with `CX_JSON_NO_ERROR` (= zero) for each JSON value that is successfully parsed, |
| |
35 and stores the pointer to the allocated value in the variable pointed to by `value`. |
| |
36 |
| |
37 > The parser is capable of parsing multiple consecutive JSON values. |
| |
38 > If those values are not objects or arrays, they must, however, be separated by any whitespace character. |
| |
39 |
| |
40 When all the data from the input buffer was successfully consumed, `cxJsonNext()` returns `CX_JSON_NO_DATA`. |
| |
41 |
| |
42 If `cxJsonNext()` returns `CX_JSON_INCOMPLETE_DATA` it means that the input buffer is exhausted, |
| |
43 but the parsed input does not constitute a complete JSON value. |
| |
44 In that case, you can call `cxJsonFill()` again to add more data and continue with `cxJsonNext()`. |
| |
45 |
| |
46 A complete list of all status codes can be seen [below](#list-of-status-codes). |
| |
47 |
| |
48 If you want to reuse a `CxJson` structure, you can call `cxJsonReset()`, even if the last operation was a failure. |
| |
49 Otherwise, you need to call `cxJsonDestroy()` when you are done with the parser. |
| 29 |
50 |
| 30 ### List of Status Codes |
51 ### List of Status Codes |
| 31 |
52 |
| 32 Below is a full list of status codes for `cxJsonNext()`. |
53 Below is a full list of status codes for `cxJsonNext()`. |
| 33 |
54 |
| 199 |
220 |
| 200 CxJsonValue* cxJsonObjPutLiteral(CxJsonValue* obj, |
221 CxJsonValue* cxJsonObjPutLiteral(CxJsonValue* obj, |
| 201 cxstring name, CxJsonLiteral lit); |
222 cxstring name, CxJsonLiteral lit); |
| 202 ``` |
223 ``` |
| 203 |
224 |
| 204 <warning> |
225 The `cxJsonCreateXY()`-family of functions can be used to create JSON values which are allocated by the specified `allocator`. |
| 205 TODO: document |
226 If you specify `NULL` as allocator, the `cxDefaultAllocator` is used. |
| 206 </warning> |
227 |
| |
228 If you want to add created values to a JSON array or JSON object, |
| |
229 you can use `cxJsonArrAddValues()` or `cxJsonObjPut()`, respectively. |
| |
230 However, it is usually more convenient to use one of the other functions, as they automatically create the JSON value for. |
| |
231 |
| |
232 ```C |
| |
233 #include <cx/json.h> |
| |
234 |
| |
235 CxJsonValue* arr = cxJsonCreateArr(NULL); |
| |
236 |
| |
237 // this is equivalent... |
| |
238 CxJsonValue* x = cxJsonCreateInteger(NULL, 47); |
| |
239 CxJsonValue* y = cxJsonCreateInteger(NULL, 11); |
| |
240 cxJsonArrAddValues(arr, (CxJsonValue*[]){x, y}, 2); |
| |
241 |
| |
242 // ... to this |
| |
243 cxJsonArrAddIntegers(arr, (int64_t[]){47, 11}, 2); |
| |
244 ``` |
| |
245 |
| |
246 The following example shows how to construct a complete JSON object. |
| |
247 |
| |
248 ```C |
| |
249 CxJsonValue *obj = cxJsonCreateObj(NULL); |
| |
250 |
| |
251 cxJsonObjPutLiteral(obj, CX_STR("bool"), CX_JSON_FALSE); |
| |
252 cxJsonObjPutInteger(obj, CX_STR("int"), 47); |
| |
253 |
| |
254 CxJsonValue *strings = cxJsonObjPutArr(obj, CX_STR("strings")); |
| |
255 cxJsonArrAddStrings(strings, (const char*[]) {"hello", "world"}, 2); |
| |
256 |
| |
257 CxJsonValue *nested = cxJsonObjPutObj(obj, CX_STR("nested")); |
| |
258 CxJsonValue *objects = cxJsonObjPutArr(nested, CX_STR("objects")); |
| |
259 CxJsonValue *obj_in_arr[2] = { |
| |
260 cxJsonCreateObj(NULL), |
| |
261 cxJsonCreateObj(NULL), |
| |
262 }; |
| |
263 cxJsonObjPutInteger(obj_in_arr[0], CX_STR("name1"), 1); |
| |
264 cxJsonObjPutInteger(obj_in_arr[0], CX_STR("name2"), 3); |
| |
265 |
| |
266 cxJsonObjPutInteger(obj_in_arr[1], CX_STR("name2"), 7); |
| |
267 cxJsonObjPutInteger(obj_in_arr[1], CX_STR("name1"), 3); |
| |
268 |
| |
269 cxJsonArrAddValues(objects, obj_in_arr, 2); |
| |
270 |
| |
271 cxJsonArrAddNumbers(cxJsonObjPutArr(nested, CX_STR("floats")), |
| |
272 (double[]){3.1415, 47.11, 8.15}, 3); |
| |
273 |
| |
274 cxJsonArrAddLiterals(cxJsonObjPutArr(nested, CX_STR("literals")), |
| |
275 (CxJsonLiteral[]){CX_JSON_TRUE, CX_JSON_NULL, CX_JSON_FALSE}, 3); |
| |
276 |
| |
277 CxJsonValue *ints = cxJsonObjPutArr(nested, CX_STR("ints")); |
| |
278 cxJsonArrAddIntegers(ints, (int64_t[]){4, 8, 15}, 3); |
| |
279 |
| |
280 CxJsonValue *nested_array = cxJsonCreateArr(NULL); |
| |
281 cxJsonArrAddValues(ints, &nested_array, 1); |
| |
282 cxJsonArrAddIntegers(nested_array, (int64_t[]){16, 23}, 2); |
| |
283 cxJsonArrAddIntegers(ints, (int64_t[]){42}, 1); |
| |
284 |
| |
285 CxJsonWriter w = cxJsonWriterPretty(true); |
| |
286 cxJsonWrite(stdout, obj, (cx_write_func) fwrite, &w); |
| |
287 |
| |
288 cxJsonValueFree(obj); |
| |
289 ``` |
| |
290 |
| |
291 The above code writes the following output to `stdout`: |
| |
292 |
| |
293 ```JSON |
| |
294 { |
| |
295 "bool": false, |
| |
296 "int": 47, |
| |
297 "nested": { |
| |
298 "floats": [3.1415, 47.11, 8.15], |
| |
299 "ints": [4, 8, 15, [16, 23], 42], |
| |
300 "literals": [true, null, false], |
| |
301 "objects": [{ |
| |
302 "name1": 1, |
| |
303 "name2": 3 |
| |
304 }, { |
| |
305 "name1": 3, |
| |
306 "name2": 7 |
| |
307 }] |
| |
308 }, |
| |
309 "strings": ["hello", "world"] |
| |
310 } |
| |
311 ``` |
| 207 |
312 |
| 208 ## Writer |
313 ## Writer |
| 209 |
314 |
| 210 ```C |
315 ```C |
| 211 #include <cx/json.h> |
316 #include <cx/json.h> |