| 186 /** |
187 /** |
| 187 * Type alias for the JSON array struct. |
188 * Type alias for the JSON array struct. |
| 188 */ |
189 */ |
| 189 typedef struct cx_json_array_s CxJsonArray; |
190 typedef struct cx_json_array_s CxJsonArray; |
| 190 /** |
191 /** |
| 191 * Type alias for the JSON object struct. |
192 * Type alias for the map representing a JSON object. |
| 192 */ |
193 * The map contains pointers of type @c CxJsonValue. |
| 193 typedef struct cx_json_object_s CxJsonObject; |
194 */ |
| |
195 typedef CxMap* CxJsonObject; |
| 194 /** |
196 /** |
| 195 * Type alias for a JSON string. |
197 * Type alias for a JSON string. |
| 196 */ |
198 */ |
| 197 typedef struct cx_mutstr_s CxJsonString; |
199 typedef struct cx_mutstr_s CxJsonString; |
| 198 /** |
200 /** |
| 207 * Type alias for a JSON literal. |
209 * Type alias for a JSON literal. |
| 208 */ |
210 */ |
| 209 typedef enum cx_json_literal CxJsonLiteral; |
211 typedef enum cx_json_literal CxJsonLiteral; |
| 210 |
212 |
| 211 /** |
213 /** |
| 212 * Type alias for a key/value pair in a JSON object. |
|
| 213 */ |
|
| 214 typedef struct cx_json_obj_value_s CxJsonObjValue; |
|
| 215 |
|
| 216 /** |
|
| 217 * JSON array structure. |
214 * JSON array structure. |
| 218 */ |
215 */ |
| 219 struct cx_json_array_s { |
216 struct cx_json_array_s { |
| 220 /** |
217 /** |
| 221 * The array data. |
218 * The array data. |
| 222 */ |
219 */ |
| 223 CX_ARRAY_DECLARE(CxJsonValue*, array); |
220 CX_ARRAY_DECLARE(CxJsonValue*, data); |
| 224 }; |
|
| 225 |
|
| 226 /** |
|
| 227 * JSON object structure. |
|
| 228 */ |
|
| 229 struct cx_json_object_s { |
|
| 230 /** |
|
| 231 * The key/value entries. |
|
| 232 */ |
|
| 233 CX_ARRAY_DECLARE(CxJsonObjValue, values); |
|
| 234 /** |
|
| 235 * The original indices to reconstruct the order in which the members were added. |
|
| 236 */ |
|
| 237 size_t *indices; |
|
| 238 }; |
|
| 239 |
|
| 240 /** |
|
| 241 * Structure for a key/value entry in a JSON object. |
|
| 242 */ |
|
| 243 struct cx_json_obj_value_s { |
|
| 244 /** |
|
| 245 * The key (or name in JSON terminology) of the value. |
|
| 246 */ |
|
| 247 cxmutstr name; |
|
| 248 /** |
|
| 249 * The value. |
|
| 250 */ |
|
| 251 CxJsonValue *value; |
|
| 252 }; |
221 }; |
| 253 |
222 |
| 254 /** |
223 /** |
| 255 * Structure for a JSON value. |
224 * Structure for a JSON value. |
| 256 */ |
225 */ |
| 347 * Never access this value manually. |
316 * Never access this value manually. |
| 348 */ |
317 */ |
| 349 CxJsonValue *parsed; |
318 CxJsonValue *parsed; |
| 350 |
319 |
| 351 /** |
320 /** |
| 352 * A pointer to an intermediate state of a currently parsed object member. |
321 * The name of a not yet completely parsed object member. |
| 353 * |
322 * |
| 354 * Never access this value manually. |
323 * Never access this value manually. |
| 355 */ |
324 */ |
| 356 CxJsonObjValue uncompleted_member; |
325 cxmutstr uncompleted_member_name; |
| 357 |
326 |
| 358 /** |
327 /** |
| 359 * State stack. |
328 * State stack. |
| 360 */ |
329 */ |
| 361 CX_ARRAY_DECLARE_SIZED(int, states, unsigned); |
330 CX_ARRAY_DECLARE_SIZED(int, states, unsigned); |
| 436 struct cx_json_writer_s { |
405 struct cx_json_writer_s { |
| 437 /** |
406 /** |
| 438 * Set true to enable pretty output. |
407 * Set true to enable pretty output. |
| 439 */ |
408 */ |
| 440 bool pretty; |
409 bool pretty; |
| 441 /** |
|
| 442 * Set false to output the members in the order in which they were added. |
|
| 443 */ |
|
| 444 bool sort_members; |
|
| 445 /** |
410 /** |
| 446 * The maximum number of fractional digits in a number value. |
411 * The maximum number of fractional digits in a number value. |
| 447 * The default value is 6 and values larger than 15 are reduced to 15. |
412 * The default value is 6 and values larger than 15 are reduced to 15. |
| 448 * Note that the actual number of digits may be lower, depending on the concrete number. |
413 * Note that the actual number of digits may be lower, depending on the concrete number. |
| 449 */ |
414 */ |
| 528 CX_EXPORT void cxJsonDestroy(CxJson *json); |
493 CX_EXPORT void cxJsonDestroy(CxJson *json); |
| 529 |
494 |
| 530 /** |
495 /** |
| 531 * Destroys and re-initializes the JSON interface. |
496 * Destroys and re-initializes the JSON interface. |
| 532 * |
497 * |
| 533 * You might want to use this to reset the parser after |
498 * You must use this to reset the parser after encountering a syntax error |
| 534 * encountering a syntax error. |
499 * if you want to continue using it. |
| 535 * |
500 * |
| 536 * @param json the JSON interface |
501 * @param json the JSON interface |
| 537 */ |
502 */ |
| 538 cx_attr_nonnull |
503 cx_attr_nonnull |
| 539 CX_EXPORT void cxJsonReset(CxJson *json); |
504 CX_EXPORT void cxJsonReset(CxJson *json); |
| 589 * @retval zero success |
554 * @retval zero success |
| 590 * @retval non-zero internal allocation error |
555 * @retval non-zero internal allocation error |
| 591 * @see cxJsonFilln() |
556 * @see cxJsonFilln() |
| 592 */ |
557 */ |
| 593 #define cxJsonFill(json, str) cx_json_fill(json, cx_strcast(str)) |
558 #define cxJsonFill(json, str) cx_json_fill(json, cx_strcast(str)) |
| |
559 |
| |
560 |
| |
561 /** |
| |
562 * Internal function - use cxJsonFromString() instead. |
| |
563 * |
| |
564 * @param allocator the allocator for the JSON value |
| |
565 * @param str the string to parse |
| |
566 * @param value a pointer where the JSON value shall be stored to |
| |
567 * @return status code |
| |
568 */ |
| |
569 cx_attr_nonnull_arg(3) |
| |
570 CX_EXPORT CxJsonStatus cx_json_from_string(const CxAllocator *allocator, |
| |
571 cxstring str, CxJsonValue **value); |
| |
572 |
| |
573 /** |
| |
574 * Parses a string into a JSON value. |
| |
575 * |
| |
576 * @param allocator (@c CxAllocator*) the allocator for the JSON value |
| |
577 * @param str (any string) the string to parse |
| |
578 * @param value (@c CxJsonValue**) a pointer where the JSON value shall be stored to |
| |
579 * @retval CX_JSON_NO_ERROR success |
| |
580 * @retval CX_JSON_NO_DATA the string was empty or blank |
| |
581 * @retval CX_JSON_INCOMPLETE_DATA the string unexpectedly ended |
| |
582 * @retval CX_JSON_BUFFER_ALLOC_FAILED allocating internal buffer space failed |
| |
583 * @retval CX_JSON_VALUE_ALLOC_FAILED allocating memory for the CxJsonValue failed |
| |
584 * @retval CX_JSON_FORMAT_ERROR_NUMBER the JSON text contains an illegally formatted number |
| |
585 * @retval CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN JSON syntax error |
| |
586 */ |
| |
587 #define cxJsonFromString(allocator, str, value) \ |
| |
588 cx_json_from_string(allocator, cx_strcast(str), value) |
| 594 |
589 |
| 595 /** |
590 /** |
| 596 * Creates a new (empty) JSON object. |
591 * Creates a new (empty) JSON object. |
| 597 * |
592 * |
| 598 * @param allocator the allocator to use |
593 * @param allocator the allocator to use |
| 1075 * @see cxJsonIsTrue() |
1070 * @see cxJsonIsTrue() |
| 1076 * @see cxJsonIsFalse() |
1071 * @see cxJsonIsFalse() |
| 1077 */ |
1072 */ |
| 1078 cx_attr_nonnull |
1073 cx_attr_nonnull |
| 1079 CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) { |
1074 CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) { |
| 1080 return cxJsonIsLiteral(value) && value->value.literal != CX_JSON_NULL; |
1075 return cxJsonIsLiteral(value) && value->literal != CX_JSON_NULL; |
| 1081 } |
1076 } |
| 1082 |
1077 |
| 1083 /** |
1078 /** |
| 1084 * Checks if the specified value is @c true. |
1079 * Checks if the specified value is @c true. |
| 1085 * |
1080 * |
| 1092 * @see cxJsonIsBool() |
1087 * @see cxJsonIsBool() |
| 1093 * @see cxJsonIsFalse() |
1088 * @see cxJsonIsFalse() |
| 1094 */ |
1089 */ |
| 1095 cx_attr_nonnull |
1090 cx_attr_nonnull |
| 1096 CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) { |
1091 CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) { |
| 1097 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_TRUE; |
1092 return cxJsonIsLiteral(value) && value->literal == CX_JSON_TRUE; |
| 1098 } |
1093 } |
| 1099 |
1094 |
| 1100 /** |
1095 /** |
| 1101 * Checks if the specified value is @c false. |
1096 * Checks if the specified value is @c false. |
| 1102 * |
1097 * |
| 1109 * @see cxJsonIsBool() |
1104 * @see cxJsonIsBool() |
| 1110 * @see cxJsonIsTrue() |
1105 * @see cxJsonIsTrue() |
| 1111 */ |
1106 */ |
| 1112 cx_attr_nonnull |
1107 cx_attr_nonnull |
| 1113 CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) { |
1108 CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) { |
| 1114 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_FALSE; |
1109 return cxJsonIsLiteral(value) && value->literal == CX_JSON_FALSE; |
| 1115 } |
1110 } |
| 1116 |
1111 |
| 1117 /** |
1112 /** |
| 1118 * Checks if the specified value is @c null. |
1113 * Checks if the specified value is @c null. |
| 1119 * |
1114 * |
| 1122 * @retval false otherwise |
1117 * @retval false otherwise |
| 1123 * @see cxJsonIsLiteral() |
1118 * @see cxJsonIsLiteral() |
| 1124 */ |
1119 */ |
| 1125 cx_attr_nonnull |
1120 cx_attr_nonnull |
| 1126 CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) { |
1121 CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) { |
| 1127 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_NULL; |
1122 return cxJsonIsLiteral(value) && value->literal == CX_JSON_NULL; |
| 1128 } |
1123 } |
| 1129 |
1124 |
| 1130 /** |
1125 /** |
| 1131 * Obtains a C string from the given JSON value. |
1126 * Obtains a C string from the given JSON value. |
| 1132 * |
1127 * |
| 1200 * @return the value represented as double |
1195 * @return the value represented as double |
| 1201 * @see cxJsonIsLiteral() |
1196 * @see cxJsonIsLiteral() |
| 1202 */ |
1197 */ |
| 1203 cx_attr_nonnull |
1198 cx_attr_nonnull |
| 1204 CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) { |
1199 CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) { |
| 1205 return value->value.literal == CX_JSON_TRUE; |
1200 return value->literal == CX_JSON_TRUE; |
| 1206 } |
1201 } |
| 1207 |
1202 |
| 1208 /** |
1203 /** |
| 1209 * Returns the size of a JSON array. |
1204 * Returns the size of a JSON array. |
| 1210 * |
1205 * |
| 1214 * @return the size of the array |
1209 * @return the size of the array |
| 1215 * @see cxJsonIsArray() |
1210 * @see cxJsonIsArray() |
| 1216 */ |
1211 */ |
| 1217 cx_attr_nonnull |
1212 cx_attr_nonnull |
| 1218 CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) { |
1213 CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) { |
| 1219 return value->value.array.array_size; |
1214 return value->array.data_size; |
| 1220 } |
1215 } |
| 1221 |
1216 |
| 1222 /** |
1217 /** |
| 1223 * Returns an element from a JSON array. |
1218 * Returns an element from a JSON array. |
| 1224 * |
1219 * |
| 1275 * @return the size of the object, i.e., the number of key/value pairs |
1270 * @return the size of the object, i.e., the number of key/value pairs |
| 1276 * @see cxJsonIsObject() |
1271 * @see cxJsonIsObject() |
| 1277 */ |
1272 */ |
| 1278 cx_attr_nonnull |
1273 cx_attr_nonnull |
| 1279 CX_INLINE size_t cxJsonObjSize(const CxJsonValue *value) { |
1274 CX_INLINE size_t cxJsonObjSize(const CxJsonValue *value) { |
| 1280 return value->value.object.values_size; |
1275 return cxCollectionSize(value->object); |
| 1281 } |
1276 } |
| 1282 |
1277 |
| 1283 /** |
1278 /** |
| 1284 * Returns an iterator over the JSON object members. |
1279 * Returns a map iterator over the JSON object members. |
| 1285 * |
1280 * |
| 1286 * The iterator yields values of type @c CxJsonObjValue* which |
1281 * The iterator yields values of type @c CxMapEntry* which |
| 1287 * contain the name and value of the member. |
1282 * contain the name and the @c CxJsonObjValue* of the member. |
| 1288 * |
1283 * |
| 1289 * If the @p value is not a JSON object, the behavior is undefined. |
1284 * If the @p value is not a JSON object, the behavior is undefined. |
| 1290 * |
1285 * |
| 1291 * @param value the JSON value |
1286 * @param value the JSON value |
| 1292 * @return an iterator over the object members |
1287 * @return an iterator over the object members |
| 1293 * @see cxJsonIsObject() |
1288 * @see cxJsonIsObject() |
| 1294 */ |
1289 */ |
| 1295 cx_attr_nonnull cx_attr_nodiscard |
1290 cx_attr_nonnull cx_attr_nodiscard |
| 1296 CX_EXPORT CxIterator cxJsonObjIter(const CxJsonValue *value); |
1291 CX_EXPORT CxMapIterator cxJsonObjIter(const CxJsonValue *value); |
| 1297 |
1292 |
| 1298 /** |
1293 /** |
| 1299 * Internal function, do not use. |
1294 * Internal function, do not use. |
| 1300 * @param value the JSON object |
1295 * @param value the JSON object |
| 1301 * @param name the key to look up |
1296 * @param name the key to look up |