| 194 /** |
194 /** |
| 195 * Type alias for a JSON string. |
195 * Type alias for a JSON string. |
| 196 */ |
196 */ |
| 197 typedef struct cx_mutstr_s CxJsonString; |
197 typedef struct cx_mutstr_s CxJsonString; |
| 198 /** |
198 /** |
| 199 * Type alias for a number that can be represented as 64-bit signed integer. |
199 * Type alias for a number that can be represented as a 64-bit signed integer. |
| 200 */ |
200 */ |
| 201 typedef int64_t CxJsonInteger; |
201 typedef int64_t CxJsonInteger; |
| 202 /** |
202 /** |
| 203 * Type alias for number that is not an integer. |
203 * Type alias for a number that is not an integer. |
| 204 */ |
204 */ |
| 205 typedef double CxJsonNumber; |
205 typedef double CxJsonNumber; |
| 206 /** |
206 /** |
| 207 * Type alias for a JSON literal. |
207 * Type alias for a JSON literal. |
| 208 */ |
208 */ |
| 270 /** |
270 /** |
| 271 * The value data. |
271 * The value data. |
| 272 */ |
272 */ |
| 273 union { |
273 union { |
| 274 /** |
274 /** |
| 275 * The array data if type is #CX_JSON_ARRAY. |
275 * The array data if the type is #CX_JSON_ARRAY. |
| 276 */ |
276 */ |
| 277 CxJsonArray array; |
277 CxJsonArray array; |
| 278 /** |
278 /** |
| 279 * The object data if type is #CX_JSON_OBJECT. |
279 * The object data if the type is #CX_JSON_OBJECT. |
| 280 */ |
280 */ |
| 281 CxJsonObject object; |
281 CxJsonObject object; |
| 282 /** |
282 /** |
| 283 * The string data if type is #CX_JSON_STRING. |
283 * The string data if the type is #CX_JSON_STRING. |
| 284 */ |
284 */ |
| 285 CxJsonString string; |
285 CxJsonString string; |
| 286 /** |
286 /** |
| 287 * The integer if type is #CX_JSON_INTEGER. |
287 * The integer if the type is #CX_JSON_INTEGER. |
| 288 */ |
288 */ |
| 289 CxJsonInteger integer; |
289 CxJsonInteger integer; |
| 290 /** |
290 /** |
| 291 * The number if type is #CX_JSON_NUMBER. |
291 * The number if the type is #CX_JSON_NUMBER. |
| 292 */ |
292 */ |
| 293 CxJsonNumber number; |
293 CxJsonNumber number; |
| 294 /** |
294 /** |
| 295 * The literal type if type is #CX_JSON_LITERAL. |
295 * The literal type if the type is #CX_JSON_LITERAL. |
| 296 */ |
296 */ |
| 297 CxJsonLiteral literal; |
297 CxJsonLiteral literal; |
| 298 } value; |
298 } value; |
| 299 }; |
299 }; |
| 300 |
300 |
| 389 */ |
389 */ |
| 390 CX_JSON_NO_DATA, |
390 CX_JSON_NO_DATA, |
| 391 /** |
391 /** |
| 392 * The input ends unexpectedly. |
392 * The input ends unexpectedly. |
| 393 * |
393 * |
| 394 * Refill the buffer with cxJsonFill() to complete the json data. |
394 * Refill the buffer with cxJsonFill() to complete the JSON data. |
| 395 */ |
395 */ |
| 396 CX_JSON_INCOMPLETE_DATA, |
396 CX_JSON_INCOMPLETE_DATA, |
| 397 /** |
397 /** |
| 398 * Not used as a status and never returned by any function. |
398 * Not used as a status and never returned by any function. |
| 399 * |
399 * |
| 400 * You can use this enumerator to check for all "good" status results |
400 * You can use this enumerator to check for all "good" status results |
| 401 * by checking if the status is less than @c CX_JSON_OK. |
401 * by checking if the status is less than @c CX_JSON_OK. |
| 402 * |
402 * |
| 403 * A "good" status means, that you can refill data and continue parsing. |
403 * A "good" status means that you can refill data and continue parsing. |
| 404 */ |
404 */ |
| 405 CX_JSON_OK, |
405 CX_JSON_OK, |
| 406 /** |
406 /** |
| 407 * The input buffer has never been filled. |
407 * The input buffer has never been filled. |
| 408 */ |
408 */ |
| 410 /** |
410 /** |
| 411 * Allocating memory for the internal buffer failed. |
411 * Allocating memory for the internal buffer failed. |
| 412 */ |
412 */ |
| 413 CX_JSON_BUFFER_ALLOC_FAILED, |
413 CX_JSON_BUFFER_ALLOC_FAILED, |
| 414 /** |
414 /** |
| 415 * Allocating memory for a json value failed. |
415 * Allocating memory for a JSON value failed. |
| 416 */ |
416 */ |
| 417 CX_JSON_VALUE_ALLOC_FAILED, |
417 CX_JSON_VALUE_ALLOC_FAILED, |
| 418 /** |
418 /** |
| 419 * A number value is incorrectly formatted. |
419 * A number value is incorrectly formatted. |
| 420 */ |
420 */ |
| 443 */ |
443 */ |
| 444 bool sort_members; |
444 bool sort_members; |
| 445 /** |
445 /** |
| 446 * The maximum number of fractional digits in a number value. |
446 * 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. |
447 * 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. |
448 * Note that the actual number of digits may be lower, depending on the concrete number. |
| 449 */ |
449 */ |
| 450 uint8_t frac_max_digits; |
450 uint8_t frac_max_digits; |
| 451 /** |
451 /** |
| 452 * Set true to use spaces instead of tab characters. |
452 * Set true to use spaces instead of tab characters. |
| 453 * Indentation is only used in pretty output. |
453 * Indentation is only used in pretty output. |
| 494 * This function blocks until either all data is written, or an error occurs. |
494 * This function blocks until either all data is written, or an error occurs. |
| 495 * The write operation is not atomic in the sense that it might happen |
495 * The write operation is not atomic in the sense that it might happen |
| 496 * that the data is only partially written when an error occurs with no |
496 * that the data is only partially written when an error occurs with no |
| 497 * way to indicate how much data was written. |
497 * way to indicate how much data was written. |
| 498 * To avoid this problem, you can use a CxBuffer as @p target which is |
498 * To avoid this problem, you can use a CxBuffer as @p target which is |
| 499 * unlikely to fail a write operation and either use the buffer's flush |
499 * unlikely to fail a write operation. You can, for example, use the buffer's flush |
| 500 * feature to relay the data or use the data in the buffer manually to |
500 * feature to relay the data. |
| 501 * write it to the actual target. |
|
| 502 * |
501 * |
| 503 * @param target the buffer or stream where to write to |
502 * @param target the buffer or stream where to write to |
| 504 * @param value the value that shall be written |
503 * @param value the value that shall be written |
| 505 * @param wfunc the write function to use |
504 * @param wfunc the write function to use |
| 506 * @param settings formatting settings (or @c NULL to use a compact default) |
505 * @param settings formatting settings (or @c NULL to use a compact default) |
| 515 cx_write_func wfunc, |
514 cx_write_func wfunc, |
| 516 const CxJsonWriter* settings |
515 const CxJsonWriter* settings |
| 517 ); |
516 ); |
| 518 |
517 |
| 519 /** |
518 /** |
| 520 * Initializes the json interface. |
519 * Initializes the JSON interface. |
| 521 * |
520 * |
| 522 * @param json the json interface |
521 * @param json the JSON interface |
| 523 * @param allocator the allocator that shall be used for the produced values |
522 * @param allocator the allocator that shall be used for the produced values |
| 524 * @see cxJsonDestroy() |
523 * @see cxJsonDestroy() |
| 525 */ |
524 */ |
| 526 cx_attr_nonnull_arg(1) |
525 cx_attr_nonnull_arg(1) |
| 527 cx_attr_export |
526 cx_attr_export |
| 528 void cxJsonInit(CxJson *json, const CxAllocator *allocator); |
527 void cxJsonInit(CxJson *json, const CxAllocator *allocator); |
| 529 |
528 |
| 530 /** |
529 /** |
| 531 * Destroys the json interface. |
530 * Destroys the JSON interface. |
| 532 * |
531 * |
| 533 * @param json the json interface |
532 * @param json the JSON interface |
| 534 * @see cxJsonInit() |
533 * @see cxJsonInit() |
| 535 */ |
534 */ |
| 536 cx_attr_nonnull |
535 cx_attr_nonnull |
| 537 cx_attr_export |
536 cx_attr_export |
| 538 void cxJsonDestroy(CxJson *json); |
537 void cxJsonDestroy(CxJson *json); |
| 539 |
538 |
| 540 /** |
539 /** |
| 541 * Destroys and re-initializes the json interface. |
540 * Destroys and re-initializes the JSON interface. |
| 542 * |
541 * |
| 543 * You might want to use this, to reset the parser after |
542 * You might want to use this to reset the parser after |
| 544 * encountering a syntax error. |
543 * encountering a syntax error. |
| 545 * |
544 * |
| 546 * @param json the json interface |
545 * @param json the JSON interface |
| 547 */ |
546 */ |
| 548 cx_attr_nonnull |
547 cx_attr_nonnull |
| 549 static inline void cxJsonReset(CxJson *json) { |
548 static inline void cxJsonReset(CxJson *json) { |
| 550 const CxAllocator *allocator = json->allocator; |
549 const CxAllocator *allocator = json->allocator; |
| 551 cxJsonDestroy(json); |
550 cxJsonDestroy(json); |
| 561 * pointer to the data in that case. When you invoke the fill |
560 * pointer to the data in that case. When you invoke the fill |
| 562 * function more than once before calling cxJsonNext(), |
561 * function more than once before calling cxJsonNext(), |
| 563 * the additional data is appended - inevitably leading to |
562 * the additional data is appended - inevitably leading to |
| 564 * an allocation of a new buffer and copying the previous contents. |
563 * an allocation of a new buffer and copying the previous contents. |
| 565 * |
564 * |
| 566 * @param json the json interface |
565 * @param json the JSON interface |
| 567 * @param buf the source buffer |
566 * @param buf the source buffer |
| 568 * @param len the length of the source buffer |
567 * @param len the length of the source buffer |
| 569 * @retval zero success |
568 * @retval zero success |
| 570 * @retval non-zero internal allocation error |
569 * @retval non-zero internal allocation error |
| 571 * @see cxJsonFill() |
570 * @see cxJsonFill() |
| 573 cx_attr_nonnull |
572 cx_attr_nonnull |
| 574 cx_attr_access_r(2, 3) |
573 cx_attr_access_r(2, 3) |
| 575 cx_attr_export |
574 cx_attr_export |
| 576 int cxJsonFilln(CxJson *json, const char *buf, size_t len); |
575 int cxJsonFilln(CxJson *json, const char *buf, size_t len); |
| 577 |
576 |
| 578 #ifdef __cplusplus |
577 |
| 579 } // extern "C" |
578 /** |
| 580 |
579 * Internal function, do not use. |
| 581 cx_attr_nonnull |
580 * |
| 582 static inline int cxJsonFill( |
581 * @param json the JSON interface |
| 583 CxJson *json, |
582 * @param str the string |
| 584 cxstring str |
583 * @retval zero success |
| 585 ) { |
584 * @retval non-zero internal allocation error |
| |
585 */ |
| |
586 cx_attr_nonnull |
| |
587 static inline int cx_json_fill(CxJson *json, cxstring str) { |
| 586 return cxJsonFilln(json, str.ptr, str.length); |
588 return cxJsonFilln(json, str.ptr, str.length); |
| 587 } |
589 } |
| 588 |
590 |
| 589 cx_attr_nonnull |
|
| 590 static inline int cxJsonFill( |
|
| 591 CxJson *json, |
|
| 592 cxmutstr str |
|
| 593 ) { |
|
| 594 return cxJsonFilln(json, str.ptr, str.length); |
|
| 595 } |
|
| 596 |
|
| 597 cx_attr_nonnull |
|
| 598 cx_attr_cstr_arg(2) |
|
| 599 static inline int cxJsonFill( |
|
| 600 CxJson *json, |
|
| 601 const char *str |
|
| 602 ) { |
|
| 603 return cxJsonFilln(json, str, strlen(str)); |
|
| 604 } |
|
| 605 |
|
| 606 extern "C" { |
|
| 607 #else // __cplusplus |
|
| 608 /** |
591 /** |
| 609 * Fills the input buffer. |
592 * Fills the input buffer. |
| 610 * |
593 * |
| 611 * The JSON interface tries to avoid copying the input data. |
594 * The JSON interface tries to avoid copying the input data. |
| 612 * When you use this function and cxJsonNext() interleaving, |
595 * When you use this function and cxJsonNext() interleaving, |
| 614 * pointer to the data in that case. When you invoke the fill |
597 * pointer to the data in that case. When you invoke the fill |
| 615 * function more than once before calling cxJsonNext(), |
598 * function more than once before calling cxJsonNext(), |
| 616 * the additional data is appended - inevitably leading to |
599 * the additional data is appended - inevitably leading to |
| 617 * an allocation of a new buffer and copying the previous contents. |
600 * an allocation of a new buffer and copying the previous contents. |
| 618 * |
601 * |
| 619 * @param json the json interface |
602 * @param json the JSON interface |
| 620 * @param str the source string |
603 * @param str the source string |
| 621 * @retval zero success |
604 * @retval zero success |
| 622 * @retval non-zero internal allocation error |
605 * @retval non-zero internal allocation error |
| 623 * @see cxJsonFilln() |
606 * @see cxJsonFilln() |
| 624 */ |
607 */ |
| 625 #define cxJsonFill(json, str) _Generic((str), \ |
608 #define cxJsonFill(json, str) cx_json_fill(json, cx_strcast(str)) |
| 626 cxstring: cx_json_fill_cxstr, \ |
|
| 627 cxmutstr: cx_json_fill_mutstr, \ |
|
| 628 char*: cx_json_fill_str, \ |
|
| 629 const char*: cx_json_fill_str) \ |
|
| 630 (json, str) |
|
| 631 |
|
| 632 /** |
|
| 633 * @copydoc cxJsonFill() |
|
| 634 */ |
|
| 635 cx_attr_nonnull |
|
| 636 static inline int cx_json_fill_cxstr( |
|
| 637 CxJson *json, |
|
| 638 cxstring str |
|
| 639 ) { |
|
| 640 return cxJsonFilln(json, str.ptr, str.length); |
|
| 641 } |
|
| 642 |
|
| 643 /** |
|
| 644 * @copydoc cxJsonFill() |
|
| 645 */ |
|
| 646 cx_attr_nonnull |
|
| 647 static inline int cx_json_fill_mutstr( |
|
| 648 CxJson *json, |
|
| 649 cxmutstr str |
|
| 650 ) { |
|
| 651 return cxJsonFilln(json, str.ptr, str.length); |
|
| 652 } |
|
| 653 |
|
| 654 /** |
|
| 655 * @copydoc cxJsonFill() |
|
| 656 */ |
|
| 657 cx_attr_nonnull |
|
| 658 cx_attr_cstr_arg(2) |
|
| 659 static inline int cx_json_fill_str( |
|
| 660 CxJson *json, |
|
| 661 const char *str |
|
| 662 ) { |
|
| 663 return cxJsonFilln(json, str, strlen(str)); |
|
| 664 } |
|
| 665 #endif |
|
| 666 |
609 |
| 667 /** |
610 /** |
| 668 * Creates a new (empty) JSON object. |
611 * Creates a new (empty) JSON object. |
| 669 * |
612 * |
| 670 * @param allocator the allocator to use |
613 * @param allocator the allocator to use |
| 971 |
914 |
| 972 /** |
915 /** |
| 973 * Recursively deallocates the memory of a JSON value. |
916 * Recursively deallocates the memory of a JSON value. |
| 974 * |
917 * |
| 975 * @remark The type of each deallocated value will be changed |
918 * @remark The type of each deallocated value will be changed |
| 976 * to #CX_JSON_NOTHING and values of such type will be skipped |
919 * to #CX_JSON_NOTHING, and values of such a type will be skipped |
| 977 * by the de-allocation. That means, this function protects |
920 * by the deallocation. That means this function protects |
| 978 * you from double-frees when you are accidentally freeing |
921 * you from double-frees when you are accidentally freeing |
| 979 * a nested value and then the parent value (or vice versa). |
922 * a nested value and then the parent value (or vice versa). |
| 980 * |
923 * |
| 981 * @param value the value |
924 * @param value the value |
| 982 */ |
925 */ |
| 991 * |
934 * |
| 992 * When this function returns #CX_JSON_INCOMPLETE_DATA, you can |
935 * When this function returns #CX_JSON_INCOMPLETE_DATA, you can |
| 993 * add the missing data with another invocation of cxJsonFill() |
936 * add the missing data with another invocation of cxJsonFill() |
| 994 * and then repeat the call to cxJsonNext(). |
937 * and then repeat the call to cxJsonNext(). |
| 995 * |
938 * |
| 996 * @param json the json interface |
939 * @param json the JSON interface |
| 997 * @param value a pointer where the next value shall be stored |
940 * @param value a pointer where the next value shall be stored |
| 998 * @retval CX_JSON_NO_ERROR successfully retrieve the @p value |
941 * @retval CX_JSON_NO_ERROR successfully retrieve the @p value |
| 999 * @retval CX_JSON_NO_DATA there is no (more) data in the buffer to read from |
942 * @retval CX_JSON_NO_DATA there is no (more) data in the buffer to read from |
| 1000 * @retval CX_JSON_INCOMPLETE_DATA an incomplete value was read |
943 * @retval CX_JSON_INCOMPLETE_DATA an incomplete value was read |
| 1001 * and more data needs to be filled |
944 * and more data needs to be filled |
| 1047 } |
990 } |
| 1048 |
991 |
| 1049 /** |
992 /** |
| 1050 * Checks if the specified value is a JSON number. |
993 * Checks if the specified value is a JSON number. |
| 1051 * |
994 * |
| 1052 * This function will return true for both floating point and |
995 * This function will return true for both floating-point and |
| 1053 * integer numbers. |
996 * integer numbers. |
| 1054 * |
997 * |
| 1055 * @param value a pointer to the value |
998 * @param value a pointer to the value |
| 1056 * @retval true the value is a JSON number |
999 * @retval true the value is a JSON number |
| 1057 * @retval false otherwise |
1000 * @retval false otherwise |
| 1107 } |
1050 } |
| 1108 |
1051 |
| 1109 /** |
1052 /** |
| 1110 * Checks if the specified value is @c true. |
1053 * Checks if the specified value is @c true. |
| 1111 * |
1054 * |
| 1112 * @remark Be advised, that this is not the same as |
1055 * @remark Be advised that this is different from |
| 1113 * testing @c !cxJsonIsFalse(v). |
1056 * testing @c !cxJsonIsFalse(v). |
| 1114 * |
1057 * |
| 1115 * @param value a pointer to the value |
1058 * @param value a pointer to the value |
| 1116 * @retval true the value is @c true |
1059 * @retval true the value is @c true |
| 1117 * @retval false otherwise |
1060 * @retval false otherwise |
| 1124 } |
1067 } |
| 1125 |
1068 |
| 1126 /** |
1069 /** |
| 1127 * Checks if the specified value is @c false. |
1070 * Checks if the specified value is @c false. |
| 1128 * |
1071 * |
| 1129 * @remark Be advised, that this is not the same as |
1072 * @remark Be advised that this is different from |
| 1130 * testing @c !cxJsonIsTrue(v). |
1073 * testing @c !cxJsonIsTrue(v). |
| 1131 * |
1074 * |
| 1132 * @param value a pointer to the value |
1075 * @param value a pointer to the value |
| 1133 * @retval true the value is @c false |
1076 * @retval true the value is @c false |
| 1134 * @retval false otherwise |
1077 * @retval false otherwise |
| 1195 static inline cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value) { |
1138 static inline cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value) { |
| 1196 return value->value.string; |
1139 return value->value.string; |
| 1197 } |
1140 } |
| 1198 |
1141 |
| 1199 /** |
1142 /** |
| 1200 * Obtains a double-precision floating point value from the given JSON value. |
1143 * Obtains a double-precision floating-point value from the given JSON value. |
| 1201 * |
1144 * |
| 1202 * If the @p value is not a JSON number, the behavior is undefined. |
1145 * If the @p value is not a JSON number, the behavior is undefined. |
| 1203 * |
1146 * |
| 1204 * @param value the JSON value |
1147 * @param value the JSON value |
| 1205 * @return the value represented as double |
1148 * @return the value represented as double |
| 1282 cx_attr_returns_nonnull |
1225 cx_attr_returns_nonnull |
| 1283 cx_attr_export |
1226 cx_attr_export |
| 1284 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index); |
1227 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index); |
| 1285 |
1228 |
| 1286 /** |
1229 /** |
| |
1230 * Removes an element from a JSON array. |
| |
1231 * |
| |
1232 * If the @p value is not a JSON array, the behavior is undefined. |
| |
1233 * |
| |
1234 * This function, in contrast to cxJsonArrayGet(), returns @c NULL |
| |
1235 * when the index is out of bounds. |
| |
1236 * |
| |
1237 * @param value the JSON value |
| |
1238 * @param index the index in the array |
| |
1239 * @return the removed value from the specified index or @c NULL when the index was out of bounds |
| |
1240 * @see cxJsonIsArray() |
| |
1241 */ |
| |
1242 cx_attr_nonnull |
| |
1243 cx_attr_export |
| |
1244 CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index); |
| |
1245 |
| |
1246 /** |
| 1287 * Returns an iterator over the JSON array elements. |
1247 * Returns an iterator over the JSON array elements. |
| 1288 * |
1248 * |
| 1289 * The iterator yields values of type @c CxJsonValue* . |
1249 * The iterator yields values of type @c CxJsonValue* . |
| 1290 * |
1250 * |
| 1291 * If the @p value is not a JSON array, the behavior is undefined. |
1251 * If the @p value is not a JSON array, the behavior is undefined. |
| 1315 cx_attr_nodiscard |
1275 cx_attr_nodiscard |
| 1316 cx_attr_export |
1276 cx_attr_export |
| 1317 CxIterator cxJsonObjIter(const CxJsonValue *value); |
1277 CxIterator cxJsonObjIter(const CxJsonValue *value); |
| 1318 |
1278 |
| 1319 /** |
1279 /** |
| 1320 * @copydoc cxJsonObjGet() |
1280 * Internal function, do not use. |
| |
1281 * @param value the JSON object |
| |
1282 * @param name the key to look up |
| |
1283 * @return the value corresponding to the key |
| 1321 */ |
1284 */ |
| 1322 cx_attr_nonnull |
1285 cx_attr_nonnull |
| 1323 cx_attr_returns_nonnull |
1286 cx_attr_returns_nonnull |
| 1324 cx_attr_export |
1287 cx_attr_export |
| 1325 CxJsonValue *cx_json_obj_get_cxstr(const CxJsonValue *value, cxstring name); |
1288 CxJsonValue *cx_json_obj_get(const CxJsonValue *value, cxstring name); |
| 1326 |
1289 |
| 1327 #ifdef __cplusplus |
|
| 1328 } // extern "C" |
|
| 1329 |
|
| 1330 static inline CxJsonValue *cxJsonObjGet(const CxJsonValue *value, cxstring name) { |
|
| 1331 return cx_json_obj_get_cxstr(value, name); |
|
| 1332 } |
|
| 1333 |
|
| 1334 static inline CxJsonValue *cxJsonObjGet(const CxJsonValue *value, cxmutstr name) { |
|
| 1335 return cx_json_obj_get_cxstr(value, cx_strcast(name)); |
|
| 1336 } |
|
| 1337 |
|
| 1338 static inline CxJsonValue *cxJsonObjGet(const CxJsonValue *value, const char *name) { |
|
| 1339 return cx_json_obj_get_cxstr(value, cx_str(name)); |
|
| 1340 } |
|
| 1341 |
|
| 1342 extern "C" { |
|
| 1343 #else |
|
| 1344 /** |
1290 /** |
| 1345 * Returns a value corresponding to a key in a JSON object. |
1291 * Returns a value corresponding to a key in a JSON object. |
| 1346 * |
1292 * |
| 1347 * If the @p value is not a JSON object, the behavior is undefined. |
1293 * If the @p value is not a JSON object, the behavior is undefined. |
| 1348 * |
1294 * |
| 1353 * @param value the JSON object |
1299 * @param value the JSON object |
| 1354 * @param name the key to look up |
1300 * @param name the key to look up |
| 1355 * @return the value corresponding to the key |
1301 * @return the value corresponding to the key |
| 1356 * @see cxJsonIsObject() |
1302 * @see cxJsonIsObject() |
| 1357 */ |
1303 */ |
| 1358 #define cxJsonObjGet(value, name) _Generic((name), \ |
1304 #define cxJsonObjGet(value, name) cx_json_obj_get(value, cx_strcast(name)) |
| 1359 cxstring: cx_json_obj_get_cxstr, \ |
1305 |
| 1360 cxmutstr: cx_json_obj_get_mutstr, \ |
1306 /** |
| 1361 char*: cx_json_obj_get_str, \ |
1307 * Internal function, do not use. |
| 1362 const char*: cx_json_obj_get_str) \ |
1308 * @param value the JSON object |
| 1363 (value, name) |
1309 * @param name the key to look up |
| 1364 |
1310 * @return the value corresponding to the key or @c NULL when the key is not part of the object |
| 1365 /** |
1311 */ |
| 1366 * @copydoc cxJsonObjGet() |
1312 cx_attr_nonnull |
| 1367 */ |
1313 cx_attr_export |
| 1368 cx_attr_nonnull |
1314 CxJsonValue *cx_json_obj_remove(CxJsonValue *value, cxstring name); |
| 1369 cx_attr_returns_nonnull |
1315 |
| 1370 static inline CxJsonValue *cx_json_obj_get_mutstr(const CxJsonValue *value, cxmutstr name) { |
1316 /** |
| 1371 return cx_json_obj_get_cxstr(value, cx_strcast(name)); |
1317 * Removes and returns a value corresponding to a key in a JSON object. |
| 1372 } |
1318 * |
| 1373 |
1319 * If the @p value is not a JSON object, the behavior is undefined. |
| 1374 /** |
1320 * |
| 1375 * @copydoc cxJsonObjGet() |
1321 * This function, in contrast to cxJsonObjGet() returns @c NULL when the |
| 1376 */ |
1322 * object does not contain @p name. |
| 1377 cx_attr_nonnull |
1323 * |
| 1378 cx_attr_returns_nonnull |
1324 * @param value the JSON object |
| 1379 cx_attr_cstr_arg(2) |
1325 * @param name the key to look up |
| 1380 static inline CxJsonValue *cx_json_obj_get_str(const CxJsonValue *value, const char *name) { |
1326 * @return the value corresponding to the key or @c NULL when the key is not part of the object |
| 1381 return cx_json_obj_get_cxstr(value, cx_str(name)); |
1327 * @see cxJsonIsObject() |
| |
1328 */ |
| |
1329 #define cxJsonObjRemove(value, name) cx_json_obj_remove(value, cx_strcast(name)) |
| |
1330 |
| |
1331 #ifdef __cplusplus |
| 1382 } |
1332 } |
| 1383 #endif |
1333 #endif |
| 1384 |
1334 |
| 1385 #ifdef __cplusplus |
|
| 1386 } |
|
| 1387 #endif |
|
| 1388 |
|
| 1389 #endif /* UCX_JSON_H */ |
1335 #endif /* UCX_JSON_H */ |
| 1390 |
1336 |