--- a/src/cx/json.h Sun Dec 28 15:45:39 2025 +0100 +++ b/src/cx/json.h Sun Dec 28 17:31:20 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, @@ -427,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. @@ -436,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. @@ -457,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); @@ -472,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. @@ -485,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. @@ -495,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. @@ -504,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. @@ -515,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. @@ -536,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); /** @@ -548,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); } @@ -581,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); /** @@ -603,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 @@ -610,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. @@ -624,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. @@ -636,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. @@ -648,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. @@ -662,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. @@ -685,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. @@ -697,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. @@ -709,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. @@ -724,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. @@ -739,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. @@ -751,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. @@ -766,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. @@ -780,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. @@ -810,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. @@ -836,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. @@ -863,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. @@ -890,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. @@ -917,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. @@ -946,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. @@ -962,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 @@ -996,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. @@ -1006,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; } @@ -1018,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; } @@ -1030,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; } @@ -1046,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; } @@ -1059,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; } @@ -1076,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; } @@ -1090,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; } @@ -1107,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; } @@ -1124,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; } @@ -1137,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; } @@ -1151,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. @@ -1163,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. @@ -1175,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. @@ -1187,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. @@ -1202,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. @@ -1215,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; } @@ -1229,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; } @@ -1248,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. @@ -1264,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. @@ -1278,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. @@ -1290,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); } @@ -1307,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. @@ -1316,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. @@ -1341,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. @@ -1369,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); /** @@ -1385,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(). * @@ -1402,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); @@ -1419,9 +1419,5 @@ */ #define cxJsonCloneFunc ((cx_clone_func) cx_json_clone_func) -#ifdef __cplusplus -} -#endif - #endif /* UCX_JSON_H */