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.
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.
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
Below is a full list of status codes for cxJsonNext().
Status Code
Meaning
CX_JSON_NO_ERROR
A value was successfully parsed.
CX_JSON_NO_DATA
The input buffer does not contain more data.
CX_JSON_INCOMPLETE_DATA
The input ends unexpectedly. Use cxJsonFill() to add more data before retrying.
CX_JSON_NULL_DATA
The input buffer was never initialized. Probably you forgot to call cxJsonFill() at least once.
CX_JSON_BUFFER_ALLOC_FAILED
More internal buffer was needed, but could not be allocated.
CX_JSON_VALUE_ALLOC_FAILED
Allocating memory for a json value failed.
CX_JSON_FORMAT_ERROR_NUMBER
A number value is incorrectly formatted.
CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN
The tokenizer found something unexpected, i.e. the JSON string contains a syntax error.
The cxJsonIsXYZ() family functions check the type of the specified JSON value.
The JSON specification only defines numbers, therefore cxJsonIsNumber() returns true for both floating point and integer numbers. On the other hand, cxJsonIsInteger() only returns true for integral numbers.
The function cxJsonIsBool() returns true if cxJsonIsLiteral() returns true, but cxJsonIsNull() does not.
The cxJsonAsXYZ() family of functions return the value with its corresponding C type.
The functions cxJsonAsInteger() and cxJsonAsDouble() can be used for any number value. For example, if cxJsonAsInteger() is used on a non-integral number, a double-to-int conversion is performed.
The function cxJsonArraySize() returns the number of items in an array value, which can be accessed via index with cxJsonArrGet() or via an iterator created with cxJsonArrIter().
The function cxJsonObjGet() returns the member in a JSON object associated with the specified name.
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.
#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.
A JSON value can be formatted with the cxJsonWrite() function.
The target can be a stream, a UCX buffer, or anything else that can be written to with a write function. The behavior of the function is controlled via a CxJsonWriter struct. With the functions cxJsonWriterCompact() and cxJsonWriterPretty() you can create default settings, which you may modify to suit your needs.
Setting
Compact Default
Pretty Default
Description
pretty
false
true
If true, the JSON will be formatted with line breaks and tabs or spaces. If false, output is as compact as possible without extra characters.
sort_members
true
true
If false members are written in the order in which they were added. If true, they are sorted lexicographically.
frac_max_digits
6
6
The maximum number of fractional digits in a number value.
indent_space
ignored
depends on use_spaces argument
If true, use spaces for indentation, otherwise use tabs.
indent
ignored
4
If indent_space is true, this is the number of spaces per tab. Ignored otherwise.
escape_slash
false
false
If true, the slash character (a.k.a forward solidus: /) is also escaped. This is usually only needed when you want to use JSON as part of an HTML attribute.