| 114:3da24640513a | 115:e57ca2747782 |
|---|---|
| 39 #include "common.h" | 39 #include "common.h" |
| 40 #include "allocator.h" | 40 #include "allocator.h" |
| 41 #include "string.h" | 41 #include "string.h" |
| 42 #include "buffer.h" | 42 #include "buffer.h" |
| 43 #include "array_list.h" | 43 #include "array_list.h" |
| 44 #include "map.h" | |
| 44 | 45 |
| 45 #include <string.h> | 46 #include <string.h> |
| 46 | 47 |
| 47 #ifdef __cplusplus | 48 #ifdef __cplusplus |
| 48 extern "C" { | 49 extern "C" { |
| 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 */ |
| 293 CxJsonNumber number; | 262 CxJsonNumber number; |
| 294 /** | 263 /** |
| 295 * The literal type if the type is #CX_JSON_LITERAL. | 264 * The literal type if the type is #CX_JSON_LITERAL. |
| 296 */ | 265 */ |
| 297 CxJsonLiteral literal; | 266 CxJsonLiteral literal; |
| 298 } value; | 267 }; |
| 299 }; | 268 }; |
| 300 | 269 |
| 301 /** | 270 /** |
| 302 * Internally used structure for a parsed token. | 271 * Internally used structure for a parsed token. |
| 303 * | 272 * |
| 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 */ |
| 506 */ | 471 */ |
| 507 cx_attr_nonnull_arg(1, 2, 3) | 472 cx_attr_nonnull_arg(1, 2, 3) |
| 508 CX_EXPORT int cxJsonWrite(void* target, const CxJsonValue* value, | 473 CX_EXPORT int cxJsonWrite(void* target, const CxJsonValue* value, |
| 509 cx_write_func wfunc, const CxJsonWriter* settings); | 474 cx_write_func wfunc, const CxJsonWriter* settings); |
| 510 | 475 |
| 476 | |
| 477 /** | |
| 478 * Produces a compact string representation of the specified JSON value. | |
| 479 * | |
| 480 * @param value the JSON value | |
| 481 * @param allocator the allocator for the string | |
| 482 * @return the produced string | |
| 483 * @see cxJsonWrite() | |
| 484 * @see cxJsonWriterCompact() | |
| 485 * @see cxJsonToPrettyString() | |
| 486 */ | |
| 487 cx_attr_nonnull_arg(1) | |
| 488 CX_EXPORT cxmutstr cxJsonToString(CxJsonValue *value, const CxAllocator *allocator); | |
| 489 | |
| 490 /** | |
| 491 * Produces a pretty string representation of the specified JSON value. | |
| 492 * | |
| 493 * @param value the JSON value | |
| 494 * @param allocator the allocator for the string | |
| 495 * @return the produced string | |
| 496 * @see cxJsonWrite() | |
| 497 * @see cxJsonWriterPretty() | |
| 498 * @see cxJsonToString() | |
| 499 */ | |
| 500 cx_attr_nonnull_arg(1) | |
| 501 CX_EXPORT cxmutstr cxJsonToPrettyString(CxJsonValue *value, const CxAllocator *allocator); | |
| 502 | |
| 511 /** | 503 /** |
| 512 * Initializes the JSON interface. | 504 * Initializes the JSON interface. |
| 513 * | 505 * |
| 514 * @param json the JSON interface | 506 * @param json the JSON interface |
| 515 * @param allocator the allocator that shall be used for the produced values | 507 * @param allocator the allocator that shall be used for the produced values |
| 528 CX_EXPORT void cxJsonDestroy(CxJson *json); | 520 CX_EXPORT void cxJsonDestroy(CxJson *json); |
| 529 | 521 |
| 530 /** | 522 /** |
| 531 * Destroys and re-initializes the JSON interface. | 523 * Destroys and re-initializes the JSON interface. |
| 532 * | 524 * |
| 533 * You might want to use this to reset the parser after | 525 * You must use this to reset the parser after encountering a syntax error |
| 534 * encountering a syntax error. | 526 * if you want to continue using it. |
| 535 * | 527 * |
| 536 * @param json the JSON interface | 528 * @param json the JSON interface |
| 537 */ | 529 */ |
| 538 cx_attr_nonnull | 530 cx_attr_nonnull |
| 539 CX_EXPORT void cxJsonReset(CxJson *json); | 531 CX_EXPORT void cxJsonReset(CxJson *json); |
| 554 * @param len the length of the source buffer | 546 * @param len the length of the source buffer |
| 555 * @retval zero success | 547 * @retval zero success |
| 556 * @retval non-zero internal allocation error | 548 * @retval non-zero internal allocation error |
| 557 * @see cxJsonFill() | 549 * @see cxJsonFill() |
| 558 */ | 550 */ |
| 559 cx_attr_nonnull cx_attr_access_r(2, 3) | 551 cx_attr_nonnull_arg(1) cx_attr_access_r(2, 3) |
| 560 CX_EXPORT int cxJsonFilln(CxJson *json, const char *buf, size_t len); | 552 CX_EXPORT int cxJsonFilln(CxJson *json, const char *buf, size_t len); |
| 561 | 553 |
| 562 | 554 |
| 563 /** | 555 /** |
| 564 * Internal function, do not use. | 556 * Internal function, do not use. |
| 590 * @retval non-zero internal allocation error | 582 * @retval non-zero internal allocation error |
| 591 * @see cxJsonFilln() | 583 * @see cxJsonFilln() |
| 592 */ | 584 */ |
| 593 #define cxJsonFill(json, str) cx_json_fill(json, cx_strcast(str)) | 585 #define cxJsonFill(json, str) cx_json_fill(json, cx_strcast(str)) |
| 594 | 586 |
| 587 | |
| 588 /** | |
| 589 * Internal function - use cxJsonFromString() instead. | |
| 590 * | |
| 591 * @param allocator the allocator for the JSON value | |
| 592 * @param str the string to parse | |
| 593 * @param value a pointer where the JSON value shall be stored to | |
| 594 * @return status code | |
| 595 */ | |
| 596 cx_attr_nonnull_arg(3) | |
| 597 CX_EXPORT CxJsonStatus cx_json_from_string(const CxAllocator *allocator, | |
| 598 cxstring str, CxJsonValue **value); | |
| 599 | |
| 600 /** | |
| 601 * Parses a string into a JSON value. | |
| 602 * | |
| 603 * @param allocator (@c CxAllocator*) the allocator for the JSON value | |
| 604 * @param str (any string) the string to parse | |
| 605 * @param value (@c CxJsonValue**) a pointer where the JSON value shall be stored to | |
| 606 * @retval CX_JSON_NO_ERROR success | |
| 607 * @retval CX_JSON_NO_DATA the string was empty or blank | |
| 608 * @retval CX_JSON_INCOMPLETE_DATA the string unexpectedly ended | |
| 609 * @retval CX_JSON_BUFFER_ALLOC_FAILED allocating internal buffer space failed | |
| 610 * @retval CX_JSON_VALUE_ALLOC_FAILED allocating memory for the CxJsonValue failed | |
| 611 * @retval CX_JSON_FORMAT_ERROR_NUMBER the JSON text contains an illegally formatted number | |
| 612 * @retval CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN JSON syntax error | |
| 613 */ | |
| 614 #define cxJsonFromString(allocator, str, value) \ | |
| 615 cx_json_from_string(allocator, cx_strcast(str), value) | |
| 616 | |
| 595 /** | 617 /** |
| 596 * Creates a new (empty) JSON object. | 618 * Creates a new (empty) JSON object. |
| 597 * | 619 * |
| 598 * @param allocator the allocator to use | 620 * @param allocator the allocator to use |
| 599 * @return the new JSON object or @c NULL if allocation fails | 621 * @return the new JSON object or @c NULL if allocation fails |
| 639 CX_EXPORT CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num); | 661 CX_EXPORT CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num); |
| 640 | 662 |
| 641 /** | 663 /** |
| 642 * Creates a new JSON string. | 664 * Creates a new JSON string. |
| 643 * | 665 * |
| 666 * Internal function - use cxJsonCreateString() instead. | |
| 667 * | |
| 644 * @param allocator the allocator to use | 668 * @param allocator the allocator to use |
| 645 * @param str the string data | 669 * @param str the string data |
| 646 * @return the new JSON value or @c NULL if allocation fails | 670 * @return the new JSON value or @c NULL if allocation fails |
| 647 * @see cxJsonCreateString() | |
| 648 * @see cxJsonObjPutString() | 671 * @see cxJsonObjPutString() |
| 649 * @see cxJsonArrAddStrings() | 672 * @see cxJsonArrAddCxStrings() |
| 650 */ | 673 */ |
| 651 cx_attr_nodiscard cx_attr_nonnull_arg(2) cx_attr_cstr_arg(2) | 674 cx_attr_nodiscard |
| 652 CX_EXPORT CxJsonValue* cxJsonCreateString(const CxAllocator* allocator, const char *str); | 675 CX_EXPORT CxJsonValue* cx_json_create_string(const CxAllocator* allocator, cxstring str); |
| 653 | 676 |
| 654 /** | 677 /** |
| 655 * Creates a new JSON string. | 678 * Creates a new JSON string. |
| 656 * | 679 * |
| 657 * @param allocator the allocator to use | 680 * @param allocator (@c CxAllocator*) the allocator to use |
| 658 * @param str the string data | 681 * @param str the string |
| 659 * @return the new JSON value or @c NULL if allocation fails | 682 * @return (@c CxJsonValue*) the new JSON value or @c NULL if allocation fails |
| 660 * @see cxJsonCreateCxString() | 683 * @see cxJsonObjPutString() |
| 661 * @see cxJsonObjPutCxString() | |
| 662 * @see cxJsonArrAddCxStrings() | 684 * @see cxJsonArrAddCxStrings() |
| 663 */ | 685 */ |
| 664 cx_attr_nodiscard | 686 #define cxJsonCreateString(allocator, str) cx_json_create_string(allocator, cx_strcast(str)) |
| 665 CX_EXPORT CxJsonValue* cxJsonCreateCxString(const CxAllocator* allocator, cxstring str); | |
| 666 | 687 |
| 667 /** | 688 /** |
| 668 * Creates a new JSON literal. | 689 * Creates a new JSON literal. |
| 669 * | 690 * |
| 670 * @param allocator the allocator to use | 691 * @param allocator the allocator to use |
| 758 CX_EXPORT int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count); | 779 CX_EXPORT int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count); |
| 759 | 780 |
| 760 /** | 781 /** |
| 761 * Adds or replaces a value within a JSON object. | 782 * Adds or replaces a value within a JSON object. |
| 762 * | 783 * |
| 763 * The value will be directly added and not copied. | 784 * Internal function - use cxJsonObjPut(). |
| 764 * | |
| 765 * @note If a value with the specified @p name already exists, | |
| 766 * it will be (recursively) freed with its own allocator. | |
| 767 * | 785 * |
| 768 * @param obj the JSON object | 786 * @param obj the JSON object |
| 769 * @param name the name of the value | 787 * @param name the name of the value |
| 770 * @param child the value | 788 * @param child the value |
| 771 * @retval zero success | 789 * @retval zero success |
| 772 * @retval non-zero allocation failure | 790 * @retval non-zero allocation failure |
| 773 */ | 791 */ |
| 774 cx_attr_nonnull | 792 cx_attr_nonnull |
| 775 CX_EXPORT int cxJsonObjPut(CxJsonValue* obj, cxstring name, CxJsonValue* child); | 793 CX_EXPORT int cx_json_obj_put(CxJsonValue* obj, cxstring name, CxJsonValue* child); |
| 794 | |
| 795 /** | |
| 796 * Adds or replaces a value within a JSON object. | |
| 797 * | |
| 798 * The value will be directly added and not copied. | |
| 799 * | |
| 800 * @note If a value with the specified @p name already exists, | |
| 801 * it will be (recursively) freed with its own allocator. | |
| 802 * | |
| 803 * @param obj (@c CxJsonValue*) the JSON object | |
| 804 * @param name (any string) the name of the value | |
| 805 * @param child (@c CxJsonValue*) the value | |
| 806 * @retval zero success | |
| 807 * @retval non-zero allocation failure | |
| 808 */ | |
| 809 #define cxJsonObjPut(obj, name, child) cx_json_obj_put(obj, cx_strcast(name), child) | |
| 776 | 810 |
| 777 /** | 811 /** |
| 778 * Creates a new JSON object and adds it to an existing object. | 812 * Creates a new JSON object and adds it to an existing object. |
| 813 * | |
| 814 * Internal function - use cxJsonObjPutObj(). | |
| 779 * | 815 * |
| 780 * @param obj the target JSON object | 816 * @param obj the target JSON object |
| 781 * @param name the name of the new value | 817 * @param name the name of the new value |
| 782 * @return the new value or @c NULL if allocation fails | 818 * @return the new value or @c NULL if allocation fails |
| 783 * @see cxJsonObjPut() | 819 * @see cxJsonObjPut() |
| 784 * @see cxJsonCreateObj() | 820 * @see cxJsonCreateObj() |
| 785 */ | 821 */ |
| 786 cx_attr_nonnull | 822 cx_attr_nonnull |
| 787 CX_EXPORT CxJsonValue* cxJsonObjPutObj(CxJsonValue* obj, cxstring name); | 823 CX_EXPORT CxJsonValue* cx_json_obj_put_obj(CxJsonValue* obj, cxstring name); |
| 824 | |
| 825 /** | |
| 826 * Creates a new JSON object and adds it to an existing object. | |
| 827 * | |
| 828 * @param obj (@c CxJsonValue*) the target JSON object | |
| 829 * @param name (any string) the name of the new value | |
| 830 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails | |
| 831 * @see cxJsonObjPut() | |
| 832 * @see cxJsonCreateObj() | |
| 833 */ | |
| 834 #define cxJsonObjPutObj(obj, name) cx_json_obj_put_obj(obj, cx_strcast(name)) | |
| 788 | 835 |
| 789 /** | 836 /** |
| 790 * Creates a new JSON array and adds it to an object. | 837 * Creates a new JSON array and adds it to an object. |
| 838 * | |
| 839 * Internal function - use cxJsonObjPutArr(). | |
| 791 * | 840 * |
| 792 * @param obj the target JSON object | 841 * @param obj the target JSON object |
| 793 * @param name the name of the new value | 842 * @param name the name of the new value |
| 794 * @return the new value or @c NULL if allocation fails | 843 * @return the new value or @c NULL if allocation fails |
| 795 * @see cxJsonObjPut() | 844 * @see cxJsonObjPut() |
| 796 * @see cxJsonCreateArr() | 845 * @see cxJsonCreateArr() |
| 797 */ | 846 */ |
| 798 cx_attr_nonnull | 847 cx_attr_nonnull |
| 799 CX_EXPORT CxJsonValue* cxJsonObjPutArr(CxJsonValue* obj, cxstring name); | 848 CX_EXPORT CxJsonValue* cx_json_obj_put_arr(CxJsonValue* obj, cxstring name); |
| 849 | |
| 850 /** | |
| 851 * Creates a new JSON array and adds it to an object. | |
| 852 * | |
| 853 * @param obj (@c CxJsonValue*) the target JSON object | |
| 854 * @param name (any string) the name of the new value | |
| 855 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails | |
| 856 * @see cxJsonObjPut() | |
| 857 * @see cxJsonCreateArr() | |
| 858 */ | |
| 859 #define cxJsonObjPutArr(obj, name) cx_json_obj_put_arr(obj, cx_strcast(name)) | |
| 800 | 860 |
| 801 /** | 861 /** |
| 802 * Creates a new JSON number and adds it to an object. | 862 * Creates a new JSON number and adds it to an object. |
| 863 * | |
| 864 * Internal function - use cxJsonObjPutNumber(). | |
| 803 * | 865 * |
| 804 * @param obj the target JSON object | 866 * @param obj the target JSON object |
| 805 * @param name the name of the new value | 867 * @param name the name of the new value |
| 806 * @param num the numeric value | 868 * @param num the numeric value |
| 807 * @return the new value or @c NULL if allocation fails | 869 * @return the new value or @c NULL if allocation fails |
| 808 * @see cxJsonObjPut() | 870 * @see cxJsonObjPut() |
| 809 * @see cxJsonCreateNumber() | 871 * @see cxJsonCreateNumber() |
| 810 */ | 872 */ |
| 811 cx_attr_nonnull | 873 cx_attr_nonnull |
| 812 CX_EXPORT CxJsonValue* cxJsonObjPutNumber(CxJsonValue* obj, cxstring name, double num); | 874 CX_EXPORT CxJsonValue* cx_json_obj_put_number(CxJsonValue* obj, cxstring name, double num); |
| 875 | |
| 876 /** | |
| 877 * Creates a new JSON number and adds it to an object. | |
| 878 * | |
| 879 * @param obj (@c CxJsonValue*) the target JSON object | |
| 880 * @param name (any string) the name of the new value | |
| 881 * @param num (@c double) the numeric value | |
| 882 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails | |
| 883 * @see cxJsonObjPut() | |
| 884 * @see cxJsonCreateNumber() | |
| 885 */ | |
| 886 #define cxJsonObjPutNumber(obj, name, num) cx_json_obj_put_number(obj, cx_strcast(name), num) | |
| 813 | 887 |
| 814 /** | 888 /** |
| 815 * Creates a new JSON number, based on an integer, and adds it to an object. | 889 * Creates a new JSON number, based on an integer, and adds it to an object. |
| 890 * | |
| 891 * Internal function - use cxJsonObjPutInteger(). | |
| 816 * | 892 * |
| 817 * @param obj the target JSON object | 893 * @param obj the target JSON object |
| 818 * @param name the name of the new value | 894 * @param name the name of the new value |
| 819 * @param num the numeric value | 895 * @param num the numeric value |
| 820 * @return the new value or @c NULL if allocation fails | 896 * @return the new value or @c NULL if allocation fails |
| 821 * @see cxJsonObjPut() | 897 * @see cxJsonObjPut() |
| 822 * @see cxJsonCreateInteger() | 898 * @see cxJsonCreateInteger() |
| 823 */ | 899 */ |
| 824 cx_attr_nonnull | 900 cx_attr_nonnull |
| 825 CX_EXPORT CxJsonValue* cxJsonObjPutInteger(CxJsonValue* obj, cxstring name, int64_t num); | 901 CX_EXPORT CxJsonValue* cx_json_obj_put_integer(CxJsonValue* obj, cxstring name, int64_t num); |
| 902 | |
| 903 /** | |
| 904 * Creates a new JSON number, based on an integer, and adds it to an object. | |
| 905 * | |
| 906 * @param obj (@c CxJsonValue*) the target JSON object | |
| 907 * @param name (any string) the name of the new value | |
| 908 * @param num (@c int64_t) the numeric value | |
| 909 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails | |
| 910 * @see cxJsonObjPut() | |
| 911 * @see cxJsonCreateInteger() | |
| 912 */ | |
| 913 #define cxJsonObjPutInteger(obj, name, num) cx_json_obj_put_integer(obj, cx_strcast(name), num) | |
| 826 | 914 |
| 827 /** | 915 /** |
| 828 * Creates a new JSON string and adds it to an object. | 916 * Creates a new JSON string and adds it to an object. |
| 829 * | 917 * |
| 830 * The string data is copied. | 918 * Internal function - use cxJsonObjPutString() |
| 831 * | 919 * |
| 832 * @param obj the target JSON object | 920 * @param obj the target JSON object |
| 833 * @param name the name of the new value | 921 * @param name the name of the new value |
| 834 * @param str the string data | 922 * @param str the string data |
| 835 * @return the new value or @c NULL if allocation fails | 923 * @return the new value or @c NULL if allocation fails |
| 836 * @see cxJsonObjPut() | 924 * @see cxJsonObjPut() |
| 837 * @see cxJsonCreateString() | 925 * @see cxJsonCreateString() |
| 838 */ | 926 */ |
| 839 cx_attr_nonnull cx_attr_cstr_arg(3) | 927 cx_attr_nonnull |
| 840 CX_EXPORT CxJsonValue* cxJsonObjPutString(CxJsonValue* obj, cxstring name, const char* str); | 928 CX_EXPORT CxJsonValue* cx_json_obj_put_string(CxJsonValue* obj, cxstring name, cxstring str); |
| 841 | 929 |
| 842 /** | 930 /** |
| 843 * Creates a new JSON string and adds it to an object. | 931 * Creates a new JSON string and adds it to an object. |
| 844 * | 932 * |
| 845 * The string data is copied. | 933 * The string data is copied. |
| 846 * | 934 * |
| 847 * @param obj the target JSON object | 935 * @param obj (@c CxJsonValue*) the target JSON object |
| 848 * @param name the name of the new value | 936 * @param name (any string) the name of the new value |
| 849 * @param str the string data | 937 * @param str (any string) the string data |
| 850 * @return the new value or @c NULL if allocation fails | 938 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails |
| 851 * @see cxJsonObjPut() | 939 * @see cxJsonObjPut() |
| 852 * @see cxJsonCreateCxString() | 940 * @see cxJsonCreateString() |
| 853 */ | 941 */ |
| 854 cx_attr_nonnull | 942 #define cxJsonObjPutString(obj, name, str) cx_json_obj_put_string(obj, cx_strcast(name), cx_strcast(str)) |
| 855 CX_EXPORT CxJsonValue* cxJsonObjPutCxString(CxJsonValue* obj, cxstring name, cxstring str); | |
| 856 | 943 |
| 857 /** | 944 /** |
| 858 * Creates a new JSON literal and adds it to an object. | 945 * Creates a new JSON literal and adds it to an object. |
| 946 * | |
| 947 * Internal function - use cxJsonObjPutLiteral(). | |
| 859 * | 948 * |
| 860 * @param obj the target JSON object | 949 * @param obj the target JSON object |
| 861 * @param name the name of the new value | 950 * @param name the name of the new value |
| 862 * @param lit the type of literal | 951 * @param lit the type of literal |
| 863 * @return the new value or @c NULL if allocation fails | 952 * @return the new value or @c NULL if allocation fails |
| 864 * @see cxJsonObjPut() | 953 * @see cxJsonObjPut() |
| 865 * @see cxJsonCreateLiteral() | 954 * @see cxJsonCreateLiteral() |
| 866 */ | 955 */ |
| 867 cx_attr_nonnull | 956 cx_attr_nonnull |
| 868 CX_EXPORT CxJsonValue* cxJsonObjPutLiteral(CxJsonValue* obj, cxstring name, CxJsonLiteral lit); | 957 CX_EXPORT CxJsonValue* cx_json_obj_put_literal(CxJsonValue* obj, cxstring name, CxJsonLiteral lit); |
| 958 | |
| 959 /** | |
| 960 * Creates a new JSON literal and adds it to an object. | |
| 961 * | |
| 962 * @param obj (@c CxJsonValue*) the target JSON object | |
| 963 * @param name (any string) the name of the new value | |
| 964 * @param lit (@c CxJsonLiteral) the type of literal | |
| 965 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails | |
| 966 * @see cxJsonObjPut() | |
| 967 * @see cxJsonCreateLiteral() | |
| 968 */ | |
| 969 #define cxJsonObjPutLiteral(obj, name, lit) cx_json_obj_put_literal(obj, cx_strcast(name), lit) | |
| 869 | 970 |
| 870 /** | 971 /** |
| 871 * Recursively deallocates the memory of a JSON value. | 972 * Recursively deallocates the memory of a JSON value. |
| 872 * | 973 * |
| 873 * @remark The type of each deallocated value will be changed | 974 * @remark The type of each deallocated value will be changed |
| 996 * @see cxJsonIsTrue() | 1097 * @see cxJsonIsTrue() |
| 997 * @see cxJsonIsFalse() | 1098 * @see cxJsonIsFalse() |
| 998 */ | 1099 */ |
| 999 cx_attr_nonnull | 1100 cx_attr_nonnull |
| 1000 CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) { | 1101 CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) { |
| 1001 return cxJsonIsLiteral(value) && value->value.literal != CX_JSON_NULL; | 1102 return cxJsonIsLiteral(value) && value->literal != CX_JSON_NULL; |
| 1002 } | 1103 } |
| 1003 | 1104 |
| 1004 /** | 1105 /** |
| 1005 * Checks if the specified value is @c true. | 1106 * Checks if the specified value is @c true. |
| 1006 * | 1107 * |
| 1013 * @see cxJsonIsBool() | 1114 * @see cxJsonIsBool() |
| 1014 * @see cxJsonIsFalse() | 1115 * @see cxJsonIsFalse() |
| 1015 */ | 1116 */ |
| 1016 cx_attr_nonnull | 1117 cx_attr_nonnull |
| 1017 CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) { | 1118 CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) { |
| 1018 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_TRUE; | 1119 return cxJsonIsLiteral(value) && value->literal == CX_JSON_TRUE; |
| 1019 } | 1120 } |
| 1020 | 1121 |
| 1021 /** | 1122 /** |
| 1022 * Checks if the specified value is @c false. | 1123 * Checks if the specified value is @c false. |
| 1023 * | 1124 * |
| 1030 * @see cxJsonIsBool() | 1131 * @see cxJsonIsBool() |
| 1031 * @see cxJsonIsTrue() | 1132 * @see cxJsonIsTrue() |
| 1032 */ | 1133 */ |
| 1033 cx_attr_nonnull | 1134 cx_attr_nonnull |
| 1034 CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) { | 1135 CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) { |
| 1035 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_FALSE; | 1136 return cxJsonIsLiteral(value) && value->literal == CX_JSON_FALSE; |
| 1036 } | 1137 } |
| 1037 | 1138 |
| 1038 /** | 1139 /** |
| 1039 * Checks if the specified value is @c null. | 1140 * Checks if the specified value is @c null. |
| 1040 * | 1141 * |
| 1043 * @retval false otherwise | 1144 * @retval false otherwise |
| 1044 * @see cxJsonIsLiteral() | 1145 * @see cxJsonIsLiteral() |
| 1045 */ | 1146 */ |
| 1046 cx_attr_nonnull | 1147 cx_attr_nonnull |
| 1047 CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) { | 1148 CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) { |
| 1048 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_NULL; | 1149 return cxJsonIsLiteral(value) && value->literal == CX_JSON_NULL; |
| 1049 } | 1150 } |
| 1050 | 1151 |
| 1051 /** | 1152 /** |
| 1052 * Obtains a C string from the given JSON value. | 1153 * Obtains a C string from the given JSON value. |
| 1053 * | 1154 * |
| 1121 * @return the value represented as double | 1222 * @return the value represented as double |
| 1122 * @see cxJsonIsLiteral() | 1223 * @see cxJsonIsLiteral() |
| 1123 */ | 1224 */ |
| 1124 cx_attr_nonnull | 1225 cx_attr_nonnull |
| 1125 CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) { | 1226 CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) { |
| 1126 return value->value.literal == CX_JSON_TRUE; | 1227 return value->literal == CX_JSON_TRUE; |
| 1127 } | 1228 } |
| 1128 | 1229 |
| 1129 /** | 1230 /** |
| 1130 * Returns the size of a JSON array. | 1231 * Returns the size of a JSON array. |
| 1131 * | 1232 * |
| 1135 * @return the size of the array | 1236 * @return the size of the array |
| 1136 * @see cxJsonIsArray() | 1237 * @see cxJsonIsArray() |
| 1137 */ | 1238 */ |
| 1138 cx_attr_nonnull | 1239 cx_attr_nonnull |
| 1139 CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) { | 1240 CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) { |
| 1140 return value->value.array.array_size; | 1241 return value->array.data_size; |
| 1141 } | 1242 } |
| 1142 | 1243 |
| 1143 /** | 1244 /** |
| 1144 * Returns an element from a JSON array. | 1245 * Returns an element from a JSON array. |
| 1145 * | 1246 * |
| 1186 */ | 1287 */ |
| 1187 cx_attr_nonnull cx_attr_nodiscard | 1288 cx_attr_nonnull cx_attr_nodiscard |
| 1188 CX_EXPORT CxIterator cxJsonArrIter(const CxJsonValue *value); | 1289 CX_EXPORT CxIterator cxJsonArrIter(const CxJsonValue *value); |
| 1189 | 1290 |
| 1190 /** | 1291 /** |
| 1191 * Returns an iterator over the JSON object members. | 1292 * Returns the size of a JSON object. |
| 1192 * | 1293 * |
| 1193 * The iterator yields values of type @c CxJsonObjValue* which | 1294 * If the @p value is not a JSON object, the behavior is undefined. |
| 1194 * contain the name and value of the member. | 1295 * |
| 1296 * @param value the JSON value | |
| 1297 * @return the size of the object, i.e., the number of key/value pairs | |
| 1298 * @see cxJsonIsObject() | |
| 1299 */ | |
| 1300 cx_attr_nonnull | |
| 1301 CX_INLINE size_t cxJsonObjSize(const CxJsonValue *value) { | |
| 1302 return cxCollectionSize(value->object); | |
| 1303 } | |
| 1304 | |
| 1305 /** | |
| 1306 * Returns a map iterator over the JSON object members. | |
| 1307 * | |
| 1308 * The iterator yields values of type @c CxMapEntry* which | |
| 1309 * contain the name and the @c CxJsonObjValue* of the member. | |
| 1195 * | 1310 * |
| 1196 * If the @p value is not a JSON object, the behavior is undefined. | 1311 * If the @p value is not a JSON object, the behavior is undefined. |
| 1197 * | 1312 * |
| 1198 * @param value the JSON value | 1313 * @param value the JSON value |
| 1199 * @return an iterator over the object members | 1314 * @return an iterator over the object members |
| 1200 * @see cxJsonIsObject() | 1315 * @see cxJsonIsObject() |
| 1201 */ | 1316 */ |
| 1202 cx_attr_nonnull cx_attr_nodiscard | 1317 cx_attr_nonnull cx_attr_nodiscard |
| 1203 CX_EXPORT CxIterator cxJsonObjIter(const CxJsonValue *value); | 1318 CX_EXPORT CxMapIterator cxJsonObjIter(const CxJsonValue *value); |
| 1204 | 1319 |
| 1205 /** | 1320 /** |
| 1206 * Internal function, do not use. | 1321 * Internal function, do not use. |
| 1207 * @param value the JSON object | 1322 * @param value the JSON object |
| 1208 * @param name the key to look up | 1323 * @param name the key to look up |