Mon, 31 Mar 2025 19:39:42 +0200
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