src/cx/json.h

changeset 1675
36c0fb2b60b2
parent 1667
608cc0b25352
equal deleted inserted replaced
1674:8b0f162ac88e 1675:36c0fb2b60b2
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 #include "map.h"
45 45
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49
50
51 /** 46 /**
52 * The type of the parsed token. 47 * The type of the parsed token.
53 */ 48 */
54 enum cx_json_token_type { 49 enum cx_json_token_type {
55 /** 50 /**
112 enum cx_json_value_type { 107 enum cx_json_value_type {
113 /** 108 /**
114 * Reserved. 109 * Reserved.
115 */ 110 */
116 CX_JSON_NOTHING, // this allows us to always return non-NULL values 111 CX_JSON_NOTHING, // this allows us to always return non-NULL values
112 /**
113 * No meaningful data.
114 */
115 CX_JSON_UNINITIALIZED,
117 /** 116 /**
118 * A JSON object. 117 * A JSON object.
119 */ 118 */
120 CX_JSON_OBJECT, 119 CX_JSON_OBJECT,
121 /** 120 /**
425 /** 424 /**
426 * Creates a default writer configuration for compact output. 425 * Creates a default writer configuration for compact output.
427 * 426 *
428 * @return new JSON writer settings 427 * @return new JSON writer settings
429 */ 428 */
430 cx_attr_nodiscard 429 CX_EXTERN CX_NODISCARD
431 CX_EXPORT CxJsonWriter cxJsonWriterCompact(void); 430 CxJsonWriter cxJsonWriterCompact(void);
432 431
433 /** 432 /**
434 * Creates a default writer configuration for pretty output. 433 * Creates a default writer configuration for pretty output.
435 * 434 *
436 * @param use_spaces false if you want tabs, true if you want four spaces instead 435 * @param use_spaces false if you want tabs, true if you want four spaces instead
437 * @return new JSON writer settings 436 * @return new JSON writer settings
438 */ 437 */
439 cx_attr_nodiscard 438 CX_EXTERN CX_NODISCARD
440 CX_EXPORT CxJsonWriter cxJsonWriterPretty(bool use_spaces); 439 CxJsonWriter cxJsonWriterPretty(bool use_spaces);
441 440
442 /** 441 /**
443 * Writes a JSON value to a buffer or stream. 442 * Writes a JSON value to a buffer or stream.
444 * 443 *
445 * This function blocks until either all data is written, or an error occurs. 444 * This function blocks until either all data is written, or an error occurs.
455 * @param wfunc the write function to use 454 * @param wfunc the write function to use
456 * @param settings formatting settings (or @c NULL to use a compact default) 455 * @param settings formatting settings (or @c NULL to use a compact default)
457 * @retval zero success 456 * @retval zero success
458 * @retval non-zero when no or not all data could be written 457 * @retval non-zero when no or not all data could be written
459 */ 458 */
460 cx_attr_nonnull_arg(1, 2, 3) 459 CX_EXTERN CX_NONNULL_ARG(1, 2, 3)
461 CX_EXPORT int cxJsonWrite(void* target, const CxJsonValue* value, 460 int cxJsonWrite(void* target, const CxJsonValue* value,
462 cx_write_func wfunc, const CxJsonWriter* settings); 461 cx_write_func wfunc, const CxJsonWriter* settings);
463 462
464 463
465 /** 464 /**
466 * Produces a compact string representation of the specified JSON value. 465 * Produces a compact string representation of the specified JSON value.
470 * @return the produced string 469 * @return the produced string
471 * @see cxJsonWrite() 470 * @see cxJsonWrite()
472 * @see cxJsonWriterCompact() 471 * @see cxJsonWriterCompact()
473 * @see cxJsonToPrettyString() 472 * @see cxJsonToPrettyString()
474 */ 473 */
475 cx_attr_nonnull_arg(2) 474 CX_EXTERN CX_NONNULL_ARG(2) CX_NODISCARD
476 CX_EXPORT cxmutstr cxJsonToString(const CxAllocator *allocator, CxJsonValue *value); 475 cxmutstr cxJsonToString(const CxAllocator *allocator, CxJsonValue *value);
477 476
478 /** 477 /**
479 * Produces a pretty string representation of the specified JSON value. 478 * Produces a pretty string representation of the specified JSON value.
480 * 479 *
481 * @param allocator the allocator for the string 480 * @param allocator the allocator for the string
483 * @return the produced string 482 * @return the produced string
484 * @see cxJsonWrite() 483 * @see cxJsonWrite()
485 * @see cxJsonWriterPretty() 484 * @see cxJsonWriterPretty()
486 * @see cxJsonToString() 485 * @see cxJsonToString()
487 */ 486 */
488 cx_attr_nonnull_arg(2) 487 CX_EXTERN CX_NONNULL_ARG(2) CX_NODISCARD
489 CX_EXPORT cxmutstr cxJsonToPrettyString(const CxAllocator *allocator, CxJsonValue *value); 488 cxmutstr cxJsonToPrettyString(const CxAllocator *allocator, CxJsonValue *value);
490 489
491 /** 490 /**
492 * Initializes the JSON interface. 491 * Initializes the JSON interface.
493 * 492 *
494 * @param json the JSON interface 493 * @param json the JSON interface
495 * @param allocator the allocator that shall be used for the produced values 494 * @param allocator the allocator that shall be used for the produced values
496 * @see cxJsonDestroy() 495 * @see cxJsonDestroy()
497 */ 496 */
498 cx_attr_nonnull_arg(1) 497 CX_EXTERN CX_NONNULL_ARG(1)
499 CX_EXPORT void cxJsonInit(CxJson *json, const CxAllocator *allocator); 498 void cxJsonInit(CxJson *json, const CxAllocator *allocator);
500 499
501 /** 500 /**
502 * Destroys the JSON interface. 501 * Destroys the JSON interface.
503 * 502 *
504 * @param json the JSON interface 503 * @param json the JSON interface
505 * @see cxJsonInit() 504 * @see cxJsonInit()
506 */ 505 */
507 cx_attr_nonnull 506 CX_EXTERN CX_NONNULL
508 CX_EXPORT void cxJsonDestroy(CxJson *json); 507 void cxJsonDestroy(CxJson *json);
509 508
510 /** 509 /**
511 * Destroys and re-initializes the JSON interface. 510 * Destroys and re-initializes the JSON interface.
512 * 511 *
513 * You must use this to reset the parser after encountering a syntax error 512 * You must use this to reset the parser after encountering a syntax error
514 * if you want to continue using it. 513 * if you want to continue using it.
515 * 514 *
516 * @param json the JSON interface 515 * @param json the JSON interface
517 */ 516 */
518 cx_attr_nonnull 517 CX_EXTERN CX_NONNULL
519 CX_EXPORT void cxJsonReset(CxJson *json); 518 void cxJsonReset(CxJson *json);
520 519
521 /** 520 /**
522 * Fills the input buffer. 521 * Fills the input buffer.
523 * 522 *
524 * @remark The JSON interface tries to avoid copying the input data. 523 * @remark The JSON interface tries to avoid copying the input data.
534 * @param len the length of the source buffer 533 * @param len the length of the source buffer
535 * @retval zero success 534 * @retval zero success
536 * @retval non-zero internal allocation error 535 * @retval non-zero internal allocation error
537 * @see cxJsonFill() 536 * @see cxJsonFill()
538 */ 537 */
539 cx_attr_nonnull_arg(1) cx_attr_access_r(2, 3) 538 CX_EXTERN CX_NONNULL_ARG(1) CX_ACCESS_R(2, 3)
540 CX_EXPORT int cxJsonFilln(CxJson *json, const char *buf, size_t len); 539 int cxJsonFilln(CxJson *json, const char *buf, size_t len);
541 540
542 541
543 /** 542 /**
544 * Internal function, do not use. 543 * Internal function, do not use.
545 * 544 *
546 * @param json the JSON interface 545 * @param json the JSON interface
547 * @param str the string 546 * @param str the string
548 * @retval zero success 547 * @retval zero success
549 * @retval non-zero internal allocation error 548 * @retval non-zero internal allocation error
550 */ 549 */
551 cx_attr_nonnull 550 CX_NONNULL CX_INLINE
552 CX_INLINE int cx_json_fill(CxJson *json, cxstring str) { 551 int cx_json_fill(CxJson *json, cxstring str) {
553 return cxJsonFilln(json, str.ptr, str.length); 552 return cxJsonFilln(json, str.ptr, str.length);
554 } 553 }
555 554
556 /** 555 /**
557 * Fills the input buffer. 556 * Fills the input buffer.
579 * @param allocator the allocator for the JSON value 578 * @param allocator the allocator for the JSON value
580 * @param str the string to parse 579 * @param str the string to parse
581 * @param value a pointer where the JSON value shall be stored to 580 * @param value a pointer where the JSON value shall be stored to
582 * @return status code 581 * @return status code
583 */ 582 */
584 cx_attr_nonnull_arg(3) 583 CX_EXTERN CX_NONNULL_ARG(3) CX_ACCESS_W(3)
585 CX_EXPORT CxJsonStatus cx_json_from_string(const CxAllocator *allocator, 584 CxJsonStatus cx_json_from_string(const CxAllocator *allocator,
586 cxstring str, CxJsonValue **value); 585 cxstring str, CxJsonValue **value);
587 586
588 /** 587 /**
589 * Parses a string into a JSON value. 588 * Parses a string into a JSON value.
590 * 589 *
601 */ 600 */
602 #define cxJsonFromString(allocator, str, value) \ 601 #define cxJsonFromString(allocator, str, value) \
603 cx_json_from_string(allocator, cx_strcast(str), value) 602 cx_json_from_string(allocator, cx_strcast(str), value)
604 603
605 /** 604 /**
605 * Recursively deallocates the memory of a JSON value.
606 *
607 * @remark The type of each deallocated value will be changed
608 * to #CX_JSON_NOTHING, and values of such a type will be skipped
609 * by the deallocation. That means this function protects
610 * you from double-frees when you are accidentally freeing
611 * a nested value and then the parent value (or vice versa).
612 *
613 * @param value the value
614 */
615 CX_EXTERN
616 void cxJsonValueFree(CxJsonValue *value);
617
618 /**
606 * Creates a new (empty) JSON object. 619 * Creates a new (empty) JSON object.
607 * 620 *
608 * @param allocator the allocator to use 621 * @param allocator the allocator to use
609 * @return the new JSON object or @c NULL if allocation fails 622 * @return the new JSON object or @c NULL if allocation fails
610 * @see cxJsonObjPutObj() 623 * @see cxJsonObjPutObj()
611 * @see cxJsonArrAddValues() 624 * @see cxJsonArrAddValues()
612 */ 625 */
613 cx_attr_nodiscard 626 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
614 CX_EXPORT CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator); 627 CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator);
615 628
616 /** 629 /**
617 * Creates a new (empty) JSON array. 630 * Creates a new (empty) JSON array.
618 * 631 *
619 * Optionally, this function already allocates memory with the given capacity. 632 * Optionally, this function already allocates memory with the given capacity.
622 * @param capacity optional capacity or zero if it's unknown how many elements the array will have 635 * @param capacity optional capacity or zero if it's unknown how many elements the array will have
623 * @return the new JSON array or @c NULL if allocation fails 636 * @return the new JSON array or @c NULL if allocation fails
624 * @see cxJsonObjPutArr() 637 * @see cxJsonObjPutArr()
625 * @see cxJsonArrAddValues() 638 * @see cxJsonArrAddValues()
626 */ 639 */
627 cx_attr_nodiscard 640 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
628 CX_EXPORT CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator, size_t capacity); 641 CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator, size_t capacity);
629 642
630 /** 643 /**
631 * Creates a new JSON number value. 644 * Creates a new JSON number value.
632 * 645 *
633 * @param allocator the allocator to use 646 * @param allocator the allocator to use
634 * @param num the numeric value 647 * @param num the numeric value
635 * @return the new JSON value or @c NULL if allocation fails 648 * @return the new JSON value or @c NULL if allocation fails
636 * @see cxJsonObjPutNumber() 649 * @see cxJsonObjPutNumber()
637 * @see cxJsonArrAddNumbers() 650 * @see cxJsonArrAddNumbers()
638 */ 651 */
639 cx_attr_nodiscard 652 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
640 CX_EXPORT CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num); 653 CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num);
641 654
642 /** 655 /**
643 * Creates a new JSON number value based on an integer. 656 * Creates a new JSON number value based on an integer.
644 * 657 *
645 * @param allocator the allocator to use 658 * @param allocator the allocator to use
646 * @param num the numeric value 659 * @param num the numeric value
647 * @return the new JSON value or @c NULL if allocation fails 660 * @return the new JSON value or @c NULL if allocation fails
648 * @see cxJsonObjPutInteger() 661 * @see cxJsonObjPutInteger()
649 * @see cxJsonArrAddIntegers() 662 * @see cxJsonArrAddIntegers()
650 */ 663 */
651 cx_attr_nodiscard 664 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
652 CX_EXPORT CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num); 665 CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num);
653 666
654 /** 667 /**
655 * Creates a new JSON string. 668 * Creates a new JSON string.
656 * 669 *
657 * Internal function - use cxJsonCreateString() instead. 670 * Internal function - use cxJsonCreateString() instead.
660 * @param str the string data 673 * @param str the string data
661 * @return the new JSON value or @c NULL if allocation fails 674 * @return the new JSON value or @c NULL if allocation fails
662 * @see cxJsonObjPutString() 675 * @see cxJsonObjPutString()
663 * @see cxJsonArrAddCxStrings() 676 * @see cxJsonArrAddCxStrings()
664 */ 677 */
665 cx_attr_nodiscard 678 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
666 CX_EXPORT CxJsonValue* cx_json_create_string(const CxAllocator* allocator, cxstring str); 679 CxJsonValue* cx_json_create_string(const CxAllocator* allocator, cxstring str);
667 680
668 /** 681 /**
669 * Creates a new JSON string. 682 * Creates a new JSON string.
670 * 683 *
671 * @param allocator (@c CxAllocator*) the allocator to use 684 * @param allocator (@c CxAllocator*) the allocator to use
683 * @param lit the type of literal 696 * @param lit the type of literal
684 * @return the new JSON value or @c NULL if allocation fails 697 * @return the new JSON value or @c NULL if allocation fails
685 * @see cxJsonObjPutLiteral() 698 * @see cxJsonObjPutLiteral()
686 * @see cxJsonArrAddLiterals() 699 * @see cxJsonArrAddLiterals()
687 */ 700 */
688 cx_attr_nodiscard 701 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
689 CX_EXPORT CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit); 702 CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit);
690 703
691 /** 704 /**
692 * Adds number values to a JSON array. 705 * Adds number values to a JSON array.
693 * 706 *
694 * @param arr the JSON array 707 * @param arr the JSON array
695 * @param num the array of values 708 * @param num the array of values
696 * @param count the number of elements 709 * @param count the number of elements
697 * @retval zero success 710 * @retval zero success
698 * @retval non-zero allocation failure 711 * @retval non-zero allocation failure
699 */ 712 */
700 cx_attr_nonnull cx_attr_access_r(2, 3) 713 CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
701 CX_EXPORT int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count); 714 int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count);
702 715
703 /** 716 /**
704 * Adds number values, of which all are integers, to a JSON array. 717 * Adds number values, of which all are integers, to a JSON array.
705 * 718 *
706 * @param arr the JSON array 719 * @param arr the JSON array
707 * @param num the array of values 720 * @param num the array of values
708 * @param count the number of elements 721 * @param count the number of elements
709 * @retval zero success 722 * @retval zero success
710 * @retval non-zero allocation failure 723 * @retval non-zero allocation failure
711 */ 724 */
712 cx_attr_nonnull cx_attr_access_r(2, 3) 725 CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
713 CX_EXPORT int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count); 726 int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count);
714 727
715 /** 728 /**
716 * Adds strings to a JSON array. 729 * Adds strings to a JSON array.
717 * 730 *
718 * The strings will be copied with the allocator of the array. 731 * The strings will be copied with the allocator of the array.
722 * @param count the number of elements 735 * @param count the number of elements
723 * @retval zero success 736 * @retval zero success
724 * @retval non-zero allocation failure 737 * @retval non-zero allocation failure
725 * @see cxJsonArrAddCxStrings() 738 * @see cxJsonArrAddCxStrings()
726 */ 739 */
727 cx_attr_nonnull cx_attr_access_r(2, 3) 740 CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
728 CX_EXPORT int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count); 741 int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count);
729 742
730 /** 743 /**
731 * Adds strings to a JSON array. 744 * Adds strings to a JSON array.
732 * 745 *
733 * The strings will be copied with the allocator of the array. 746 * The strings will be copied with the allocator of the array.
737 * @param count the number of elements 750 * @param count the number of elements
738 * @retval zero success 751 * @retval zero success
739 * @retval non-zero allocation failure 752 * @retval non-zero allocation failure
740 * @see cxJsonArrAddStrings() 753 * @see cxJsonArrAddStrings()
741 */ 754 */
742 cx_attr_nonnull cx_attr_access_r(2, 3) 755 CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
743 CX_EXPORT int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count); 756 int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count);
744 757
745 /** 758 /**
746 * Adds literals to a JSON array. 759 * Adds literals to a JSON array.
747 * 760 *
748 * @param arr the JSON array 761 * @param arr the JSON array
749 * @param lit the array of literal types 762 * @param lit the array of literal types
750 * @param count the number of elements 763 * @param count the number of elements
751 * @retval zero success 764 * @retval zero success
752 * @retval non-zero allocation failure 765 * @retval non-zero allocation failure
753 */ 766 */
754 cx_attr_nonnull cx_attr_access_r(2, 3) 767 CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
755 CX_EXPORT int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count); 768 int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count);
756 769
757 /** 770 /**
758 * Add arbitrary values to a JSON array. 771 * Add arbitrary values to a JSON array.
759 * 772 *
760 * @attention In contrast to all other add functions, this function adds the values 773 * @attention In contrast to all other add functions, this function adds the values
764 * @param val the values 777 * @param val the values
765 * @param count the number of elements 778 * @param count the number of elements
766 * @retval zero success 779 * @retval zero success
767 * @retval non-zero allocation failure 780 * @retval non-zero allocation failure
768 */ 781 */
769 cx_attr_nonnull cx_attr_access_r(2, 3) 782 CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
770 CX_EXPORT int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count); 783 int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count);
771 784
772 /** 785 /**
773 * Adds or replaces a value within a JSON object. 786 * Adds or replaces a value within a JSON object.
774 * 787 *
775 * Internal function - use cxJsonObjPut(). 788 * Internal function - use cxJsonObjPut().
778 * @param name the name of the value 791 * @param name the name of the value
779 * @param child the value 792 * @param child the value
780 * @retval zero success 793 * @retval zero success
781 * @retval non-zero allocation failure 794 * @retval non-zero allocation failure
782 */ 795 */
783 cx_attr_nonnull 796 CX_EXTERN CX_NONNULL
784 CX_EXPORT int cx_json_obj_put(CxJsonValue* obj, cxstring name, CxJsonValue* child); 797 int cx_json_obj_put(CxJsonValue* obj, cxstring name, CxJsonValue* child);
785 798
786 /** 799 /**
787 * Adds or replaces a value within a JSON object. 800 * Adds or replaces a value within a JSON object.
788 * 801 *
789 * The value will be directly added and not copied. 802 * The value will be directly added and not copied.
808 * @param name the name of the new value 821 * @param name the name of the new value
809 * @return the new value or @c NULL if allocation fails 822 * @return the new value or @c NULL if allocation fails
810 * @see cxJsonObjPut() 823 * @see cxJsonObjPut()
811 * @see cxJsonCreateObj() 824 * @see cxJsonCreateObj()
812 */ 825 */
813 cx_attr_nonnull 826 CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
814 CX_EXPORT CxJsonValue* cx_json_obj_put_obj(CxJsonValue* obj, cxstring name); 827 CxJsonValue* cx_json_obj_put_obj(CxJsonValue* obj, cxstring name);
815 828
816 /** 829 /**
817 * Creates a new JSON object and adds it to an existing object. 830 * Creates a new JSON object and adds it to an existing object.
818 * 831 *
819 * @param obj (@c CxJsonValue*) the target JSON object 832 * @param obj (@c CxJsonValue*) the target JSON object
834 * @param capacity optional initial capacity 847 * @param capacity optional initial capacity
835 * @return the new value or @c NULL if allocation fails 848 * @return the new value or @c NULL if allocation fails
836 * @see cxJsonObjPut() 849 * @see cxJsonObjPut()
837 * @see cxJsonCreateArr() 850 * @see cxJsonCreateArr()
838 */ 851 */
839 cx_attr_nonnull 852 CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
840 CX_EXPORT CxJsonValue* cx_json_obj_put_arr(CxJsonValue* obj, cxstring name, size_t capacity); 853 CxJsonValue* cx_json_obj_put_arr(CxJsonValue* obj, cxstring name, size_t capacity);
841 854
842 /** 855 /**
843 * Creates a new JSON array and adds it to an object. 856 * Creates a new JSON array and adds it to an object.
844 * 857 *
845 * @param obj (@c CxJsonValue*) the target JSON object 858 * @param obj (@c CxJsonValue*) the target JSON object
861 * @param num the numeric value 874 * @param num the numeric value
862 * @return the new value or @c NULL if allocation fails 875 * @return the new value or @c NULL if allocation fails
863 * @see cxJsonObjPut() 876 * @see cxJsonObjPut()
864 * @see cxJsonCreateNumber() 877 * @see cxJsonCreateNumber()
865 */ 878 */
866 cx_attr_nonnull 879 CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
867 CX_EXPORT CxJsonValue* cx_json_obj_put_number(CxJsonValue* obj, cxstring name, double num); 880 CxJsonValue* cx_json_obj_put_number(CxJsonValue* obj, cxstring name, double num);
868 881
869 /** 882 /**
870 * Creates a new JSON number and adds it to an object. 883 * Creates a new JSON number and adds it to an object.
871 * 884 *
872 * @param obj (@c CxJsonValue*) the target JSON object 885 * @param obj (@c CxJsonValue*) the target JSON object
888 * @param num the numeric value 901 * @param num the numeric value
889 * @return the new value or @c NULL if allocation fails 902 * @return the new value or @c NULL if allocation fails
890 * @see cxJsonObjPut() 903 * @see cxJsonObjPut()
891 * @see cxJsonCreateInteger() 904 * @see cxJsonCreateInteger()
892 */ 905 */
893 cx_attr_nonnull 906 CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
894 CX_EXPORT CxJsonValue* cx_json_obj_put_integer(CxJsonValue* obj, cxstring name, int64_t num); 907 CxJsonValue* cx_json_obj_put_integer(CxJsonValue* obj, cxstring name, int64_t num);
895 908
896 /** 909 /**
897 * Creates a new JSON number, based on an integer, and adds it to an object. 910 * Creates a new JSON number, based on an integer, and adds it to an object.
898 * 911 *
899 * @param obj (@c CxJsonValue*) the target JSON object 912 * @param obj (@c CxJsonValue*) the target JSON object
915 * @param str the string data 928 * @param str the string data
916 * @return the new value or @c NULL if allocation fails 929 * @return the new value or @c NULL if allocation fails
917 * @see cxJsonObjPut() 930 * @see cxJsonObjPut()
918 * @see cxJsonCreateString() 931 * @see cxJsonCreateString()
919 */ 932 */
920 cx_attr_nonnull 933 CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
921 CX_EXPORT CxJsonValue* cx_json_obj_put_string(CxJsonValue* obj, cxstring name, cxstring str); 934 CxJsonValue* cx_json_obj_put_string(CxJsonValue* obj, cxstring name, cxstring str);
922 935
923 /** 936 /**
924 * Creates a new JSON string and adds it to an object. 937 * Creates a new JSON string and adds it to an object.
925 * 938 *
926 * The string data is copied. 939 * The string data is copied.
944 * @param lit the type of literal 957 * @param lit the type of literal
945 * @return the new value or @c NULL if allocation fails 958 * @return the new value or @c NULL if allocation fails
946 * @see cxJsonObjPut() 959 * @see cxJsonObjPut()
947 * @see cxJsonCreateLiteral() 960 * @see cxJsonCreateLiteral()
948 */ 961 */
949 cx_attr_nonnull 962 CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
950 CX_EXPORT CxJsonValue* cx_json_obj_put_literal(CxJsonValue* obj, cxstring name, CxJsonLiteral lit); 963 CxJsonValue* cx_json_obj_put_literal(CxJsonValue* obj, cxstring name, CxJsonLiteral lit);
951 964
952 /** 965 /**
953 * Creates a new JSON literal and adds it to an object. 966 * Creates a new JSON literal and adds it to an object.
954 * 967 *
955 * @param obj (@c CxJsonValue*) the target JSON object 968 * @param obj (@c CxJsonValue*) the target JSON object
958 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails 971 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails
959 * @see cxJsonObjPut() 972 * @see cxJsonObjPut()
960 * @see cxJsonCreateLiteral() 973 * @see cxJsonCreateLiteral()
961 */ 974 */
962 #define cxJsonObjPutLiteral(obj, name, lit) cx_json_obj_put_literal(obj, cx_strcast(name), lit) 975 #define cxJsonObjPutLiteral(obj, name, lit) cx_json_obj_put_literal(obj, cx_strcast(name), lit)
963
964 /**
965 * Recursively deallocates the memory of a JSON value.
966 *
967 * @remark The type of each deallocated value will be changed
968 * to #CX_JSON_NOTHING, and values of such a type will be skipped
969 * by the deallocation. That means this function protects
970 * you from double-frees when you are accidentally freeing
971 * a nested value and then the parent value (or vice versa).
972 *
973 * @param value the value
974 */
975 CX_EXPORT void cxJsonValueFree(CxJsonValue *value);
976 976
977 /** 977 /**
978 * Tries to obtain the next JSON value. 978 * Tries to obtain the next JSON value.
979 * 979 *
980 * Before this function can be called, the input buffer needs 980 * Before this function can be called, the input buffer needs
994 * @retval CX_JSON_BUFFER_ALLOC_FAILED allocating internal buffer space failed 994 * @retval CX_JSON_BUFFER_ALLOC_FAILED allocating internal buffer space failed
995 * @retval CX_JSON_VALUE_ALLOC_FAILED allocating memory for a CxJsonValue failed 995 * @retval CX_JSON_VALUE_ALLOC_FAILED allocating memory for a CxJsonValue failed
996 * @retval CX_JSON_FORMAT_ERROR_NUMBER the JSON text contains an illegally formatted number 996 * @retval CX_JSON_FORMAT_ERROR_NUMBER the JSON text contains an illegally formatted number
997 * @retval CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN JSON syntax error 997 * @retval CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN JSON syntax error
998 */ 998 */
999 cx_attr_nonnull cx_attr_access_w(2) 999 CX_EXTERN CX_NONNULL CX_ACCESS_W(2)
1000 CX_EXPORT CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value); 1000 CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value);
1001 1001
1002 /** 1002 /**
1003 * Checks if the specified value is a JSON object. 1003 * Checks if the specified value is a JSON object.
1004 * 1004 *
1005 * @param value a pointer to the value 1005 * @param value a pointer to the value
1006 * @retval true the value is a JSON object 1006 * @retval true the value is a JSON object
1007 * @retval false otherwise 1007 * @retval false otherwise
1008 */ 1008 */
1009 cx_attr_nonnull 1009 CX_NONNULL CX_NODISCARD CX_INLINE
1010 CX_INLINE bool cxJsonIsObject(const CxJsonValue *value) { 1010 bool cxJsonIsObject(const CxJsonValue *value) {
1011 return value->type == CX_JSON_OBJECT; 1011 return value->type == CX_JSON_OBJECT;
1012 } 1012 }
1013 1013
1014 /** 1014 /**
1015 * Checks if the specified value is a JSON array. 1015 * Checks if the specified value is a JSON array.
1016 * 1016 *
1017 * @param value a pointer to the value 1017 * @param value a pointer to the value
1018 * @retval true the value is a JSON array 1018 * @retval true the value is a JSON array
1019 * @retval false otherwise 1019 * @retval false otherwise
1020 */ 1020 */
1021 cx_attr_nonnull 1021 CX_NONNULL CX_NODISCARD CX_INLINE
1022 CX_INLINE bool cxJsonIsArray(const CxJsonValue *value) { 1022 bool cxJsonIsArray(const CxJsonValue *value) {
1023 return value->type == CX_JSON_ARRAY; 1023 return value->type == CX_JSON_ARRAY;
1024 } 1024 }
1025 1025
1026 /** 1026 /**
1027 * Checks if the specified value is a string. 1027 * Checks if the specified value is a string.
1028 * 1028 *
1029 * @param value a pointer to the value 1029 * @param value a pointer to the value
1030 * @retval true the value is a string 1030 * @retval true the value is a string
1031 * @retval false otherwise 1031 * @retval false otherwise
1032 */ 1032 */
1033 cx_attr_nonnull 1033 CX_NONNULL CX_NODISCARD CX_INLINE
1034 CX_INLINE bool cxJsonIsString(const CxJsonValue *value) { 1034 bool cxJsonIsString(const CxJsonValue *value) {
1035 return value->type == CX_JSON_STRING; 1035 return value->type == CX_JSON_STRING;
1036 } 1036 }
1037 1037
1038 /** 1038 /**
1039 * Checks if the specified value is a JSON number. 1039 * Checks if the specified value is a JSON number.
1044 * @param value a pointer to the value 1044 * @param value a pointer to the value
1045 * @retval true the value is a JSON number 1045 * @retval true the value is a JSON number
1046 * @retval false otherwise 1046 * @retval false otherwise
1047 * @see cxJsonIsInteger() 1047 * @see cxJsonIsInteger()
1048 */ 1048 */
1049 cx_attr_nonnull 1049 CX_NONNULL CX_NODISCARD CX_INLINE
1050 CX_INLINE bool cxJsonIsNumber(const CxJsonValue *value) { 1050 bool cxJsonIsNumber(const CxJsonValue *value) {
1051 return value->type == CX_JSON_NUMBER || value->type == CX_JSON_INTEGER; 1051 return value->type == CX_JSON_NUMBER || value->type == CX_JSON_INTEGER;
1052 } 1052 }
1053 1053
1054 /** 1054 /**
1055 * Checks if the specified value is an integer number. 1055 * Checks if the specified value is an integer number.
1057 * @param value a pointer to the value 1057 * @param value a pointer to the value
1058 * @retval true the value is an integer number 1058 * @retval true the value is an integer number
1059 * @retval false otherwise 1059 * @retval false otherwise
1060 * @see cxJsonIsNumber() 1060 * @see cxJsonIsNumber()
1061 */ 1061 */
1062 cx_attr_nonnull 1062 CX_NONNULL CX_NODISCARD CX_INLINE
1063 CX_INLINE bool cxJsonIsInteger(const CxJsonValue *value) { 1063 bool cxJsonIsInteger(const CxJsonValue *value) {
1064 return value->type == CX_JSON_INTEGER; 1064 return value->type == CX_JSON_INTEGER;
1065 } 1065 }
1066 1066
1067 /** 1067 /**
1068 * Checks if the specified value is a JSON literal. 1068 * Checks if the specified value is a JSON literal.
1074 * @retval false otherwise 1074 * @retval false otherwise
1075 * @see cxJsonIsTrue() 1075 * @see cxJsonIsTrue()
1076 * @see cxJsonIsFalse() 1076 * @see cxJsonIsFalse()
1077 * @see cxJsonIsNull() 1077 * @see cxJsonIsNull()
1078 */ 1078 */
1079 cx_attr_nonnull 1079 CX_NONNULL CX_NODISCARD CX_INLINE
1080 CX_INLINE bool cxJsonIsLiteral(const CxJsonValue *value) { 1080 bool cxJsonIsLiteral(const CxJsonValue *value) {
1081 return value->type == CX_JSON_LITERAL; 1081 return value->type == CX_JSON_LITERAL;
1082 } 1082 }
1083 1083
1084 /** 1084 /**
1085 * Checks if the specified value is a Boolean literal. 1085 * Checks if the specified value is a Boolean literal.
1088 * @retval true the value is either @c true or @c false 1088 * @retval true the value is either @c true or @c false
1089 * @retval false otherwise 1089 * @retval false otherwise
1090 * @see cxJsonIsTrue() 1090 * @see cxJsonIsTrue()
1091 * @see cxJsonIsFalse() 1091 * @see cxJsonIsFalse()
1092 */ 1092 */
1093 cx_attr_nonnull 1093 CX_NONNULL CX_NODISCARD CX_INLINE
1094 CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) { 1094 bool cxJsonIsBool(const CxJsonValue *value) {
1095 return cxJsonIsLiteral(value) && value->literal != CX_JSON_NULL; 1095 return cxJsonIsLiteral(value) && value->literal != CX_JSON_NULL;
1096 } 1096 }
1097 1097
1098 /** 1098 /**
1099 * Checks if the specified value is @c true. 1099 * Checks if the specified value is @c true.
1105 * @retval true the value is @c true 1105 * @retval true the value is @c true
1106 * @retval false otherwise 1106 * @retval false otherwise
1107 * @see cxJsonIsBool() 1107 * @see cxJsonIsBool()
1108 * @see cxJsonIsFalse() 1108 * @see cxJsonIsFalse()
1109 */ 1109 */
1110 cx_attr_nonnull 1110 CX_NONNULL CX_NODISCARD CX_INLINE
1111 CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) { 1111 bool cxJsonIsTrue(const CxJsonValue *value) {
1112 return cxJsonIsLiteral(value) && value->literal == CX_JSON_TRUE; 1112 return cxJsonIsLiteral(value) && value->literal == CX_JSON_TRUE;
1113 } 1113 }
1114 1114
1115 /** 1115 /**
1116 * Checks if the specified value is @c false. 1116 * Checks if the specified value is @c false.
1122 * @retval true the value is @c false 1122 * @retval true the value is @c false
1123 * @retval false otherwise 1123 * @retval false otherwise
1124 * @see cxJsonIsBool() 1124 * @see cxJsonIsBool()
1125 * @see cxJsonIsTrue() 1125 * @see cxJsonIsTrue()
1126 */ 1126 */
1127 cx_attr_nonnull 1127 CX_NONNULL CX_NODISCARD CX_INLINE
1128 CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) { 1128 bool cxJsonIsFalse(const CxJsonValue *value) {
1129 return cxJsonIsLiteral(value) && value->literal == CX_JSON_FALSE; 1129 return cxJsonIsLiteral(value) && value->literal == CX_JSON_FALSE;
1130 } 1130 }
1131 1131
1132 /** 1132 /**
1133 * Checks if the specified value is @c null. 1133 * Checks if the specified value is @c null.
1135 * @param value a pointer to the value 1135 * @param value a pointer to the value
1136 * @retval true the value is @c null 1136 * @retval true the value is @c null
1137 * @retval false otherwise 1137 * @retval false otherwise
1138 * @see cxJsonIsLiteral() 1138 * @see cxJsonIsLiteral()
1139 */ 1139 */
1140 cx_attr_nonnull 1140 CX_NONNULL CX_NODISCARD CX_INLINE
1141 CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) { 1141 bool cxJsonIsNull(const CxJsonValue *value) {
1142 return cxJsonIsLiteral(value) && value->literal == CX_JSON_NULL; 1142 return cxJsonIsLiteral(value) && value->literal == CX_JSON_NULL;
1143 } 1143 }
1144 1144
1145 /** 1145 /**
1146 * Obtains a C string from the given JSON value. 1146 * Obtains a C string from the given JSON value.
1149 * 1149 *
1150 * @param value the JSON value 1150 * @param value the JSON value
1151 * @return the value represented as C string 1151 * @return the value represented as C string
1152 * @see cxJsonIsString() 1152 * @see cxJsonIsString()
1153 */ 1153 */
1154 cx_attr_nonnull cx_attr_returns_nonnull 1154 CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL CX_NODISCARD
1155 CX_EXPORT char *cxJsonAsString(const CxJsonValue *value); 1155 char *cxJsonAsString(const CxJsonValue *value);
1156 1156
1157 /** 1157 /**
1158 * Obtains a UCX string from the given JSON value. 1158 * Obtains a UCX string from the given JSON value.
1159 * 1159 *
1160 * If the @p value is not a string, the behavior is undefined. 1160 * If the @p value is not a string, the behavior is undefined.
1161 * 1161 *
1162 * @param value the JSON value 1162 * @param value the JSON value
1163 * @return the value represented as UCX string 1163 * @return the value represented as UCX string
1164 * @see cxJsonIsString() 1164 * @see cxJsonIsString()
1165 */ 1165 */
1166 cx_attr_nonnull 1166 CX_EXTERN CX_NONNULL CX_NODISCARD
1167 CX_EXPORT cxstring cxJsonAsCxString(const CxJsonValue *value); 1167 cxstring cxJsonAsCxString(const CxJsonValue *value);
1168 1168
1169 /** 1169 /**
1170 * Obtains a mutable UCX string from the given JSON value. 1170 * Obtains a mutable UCX string from the given JSON value.
1171 * 1171 *
1172 * If the @p value is not a string, the behavior is undefined. 1172 * If the @p value is not a string, the behavior is undefined.
1173 * 1173 *
1174 * @param value the JSON value 1174 * @param value the JSON value
1175 * @return the value represented as mutable UCX string 1175 * @return the value represented as mutable UCX string
1176 * @see cxJsonIsString() 1176 * @see cxJsonIsString()
1177 */ 1177 */
1178 cx_attr_nonnull 1178 CX_EXTERN CX_NONNULL CX_NODISCARD
1179 CX_EXPORT cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value); 1179 cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value);
1180 1180
1181 /** 1181 /**
1182 * Obtains a double-precision floating-point value from the given JSON value. 1182 * Obtains a double-precision floating-point value from the given JSON value.
1183 * 1183 *
1184 * If the @p value is not a JSON number, the behavior is undefined. 1184 * If the @p value is not a JSON number, the behavior is undefined.
1185 * 1185 *
1186 * @param value the JSON value 1186 * @param value the JSON value
1187 * @return the value represented as double 1187 * @return the value represented as double
1188 * @see cxJsonIsNumber() 1188 * @see cxJsonIsNumber()
1189 */ 1189 */
1190 cx_attr_nonnull 1190 CX_EXTERN CX_NONNULL CX_NODISCARD
1191 CX_EXPORT double cxJsonAsDouble(const CxJsonValue *value); 1191 double cxJsonAsDouble(const CxJsonValue *value);
1192 1192
1193 /** 1193 /**
1194 * Obtains a 64-bit signed integer from the given JSON value. 1194 * Obtains a 64-bit signed integer from the given JSON value.
1195 * 1195 *
1196 * If the @p value is not a JSON number, the behavior is undefined. 1196 * If the @p value is not a JSON number, the behavior is undefined.
1200 * @param value the JSON value 1200 * @param value the JSON value
1201 * @return the value represented as double 1201 * @return the value represented as double
1202 * @see cxJsonIsNumber() 1202 * @see cxJsonIsNumber()
1203 * @see cxJsonIsInteger() 1203 * @see cxJsonIsInteger()
1204 */ 1204 */
1205 cx_attr_nonnull 1205 CX_EXTERN CX_NONNULL CX_NODISCARD
1206 CX_EXPORT int64_t cxJsonAsInteger(const CxJsonValue *value); 1206 int64_t cxJsonAsInteger(const CxJsonValue *value);
1207 1207
1208 /** 1208 /**
1209 * Obtains a Boolean value from the given JSON value. 1209 * Obtains a Boolean value from the given JSON value.
1210 * 1210 *
1211 * If the @p value is not a JSON literal, the behavior is undefined. 1211 * If the @p value is not a JSON literal, the behavior is undefined.
1213 * 1213 *
1214 * @param value the JSON value 1214 * @param value the JSON value
1215 * @return the value represented as double 1215 * @return the value represented as double
1216 * @see cxJsonIsLiteral() 1216 * @see cxJsonIsLiteral()
1217 */ 1217 */
1218 cx_attr_nonnull 1218 CX_NONNULL CX_NODISCARD CX_INLINE
1219 CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) { 1219 bool cxJsonAsBool(const CxJsonValue *value) {
1220 return value->literal == CX_JSON_TRUE; 1220 return value->literal == CX_JSON_TRUE;
1221 } 1221 }
1222 1222
1223 /** 1223 /**
1224 * Returns the size of a JSON array. 1224 * Returns the size of a JSON array.
1227 * 1227 *
1228 * @param value the JSON value 1228 * @param value the JSON value
1229 * @return the size of the array 1229 * @return the size of the array
1230 * @see cxJsonIsArray() 1230 * @see cxJsonIsArray()
1231 */ 1231 */
1232 cx_attr_nonnull 1232 CX_NONNULL CX_NODISCARD CX_INLINE
1233 CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) { 1233 size_t cxJsonArrSize(const CxJsonValue *value) {
1234 return value->array.size; 1234 return value->array.size;
1235 } 1235 }
1236 1236
1237 /** 1237 /**
1238 * Returns an element from a JSON array. 1238 * Returns an element from a JSON array.
1246 * @param value the JSON value 1246 * @param value the JSON value
1247 * @param index the index in the array 1247 * @param index the index in the array
1248 * @return the value at the specified index 1248 * @return the value at the specified index
1249 * @see cxJsonIsArray() 1249 * @see cxJsonIsArray()
1250 */ 1250 */
1251 cx_attr_nonnull cx_attr_returns_nonnull 1251 CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL CX_NODISCARD
1252 CX_EXPORT CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index); 1252 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index);
1253 1253
1254 /** 1254 /**
1255 * Removes an element from a JSON array. 1255 * Removes an element from a JSON array.
1256 * 1256 *
1257 * If the @p value is not a JSON array, the behavior is undefined. 1257 * If the @p value is not a JSON array, the behavior is undefined.
1262 * @param value the JSON value 1262 * @param value the JSON value
1263 * @param index the index in the array 1263 * @param index the index in the array
1264 * @return the removed value from the specified index or @c NULL when the index was out of bounds 1264 * @return the removed value from the specified index or @c NULL when the index was out of bounds
1265 * @see cxJsonIsArray() 1265 * @see cxJsonIsArray()
1266 */ 1266 */
1267 cx_attr_nonnull 1267 CX_EXTERN CX_NONNULL
1268 CX_EXPORT CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index); 1268 CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index);
1269 1269
1270 /** 1270 /**
1271 * Returns an iterator over the JSON array elements. 1271 * Returns an iterator over the JSON array elements.
1272 * 1272 *
1273 * The iterator yields values of type @c CxJsonValue* . 1273 * The iterator yields values of type @c CxJsonValue* .
1276 * 1276 *
1277 * @param value the JSON value 1277 * @param value the JSON value
1278 * @return an iterator over the array elements 1278 * @return an iterator over the array elements
1279 * @see cxJsonIsArray() 1279 * @see cxJsonIsArray()
1280 */ 1280 */
1281 cx_attr_nonnull cx_attr_nodiscard 1281 CX_EXTERN CX_NONNULL CX_NODISCARD
1282 CX_EXPORT CxIterator cxJsonArrIter(const CxJsonValue *value); 1282 CxIterator cxJsonArrIter(const CxJsonValue *value);
1283 1283
1284 /** 1284 /**
1285 * Returns the size of a JSON object. 1285 * Returns the size of a JSON object.
1286 * 1286 *
1287 * If the @p value is not a JSON object, the behavior is undefined. 1287 * If the @p value is not a JSON object, the behavior is undefined.
1288 * 1288 *
1289 * @param value the JSON value 1289 * @param value the JSON value
1290 * @return the size of the object, i.e., the number of key/value pairs 1290 * @return the size of the object, i.e., the number of key/value pairs
1291 * @see cxJsonIsObject() 1291 * @see cxJsonIsObject()
1292 */ 1292 */
1293 cx_attr_nonnull 1293 CX_NONNULL CX_INLINE
1294 CX_INLINE size_t cxJsonObjSize(const CxJsonValue *value) { 1294 size_t cxJsonObjSize(const CxJsonValue *value) {
1295 return cxCollectionSize(value->object); 1295 return cxCollectionSize(value->object);
1296 } 1296 }
1297 1297
1298 /** 1298 /**
1299 * Returns a map iterator over the JSON object members. 1299 * Returns a map iterator over the JSON object members.
1305 * 1305 *
1306 * @param value the JSON value 1306 * @param value the JSON value
1307 * @return an iterator over the object members 1307 * @return an iterator over the object members
1308 * @see cxJsonIsObject() 1308 * @see cxJsonIsObject()
1309 */ 1309 */
1310 cx_attr_nonnull cx_attr_nodiscard 1310 CX_EXTERN CX_NONNULL CX_NODISCARD
1311 CX_EXPORT CxMapIterator cxJsonObjIter(const CxJsonValue *value); 1311 CxMapIterator cxJsonObjIter(const CxJsonValue *value);
1312 1312
1313 /** 1313 /**
1314 * Internal function, do not use. 1314 * Internal function, do not use.
1315 * @param value the JSON object 1315 * @param value the JSON object
1316 * @param name the key to look up 1316 * @param name the key to look up
1317 * @return the value corresponding to the key 1317 * @return the value corresponding to the key
1318 */ 1318 */
1319 cx_attr_nonnull cx_attr_returns_nonnull 1319 CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL CX_NODISCARD
1320 CX_EXPORT CxJsonValue *cx_json_obj_get(const CxJsonValue *value, cxstring name); 1320 CxJsonValue *cx_json_obj_get(const CxJsonValue *value, cxstring name);
1321 1321
1322 /** 1322 /**
1323 * Returns a value corresponding to a key in a JSON object. 1323 * Returns a value corresponding to a key in a JSON object.
1324 * 1324 *
1325 * If the @p value is not a JSON object, the behavior is undefined. 1325 * If the @p value is not a JSON object, the behavior is undefined.
1339 * Internal function, do not use. 1339 * Internal function, do not use.
1340 * @param value the JSON object 1340 * @param value the JSON object
1341 * @param name the key to look up 1341 * @param name the key to look up
1342 * @return the value corresponding to the key or @c NULL when the key is not part of the object 1342 * @return the value corresponding to the key or @c NULL when the key is not part of the object
1343 */ 1343 */
1344 cx_attr_nonnull 1344 CX_EXTERN CX_NONNULL
1345 CX_EXPORT CxJsonValue *cx_json_obj_remove(CxJsonValue *value, cxstring name); 1345 CxJsonValue *cx_json_obj_remove(CxJsonValue *value, cxstring name);
1346 1346
1347 /** 1347 /**
1348 * Removes and returns a value corresponding to a key in a JSON object. 1348 * Removes and returns a value corresponding to a key in a JSON object.
1349 * 1349 *
1350 * If the @p value is not a JSON object, the behavior is undefined. 1350 * If the @p value is not a JSON object, the behavior is undefined.
1367 * @param json the JSON value 1367 * @param json the JSON value
1368 * @param other the other JSON value that the JSON value is compared to 1368 * @param other the other JSON value that the JSON value is compared to
1369 * @retval zero the values are equal (except for ordering of object members) 1369 * @retval zero the values are equal (except for ordering of object members)
1370 * @retval non-zero the values differ 1370 * @retval non-zero the values differ
1371 */ 1371 */
1372 CX_EXPORT int cxJsonCompare(const CxJsonValue *json, const CxJsonValue *other); 1372 CX_EXTERN CX_NODISCARD
1373 int cxJsonCompare(const CxJsonValue *json, const CxJsonValue *other);
1373 1374
1374 1375
1375 /** 1376 /**
1376 * Creates a deep copy of the specified JSON value. 1377 * Creates a deep copy of the specified JSON value.
1377 * 1378 *
1383 * @param value the value to be cloned 1384 * @param value the value to be cloned
1384 * @param allocator the allocator for the new value 1385 * @param allocator the allocator for the new value
1385 * @return the new value or @c NULL if any allocation was unsuccessful 1386 * @return the new value or @c NULL if any allocation was unsuccessful
1386 * @see cxJsonCloneFunc() 1387 * @see cxJsonCloneFunc()
1387 */ 1388 */
1388 cx_attr_nodiscard 1389 CX_EXTERN CX_NODISCARD
1389 CX_EXPORT CxJsonValue* cxJsonClone(const CxJsonValue* value, 1390 CxJsonValue* cxJsonClone(const CxJsonValue* value,
1390 const CxAllocator* allocator); 1391 const CxAllocator* allocator);
1391
1392 1392
1393 /** 1393 /**
1394 * A @c cx_clone_func compatible version of cxJsonClone(). 1394 * A @c cx_clone_func compatible version of cxJsonClone().
1395 * 1395 *
1396 * Internal function - use cxJsonCloneFunc() to get a properly casted function pointer. 1396 * Internal function - use cxJsonCloneFunc() to get a properly casted function pointer.
1400 * @param allocator the allocator for the new value 1400 * @param allocator the allocator for the new value
1401 * @param data unused 1401 * @param data unused
1402 * @return the new value or @c NULL if any allocation was unsuccessful 1402 * @return the new value or @c NULL if any allocation was unsuccessful
1403 * @see cxJsonClone() 1403 * @see cxJsonClone()
1404 */ 1404 */
1405 cx_attr_nodiscard 1405 CX_EXTERN CX_NODISCARD
1406 CX_EXPORT CxJsonValue* cx_json_clone_func( 1406 CxJsonValue* cx_json_clone_func(
1407 CxJsonValue* target, const CxJsonValue* source, 1407 CxJsonValue* target, const CxJsonValue* source,
1408 const CxAllocator* allocator, void *data); 1408 const CxAllocator* allocator, void *data);
1409 1409
1410 /** 1410 /**
1411 * A @c cx_clone_func compatible version of cxJsonClone(). 1411 * A @c cx_clone_func compatible version of cxJsonClone().
1417 * @return the new value or @c NULL if any allocation was unsuccessful 1417 * @return the new value or @c NULL if any allocation was unsuccessful
1418 * @see cxJsonClone() 1418 * @see cxJsonClone()
1419 */ 1419 */
1420 #define cxJsonCloneFunc ((cx_clone_func) cx_json_clone_func) 1420 #define cxJsonCloneFunc ((cx_clone_func) cx_json_clone_func)
1421 1421
1422 #ifdef __cplusplus
1423 }
1424 #endif
1425
1426 #endif /* UCX_JSON_H */ 1422 #endif /* UCX_JSON_H */
1427 1423

mercurial