--- a/ucx/cx/json.h Wed Dec 31 12:37:09 2025 +0100 +++ b/ucx/cx/json.h Wed Dec 31 16:40:12 2025 +0100 @@ -43,11 +43,6 @@ #include "array_list.h" #include "map.h" -#ifdef __cplusplus -extern "C" { -#endif - - /** * The type of the parsed token. */ @@ -115,6 +110,10 @@ */ CX_JSON_NOTHING, // this allows us to always return non-NULL values /** + * No meaningful data. + */ + CX_JSON_UNINITIALIZED, + /** * A JSON object. */ CX_JSON_OBJECT, @@ -289,13 +288,6 @@ CxBuffer buffer; /** - * Used internally. - * - * Remembers the prefix of the last uncompleted token. - */ - CxJsonToken uncompleted; - - /** * A pointer to an intermediate state of the currently parsed value. * * Never access this value manually. @@ -310,6 +302,16 @@ cxmutstr uncompleted_member_name; /** + * Internal buffer for uncompleted tokens. + */ + cxmutstr uncompleted_content; + + /** + * The expected type of the currently parsed, uncompleted token. + */ + CxJsonTokenType uncompleted_tokentype; + + /** * State stack. */ CX_ARRAY(int, states); @@ -424,8 +426,8 @@ * * @return new JSON writer settings */ -cx_attr_nodiscard -CX_EXPORT CxJsonWriter cxJsonWriterCompact(void); +CX_EXTERN CX_NODISCARD +CxJsonWriter cxJsonWriterCompact(void); /** * Creates a default writer configuration for pretty output. @@ -433,8 +435,8 @@ * @param use_spaces false if you want tabs, true if you want four spaces instead * @return new JSON writer settings */ -cx_attr_nodiscard -CX_EXPORT CxJsonWriter cxJsonWriterPretty(bool use_spaces); +CX_EXTERN CX_NODISCARD +CxJsonWriter cxJsonWriterPretty(bool use_spaces); /** * Writes a JSON value to a buffer or stream. @@ -454,8 +456,8 @@ * @retval zero success * @retval non-zero when no or not all data could be written */ -cx_attr_nonnull_arg(1, 2, 3) -CX_EXPORT int cxJsonWrite(void* target, const CxJsonValue* value, +CX_EXTERN CX_NONNULL_ARG(1, 2, 3) +int cxJsonWrite(void* target, const CxJsonValue* value, cx_write_func wfunc, const CxJsonWriter* settings); @@ -469,8 +471,8 @@ * @see cxJsonWriterCompact() * @see cxJsonToPrettyString() */ -cx_attr_nonnull_arg(2) -CX_EXPORT cxmutstr cxJsonToString(const CxAllocator *allocator, CxJsonValue *value); +CX_EXTERN CX_NONNULL_ARG(2) CX_NODISCARD +cxmutstr cxJsonToString(const CxAllocator *allocator, CxJsonValue *value); /** * Produces a pretty string representation of the specified JSON value. @@ -482,8 +484,8 @@ * @see cxJsonWriterPretty() * @see cxJsonToString() */ -cx_attr_nonnull_arg(2) -CX_EXPORT cxmutstr cxJsonToPrettyString(const CxAllocator *allocator, CxJsonValue *value); +CX_EXTERN CX_NONNULL_ARG(2) CX_NODISCARD +cxmutstr cxJsonToPrettyString(const CxAllocator *allocator, CxJsonValue *value); /** * Initializes the JSON interface. @@ -492,8 +494,8 @@ * @param allocator the allocator that shall be used for the produced values * @see cxJsonDestroy() */ -cx_attr_nonnull_arg(1) -CX_EXPORT void cxJsonInit(CxJson *json, const CxAllocator *allocator); +CX_EXTERN CX_NONNULL_ARG(1) +void cxJsonInit(CxJson *json, const CxAllocator *allocator); /** * Destroys the JSON interface. @@ -501,8 +503,8 @@ * @param json the JSON interface * @see cxJsonInit() */ -cx_attr_nonnull -CX_EXPORT void cxJsonDestroy(CxJson *json); +CX_EXTERN CX_NONNULL +void cxJsonDestroy(CxJson *json); /** * Destroys and re-initializes the JSON interface. @@ -512,8 +514,8 @@ * * @param json the JSON interface */ -cx_attr_nonnull -CX_EXPORT void cxJsonReset(CxJson *json); +CX_EXTERN CX_NONNULL +void cxJsonReset(CxJson *json); /** * Fills the input buffer. @@ -533,8 +535,8 @@ * @retval non-zero internal allocation error * @see cxJsonFill() */ -cx_attr_nonnull_arg(1) cx_attr_access_r(2, 3) -CX_EXPORT int cxJsonFilln(CxJson *json, const char *buf, size_t len); +CX_EXTERN CX_NONNULL_ARG(1) CX_ACCESS_R(2, 3) +int cxJsonFilln(CxJson *json, const char *buf, size_t len); /** @@ -545,8 +547,8 @@ * @retval zero success * @retval non-zero internal allocation error */ -cx_attr_nonnull -CX_INLINE int cx_json_fill(CxJson *json, cxstring str) { +CX_NONNULL CX_INLINE +int cx_json_fill(CxJson *json, cxstring str) { return cxJsonFilln(json, str.ptr, str.length); } @@ -578,8 +580,8 @@ * @param value a pointer where the JSON value shall be stored to * @return status code */ -cx_attr_nonnull_arg(3) -CX_EXPORT CxJsonStatus cx_json_from_string(const CxAllocator *allocator, +CX_EXTERN CX_NONNULL_ARG(3) CX_ACCESS_W(3) +CxJsonStatus cx_json_from_string(const CxAllocator *allocator, cxstring str, CxJsonValue **value); /** @@ -600,6 +602,20 @@ cx_json_from_string(allocator, cx_strcast(str), value) /** + * Recursively deallocates the memory of a JSON value. + * + * @remark The type of each deallocated value will be changed + * to #CX_JSON_NOTHING, and values of such a type will be skipped + * by the deallocation. That means this function protects + * you from double-frees when you are accidentally freeing + * a nested value and then the parent value (or vice versa). + * + * @param value the value + */ +CX_EXTERN +void cxJsonValueFree(CxJsonValue *value); + +/** * Creates a new (empty) JSON object. * * @param allocator the allocator to use @@ -607,8 +623,8 @@ * @see cxJsonObjPutObj() * @see cxJsonArrAddValues() */ -cx_attr_nodiscard -CX_EXPORT CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator); +CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1) +CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator); /** * Creates a new (empty) JSON array. @@ -621,8 +637,8 @@ * @see cxJsonObjPutArr() * @see cxJsonArrAddValues() */ -cx_attr_nodiscard -CX_EXPORT CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator, size_t capacity); +CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1) +CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator, size_t capacity); /** * Creates a new JSON number value. @@ -633,8 +649,8 @@ * @see cxJsonObjPutNumber() * @see cxJsonArrAddNumbers() */ -cx_attr_nodiscard -CX_EXPORT CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num); +CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1) +CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num); /** * Creates a new JSON number value based on an integer. @@ -645,8 +661,8 @@ * @see cxJsonObjPutInteger() * @see cxJsonArrAddIntegers() */ -cx_attr_nodiscard -CX_EXPORT CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num); +CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1) +CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num); /** * Creates a new JSON string. @@ -659,8 +675,8 @@ * @see cxJsonObjPutString() * @see cxJsonArrAddCxStrings() */ -cx_attr_nodiscard -CX_EXPORT CxJsonValue* cx_json_create_string(const CxAllocator* allocator, cxstring str); +CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1) +CxJsonValue* cx_json_create_string(const CxAllocator* allocator, cxstring str); /** * Creates a new JSON string. @@ -682,8 +698,8 @@ * @see cxJsonObjPutLiteral() * @see cxJsonArrAddLiterals() */ -cx_attr_nodiscard -CX_EXPORT CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit); +CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1) +CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit); /** * Adds number values to a JSON array. @@ -694,8 +710,8 @@ * @retval zero success * @retval non-zero allocation failure */ -cx_attr_nonnull cx_attr_access_r(2, 3) -CX_EXPORT int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count); +CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3) +int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count); /** * Adds number values, of which all are integers, to a JSON array. @@ -706,8 +722,8 @@ * @retval zero success * @retval non-zero allocation failure */ -cx_attr_nonnull cx_attr_access_r(2, 3) -CX_EXPORT int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count); +CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3) +int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count); /** * Adds strings to a JSON array. @@ -721,8 +737,8 @@ * @retval non-zero allocation failure * @see cxJsonArrAddCxStrings() */ -cx_attr_nonnull cx_attr_access_r(2, 3) -CX_EXPORT int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count); +CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3) +int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count); /** * Adds strings to a JSON array. @@ -736,8 +752,8 @@ * @retval non-zero allocation failure * @see cxJsonArrAddStrings() */ -cx_attr_nonnull cx_attr_access_r(2, 3) -CX_EXPORT int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count); +CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3) +int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count); /** * Adds literals to a JSON array. @@ -748,8 +764,8 @@ * @retval zero success * @retval non-zero allocation failure */ -cx_attr_nonnull cx_attr_access_r(2, 3) -CX_EXPORT int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count); +CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3) +int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count); /** * Add arbitrary values to a JSON array. @@ -763,8 +779,8 @@ * @retval zero success * @retval non-zero allocation failure */ -cx_attr_nonnull cx_attr_access_r(2, 3) -CX_EXPORT int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count); +CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3) +int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count); /** * Adds or replaces a value within a JSON object. @@ -777,8 +793,8 @@ * @retval zero success * @retval non-zero allocation failure */ -cx_attr_nonnull -CX_EXPORT int cx_json_obj_put(CxJsonValue* obj, cxstring name, CxJsonValue* child); +CX_EXTERN CX_NONNULL +int cx_json_obj_put(CxJsonValue* obj, cxstring name, CxJsonValue* child); /** * Adds or replaces a value within a JSON object. @@ -807,8 +823,8 @@ * @see cxJsonObjPut() * @see cxJsonCreateObj() */ -cx_attr_nonnull -CX_EXPORT CxJsonValue* cx_json_obj_put_obj(CxJsonValue* obj, cxstring name); +CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1) +CxJsonValue* cx_json_obj_put_obj(CxJsonValue* obj, cxstring name); /** * Creates a new JSON object and adds it to an existing object. @@ -833,8 +849,8 @@ * @see cxJsonObjPut() * @see cxJsonCreateArr() */ -cx_attr_nonnull -CX_EXPORT CxJsonValue* cx_json_obj_put_arr(CxJsonValue* obj, cxstring name, size_t capacity); +CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1) +CxJsonValue* cx_json_obj_put_arr(CxJsonValue* obj, cxstring name, size_t capacity); /** * Creates a new JSON array and adds it to an object. @@ -860,8 +876,8 @@ * @see cxJsonObjPut() * @see cxJsonCreateNumber() */ -cx_attr_nonnull -CX_EXPORT CxJsonValue* cx_json_obj_put_number(CxJsonValue* obj, cxstring name, double num); +CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1) +CxJsonValue* cx_json_obj_put_number(CxJsonValue* obj, cxstring name, double num); /** * Creates a new JSON number and adds it to an object. @@ -887,8 +903,8 @@ * @see cxJsonObjPut() * @see cxJsonCreateInteger() */ -cx_attr_nonnull -CX_EXPORT CxJsonValue* cx_json_obj_put_integer(CxJsonValue* obj, cxstring name, int64_t num); +CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1) +CxJsonValue* cx_json_obj_put_integer(CxJsonValue* obj, cxstring name, int64_t num); /** * Creates a new JSON number, based on an integer, and adds it to an object. @@ -914,8 +930,8 @@ * @see cxJsonObjPut() * @see cxJsonCreateString() */ -cx_attr_nonnull -CX_EXPORT CxJsonValue* cx_json_obj_put_string(CxJsonValue* obj, cxstring name, cxstring str); +CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1) +CxJsonValue* cx_json_obj_put_string(CxJsonValue* obj, cxstring name, cxstring str); /** * Creates a new JSON string and adds it to an object. @@ -943,8 +959,8 @@ * @see cxJsonObjPut() * @see cxJsonCreateLiteral() */ -cx_attr_nonnull -CX_EXPORT CxJsonValue* cx_json_obj_put_literal(CxJsonValue* obj, cxstring name, CxJsonLiteral lit); +CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1) +CxJsonValue* cx_json_obj_put_literal(CxJsonValue* obj, cxstring name, CxJsonLiteral lit); /** * Creates a new JSON literal and adds it to an object. @@ -959,19 +975,6 @@ #define cxJsonObjPutLiteral(obj, name, lit) cx_json_obj_put_literal(obj, cx_strcast(name), lit) /** - * Recursively deallocates the memory of a JSON value. - * - * @remark The type of each deallocated value will be changed - * to #CX_JSON_NOTHING, and values of such a type will be skipped - * by the deallocation. That means this function protects - * you from double-frees when you are accidentally freeing - * a nested value and then the parent value (or vice versa). - * - * @param value the value - */ -CX_EXPORT void cxJsonValueFree(CxJsonValue *value); - -/** * Tries to obtain the next JSON value. * * Before this function can be called, the input buffer needs @@ -993,8 +996,8 @@ * @retval CX_JSON_FORMAT_ERROR_NUMBER the JSON text contains an illegally formatted number * @retval CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN JSON syntax error */ -cx_attr_nonnull cx_attr_access_w(2) -CX_EXPORT CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value); +CX_EXTERN CX_NONNULL CX_ACCESS_W(2) +CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value); /** * Checks if the specified value is a JSON object. @@ -1003,8 +1006,8 @@ * @retval true the value is a JSON object * @retval false otherwise */ -cx_attr_nonnull -CX_INLINE bool cxJsonIsObject(const CxJsonValue *value) { +CX_NONNULL CX_NODISCARD CX_INLINE +bool cxJsonIsObject(const CxJsonValue *value) { return value->type == CX_JSON_OBJECT; } @@ -1015,8 +1018,8 @@ * @retval true the value is a JSON array * @retval false otherwise */ -cx_attr_nonnull -CX_INLINE bool cxJsonIsArray(const CxJsonValue *value) { +CX_NONNULL CX_NODISCARD CX_INLINE +bool cxJsonIsArray(const CxJsonValue *value) { return value->type == CX_JSON_ARRAY; } @@ -1027,8 +1030,8 @@ * @retval true the value is a string * @retval false otherwise */ -cx_attr_nonnull -CX_INLINE bool cxJsonIsString(const CxJsonValue *value) { +CX_NONNULL CX_NODISCARD CX_INLINE +bool cxJsonIsString(const CxJsonValue *value) { return value->type == CX_JSON_STRING; } @@ -1043,8 +1046,8 @@ * @retval false otherwise * @see cxJsonIsInteger() */ -cx_attr_nonnull -CX_INLINE bool cxJsonIsNumber(const CxJsonValue *value) { +CX_NONNULL CX_NODISCARD CX_INLINE +bool cxJsonIsNumber(const CxJsonValue *value) { return value->type == CX_JSON_NUMBER || value->type == CX_JSON_INTEGER; } @@ -1056,8 +1059,8 @@ * @retval false otherwise * @see cxJsonIsNumber() */ -cx_attr_nonnull -CX_INLINE bool cxJsonIsInteger(const CxJsonValue *value) { +CX_NONNULL CX_NODISCARD CX_INLINE +bool cxJsonIsInteger(const CxJsonValue *value) { return value->type == CX_JSON_INTEGER; } @@ -1073,8 +1076,8 @@ * @see cxJsonIsFalse() * @see cxJsonIsNull() */ -cx_attr_nonnull -CX_INLINE bool cxJsonIsLiteral(const CxJsonValue *value) { +CX_NONNULL CX_NODISCARD CX_INLINE +bool cxJsonIsLiteral(const CxJsonValue *value) { return value->type == CX_JSON_LITERAL; } @@ -1087,8 +1090,8 @@ * @see cxJsonIsTrue() * @see cxJsonIsFalse() */ -cx_attr_nonnull -CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) { +CX_NONNULL CX_NODISCARD CX_INLINE +bool cxJsonIsBool(const CxJsonValue *value) { return cxJsonIsLiteral(value) && value->literal != CX_JSON_NULL; } @@ -1104,8 +1107,8 @@ * @see cxJsonIsBool() * @see cxJsonIsFalse() */ -cx_attr_nonnull -CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) { +CX_NONNULL CX_NODISCARD CX_INLINE +bool cxJsonIsTrue(const CxJsonValue *value) { return cxJsonIsLiteral(value) && value->literal == CX_JSON_TRUE; } @@ -1121,8 +1124,8 @@ * @see cxJsonIsBool() * @see cxJsonIsTrue() */ -cx_attr_nonnull -CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) { +CX_NONNULL CX_NODISCARD CX_INLINE +bool cxJsonIsFalse(const CxJsonValue *value) { return cxJsonIsLiteral(value) && value->literal == CX_JSON_FALSE; } @@ -1134,8 +1137,8 @@ * @retval false otherwise * @see cxJsonIsLiteral() */ -cx_attr_nonnull -CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) { +CX_NONNULL CX_NODISCARD CX_INLINE +bool cxJsonIsNull(const CxJsonValue *value) { return cxJsonIsLiteral(value) && value->literal == CX_JSON_NULL; } @@ -1148,8 +1151,8 @@ * @return the value represented as C string * @see cxJsonIsString() */ -cx_attr_nonnull cx_attr_returns_nonnull -CX_EXPORT char *cxJsonAsString(const CxJsonValue *value); +CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL CX_NODISCARD +char *cxJsonAsString(const CxJsonValue *value); /** * Obtains a UCX string from the given JSON value. @@ -1160,8 +1163,8 @@ * @return the value represented as UCX string * @see cxJsonIsString() */ -cx_attr_nonnull -CX_EXPORT cxstring cxJsonAsCxString(const CxJsonValue *value); +CX_EXTERN CX_NONNULL CX_NODISCARD +cxstring cxJsonAsCxString(const CxJsonValue *value); /** * Obtains a mutable UCX string from the given JSON value. @@ -1172,8 +1175,8 @@ * @return the value represented as mutable UCX string * @see cxJsonIsString() */ -cx_attr_nonnull -CX_EXPORT cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value); +CX_EXTERN CX_NONNULL CX_NODISCARD +cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value); /** * Obtains a double-precision floating-point value from the given JSON value. @@ -1184,8 +1187,8 @@ * @return the value represented as double * @see cxJsonIsNumber() */ -cx_attr_nonnull -CX_EXPORT double cxJsonAsDouble(const CxJsonValue *value); +CX_EXTERN CX_NONNULL CX_NODISCARD +double cxJsonAsDouble(const CxJsonValue *value); /** * Obtains a 64-bit signed integer from the given JSON value. @@ -1199,8 +1202,8 @@ * @see cxJsonIsNumber() * @see cxJsonIsInteger() */ -cx_attr_nonnull -CX_EXPORT int64_t cxJsonAsInteger(const CxJsonValue *value); +CX_EXTERN CX_NONNULL CX_NODISCARD +int64_t cxJsonAsInteger(const CxJsonValue *value); /** * Obtains a Boolean value from the given JSON value. @@ -1212,8 +1215,8 @@ * @return the value represented as double * @see cxJsonIsLiteral() */ -cx_attr_nonnull -CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) { +CX_NONNULL CX_NODISCARD CX_INLINE +bool cxJsonAsBool(const CxJsonValue *value) { return value->literal == CX_JSON_TRUE; } @@ -1226,8 +1229,8 @@ * @return the size of the array * @see cxJsonIsArray() */ -cx_attr_nonnull -CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) { +CX_NONNULL CX_NODISCARD CX_INLINE +size_t cxJsonArrSize(const CxJsonValue *value) { return value->array.size; } @@ -1245,8 +1248,8 @@ * @return the value at the specified index * @see cxJsonIsArray() */ -cx_attr_nonnull cx_attr_returns_nonnull -CX_EXPORT CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index); +CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL CX_NODISCARD +CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index); /** * Removes an element from a JSON array. @@ -1261,8 +1264,8 @@ * @return the removed value from the specified index or @c NULL when the index was out of bounds * @see cxJsonIsArray() */ -cx_attr_nonnull -CX_EXPORT CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index); +CX_EXTERN CX_NONNULL +CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index); /** * Returns an iterator over the JSON array elements. @@ -1275,8 +1278,8 @@ * @return an iterator over the array elements * @see cxJsonIsArray() */ -cx_attr_nonnull cx_attr_nodiscard -CX_EXPORT CxIterator cxJsonArrIter(const CxJsonValue *value); +CX_EXTERN CX_NONNULL CX_NODISCARD +CxIterator cxJsonArrIter(const CxJsonValue *value); /** * Returns the size of a JSON object. @@ -1287,8 +1290,8 @@ * @return the size of the object, i.e., the number of key/value pairs * @see cxJsonIsObject() */ -cx_attr_nonnull -CX_INLINE size_t cxJsonObjSize(const CxJsonValue *value) { +CX_NONNULL CX_INLINE +size_t cxJsonObjSize(const CxJsonValue *value) { return cxCollectionSize(value->object); } @@ -1304,8 +1307,8 @@ * @return an iterator over the object members * @see cxJsonIsObject() */ -cx_attr_nonnull cx_attr_nodiscard -CX_EXPORT CxMapIterator cxJsonObjIter(const CxJsonValue *value); +CX_EXTERN CX_NONNULL CX_NODISCARD +CxMapIterator cxJsonObjIter(const CxJsonValue *value); /** * Internal function, do not use. @@ -1313,8 +1316,8 @@ * @param name the key to look up * @return the value corresponding to the key */ -cx_attr_nonnull cx_attr_returns_nonnull -CX_EXPORT CxJsonValue *cx_json_obj_get(const CxJsonValue *value, cxstring name); +CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL CX_NODISCARD +CxJsonValue *cx_json_obj_get(const CxJsonValue *value, cxstring name); /** * Returns a value corresponding to a key in a JSON object. @@ -1338,8 +1341,8 @@ * @param name the key to look up * @return the value corresponding to the key or @c NULL when the key is not part of the object */ -cx_attr_nonnull -CX_EXPORT CxJsonValue *cx_json_obj_remove(CxJsonValue *value, cxstring name); +CX_EXTERN CX_NONNULL +CxJsonValue *cx_json_obj_remove(CxJsonValue *value, cxstring name); /** * Removes and returns a value corresponding to a key in a JSON object. @@ -1366,7 +1369,8 @@ * @retval zero the values are equal (except for ordering of object members) * @retval non-zero the values differ */ -CX_EXPORT int cxJsonCompare(const CxJsonValue *json, const CxJsonValue *other); +CX_EXTERN CX_NODISCARD +int cxJsonCompare(const CxJsonValue *json, const CxJsonValue *other); /** @@ -1382,11 +1386,10 @@ * @return the new value or @c NULL if any allocation was unsuccessful * @see cxJsonCloneFunc() */ -cx_attr_nodiscard -CX_EXPORT CxJsonValue* cxJsonClone(const CxJsonValue* value, +CX_EXTERN CX_NODISCARD +CxJsonValue* cxJsonClone(const CxJsonValue* value, const CxAllocator* allocator); - /** * A @c cx_clone_func compatible version of cxJsonClone(). * @@ -1399,8 +1402,8 @@ * @return the new value or @c NULL if any allocation was unsuccessful * @see cxJsonClone() */ -cx_attr_nodiscard -CX_EXPORT CxJsonValue* cx_json_clone_func( +CX_EXTERN CX_NODISCARD +CxJsonValue* cx_json_clone_func( CxJsonValue* target, const CxJsonValue* source, const CxAllocator* allocator, void *data); @@ -1416,9 +1419,5 @@ */ #define cxJsonCloneFunc ((cx_clone_func) cx_json_clone_func) -#ifdef __cplusplus -} -#endif - #endif /* UCX_JSON_H */