complete JSON documentation default tip

Mon, 31 Mar 2025 19:39:42 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 31 Mar 2025 19:39:42 +0200
changeset 1268
a84403b0a503
parent 1267
d17eba9fae33

complete JSON documentation

relates to #451

docs/Writerside/topics/json.h.md file | annotate | diff | comparison | revisions
docs/Writerside/topics/properties.h.md file | annotate | diff | comparison | revisions
--- a/docs/Writerside/topics/json.h.md	Sun Mar 30 18:21:43 2025 +0200
+++ b/docs/Writerside/topics/json.h.md	Mon Mar 31 19:39:42 2025 +0200
@@ -23,9 +23,30 @@
 void cxJsonDestroy(CxJson *json);
 ```
 
-<warning>
-TODO: document
-</warning>
+The first step is to initialize a `CxJson` structure with a call to `cxJsonInit()`,
+specifying the allocator that shall be used for allocating values of type `CxJsonValue`.
+
+Specifying `NULL` as `allocator` is allowed, in which case the `cxDefaultAllocator` will be used.
+
+The actual parsing is an interleaving invocation of the `cxJsonFill()` (or `cxJsonFilln()`) and `cxJsonNext()` functions.
+The `cxJsonFill()` function is a convenience function, that accepts UCX strings and normal zero-terminated C strings.
+
+Calling `cxJsonNext()` will return with `CX_JSON_NO_ERROR` (= zero) for each JSON value that is successfully parsed,
+and stores the pointer to the allocated value in the variable pointed to by `value`.
+
+> The parser is capable of parsing multiple consecutive JSON values.
+> If those values are not objects or arrays, they must, however, be separated by any whitespace character. 
+
+When all the data from the input buffer was successfully consumed, `cxJsonNext()` returns `CX_JSON_NO_DATA`.
+
+If `cxJsonNext()` returns `CX_JSON_INCOMPLETE_DATA` it means that the input buffer is exhausted,
+but the parsed input does not constitute a complete JSON value. 
+In that case, you can call `cxJsonFill()` again to add more data and continue with `cxJsonNext()`.
+
+A complete list of all status codes can be seen [below](#list-of-status-codes).
+
+If you want to reuse a `CxJson` structure, you can call `cxJsonReset()`, even if the last operation was a failure.
+Otherwise, you need to call `cxJsonDestroy()` when you are done with the parser.
 
 ### List of Status Codes
 
@@ -201,9 +222,93 @@
         cxstring name, CxJsonLiteral lit);
 ```
 
-<warning>
-TODO: document
-</warning>
+The `cxJsonCreateXY()`-family of functions can be used to create JSON values which are allocated by the specified `allocator`.
+If you specify `NULL` as allocator, the `cxDefaultAllocator` is used.
+
+If you want to add created values to a JSON array or JSON object,
+you can use `cxJsonArrAddValues()` or `cxJsonObjPut()`, respectively.
+However, it is usually more convenient to use one of the other functions, as they automatically create the JSON value for.
+
+```C
+#include <cx/json.h>
+
+CxJsonValue* arr = cxJsonCreateArr(NULL);
+
+// this is equivalent...
+CxJsonValue* x = cxJsonCreateInteger(NULL, 47);
+CxJsonValue* y = cxJsonCreateInteger(NULL, 11);
+cxJsonArrAddValues(arr, (CxJsonValue*[]){x, y}, 2);
+
+// ... to this
+cxJsonArrAddIntegers(arr, (int64_t[]){47, 11}, 2);
+```
+
+The following example shows how to construct a complete JSON object.
+
+```C
+CxJsonValue *obj = cxJsonCreateObj(NULL);
+
+cxJsonObjPutLiteral(obj, CX_STR("bool"), CX_JSON_FALSE);
+cxJsonObjPutInteger(obj, CX_STR("int"), 47);
+
+CxJsonValue *strings = cxJsonObjPutArr(obj, CX_STR("strings"));
+cxJsonArrAddStrings(strings, (const char*[]) {"hello", "world"}, 2);
+
+CxJsonValue *nested = cxJsonObjPutObj(obj, CX_STR("nested"));
+CxJsonValue *objects = cxJsonObjPutArr(nested, CX_STR("objects"));
+CxJsonValue *obj_in_arr[2] = {
+    cxJsonCreateObj(NULL),
+    cxJsonCreateObj(NULL),
+};
+cxJsonObjPutInteger(obj_in_arr[0], CX_STR("name1"), 1);
+cxJsonObjPutInteger(obj_in_arr[0], CX_STR("name2"), 3);
+
+cxJsonObjPutInteger(obj_in_arr[1], CX_STR("name2"), 7);
+cxJsonObjPutInteger(obj_in_arr[1], CX_STR("name1"), 3);
+
+cxJsonArrAddValues(objects, obj_in_arr, 2);
+
+cxJsonArrAddNumbers(cxJsonObjPutArr(nested, CX_STR("floats")),
+    (double[]){3.1415, 47.11, 8.15}, 3);
+    
+cxJsonArrAddLiterals(cxJsonObjPutArr(nested, CX_STR("literals")),
+    (CxJsonLiteral[]){CX_JSON_TRUE, CX_JSON_NULL, CX_JSON_FALSE}, 3);
+ 
+CxJsonValue *ints = cxJsonObjPutArr(nested, CX_STR("ints"));
+cxJsonArrAddIntegers(ints, (int64_t[]){4, 8, 15}, 3);
+
+CxJsonValue *nested_array = cxJsonCreateArr(NULL);
+cxJsonArrAddValues(ints, &nested_array, 1);
+cxJsonArrAddIntegers(nested_array, (int64_t[]){16, 23}, 2);
+cxJsonArrAddIntegers(ints, (int64_t[]){42}, 1);
+
+CxJsonWriter w = cxJsonWriterPretty(true);
+cxJsonWrite(stdout, obj, (cx_write_func) fwrite, &w);
+
+cxJsonValueFree(obj);
+```
+
+The above code writes the following output to `stdout`:
+
+```JSON
+{
+    "bool": false,
+    "int": 47,
+    "nested": {
+        "floats": [3.1415, 47.11, 8.15],
+        "ints": [4, 8, 15, [16, 23], 42],
+        "literals": [true, null, false],
+        "objects": [{
+            "name1": 1,
+            "name2": 3
+        }, {
+            "name1": 3,
+            "name2": 7
+        }]
+    },
+    "strings": ["hello", "world"]
+}
+```
 
 ## Writer
 
--- a/docs/Writerside/topics/properties.h.md	Sun Mar 30 18:21:43 2025 +0200
+++ b/docs/Writerside/topics/properties.h.md	Mon Mar 31 19:39:42 2025 +0200
@@ -96,7 +96,7 @@
 If you want to reuse a `CxProperties` structure with the same config, you can call `cxPropertiesReset()`, even if the last operation was a failure.
 Otherwise, you should always call `cxPropertiesDestroy()` when you are done with the parser.
 
-> It is strongly recommended to always call `cxPropertiesDestroy` when you are done with the parser,
+> It is strongly recommended to always call `cxPropertiesDestroy()` when you are done with the parser,
 > even if you did not expect any allocations because you used `cxPropertiesUseStack()`.
 
 ### List of Status Codes

mercurial