ucx/cx/json.h

branch
dav-2
changeset 894
e86049631677
parent 891
4d58cbcc9efa
equal deleted inserted replaced
893:38800d479cd4 894:e86049631677
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 /**
287 * The input buffer. 286 * The input buffer.
288 */ 287 */
289 CxBuffer buffer; 288 CxBuffer buffer;
290 289
291 /** 290 /**
292 * Used internally.
293 *
294 * Remembers the prefix of the last uncompleted token.
295 */
296 CxJsonToken uncompleted;
297
298 /**
299 * A pointer to an intermediate state of the currently parsed value. 291 * A pointer to an intermediate state of the currently parsed value.
300 * 292 *
301 * Never access this value manually. 293 * Never access this value manually.
302 */ 294 */
303 CxJsonValue *parsed; 295 CxJsonValue *parsed;
306 * The name of a not yet completely parsed object member. 298 * The name of a not yet completely parsed object member.
307 * 299 *
308 * Never access this value manually. 300 * Never access this value manually.
309 */ 301 */
310 cxmutstr uncompleted_member_name; 302 cxmutstr uncompleted_member_name;
303
304 /**
305 * Internal buffer for uncompleted tokens.
306 */
307 cxmutstr uncompleted_content;
308
309 /**
310 * The expected type of the currently parsed, uncompleted token.
311 */
312 CxJsonTokenType uncompleted_tokentype;
311 313
312 /** 314 /**
313 * State stack. 315 * State stack.
314 */ 316 */
315 CX_ARRAY(int, states); 317 CX_ARRAY(int, states);
422 /** 424 /**
423 * Creates a default writer configuration for compact output. 425 * Creates a default writer configuration for compact output.
424 * 426 *
425 * @return new JSON writer settings 427 * @return new JSON writer settings
426 */ 428 */
427 cx_attr_nodiscard 429 CX_EXTERN CX_NODISCARD
428 CX_EXPORT CxJsonWriter cxJsonWriterCompact(void); 430 CxJsonWriter cxJsonWriterCompact(void);
429 431
430 /** 432 /**
431 * Creates a default writer configuration for pretty output. 433 * Creates a default writer configuration for pretty output.
432 * 434 *
433 * @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
434 * @return new JSON writer settings 436 * @return new JSON writer settings
435 */ 437 */
436 cx_attr_nodiscard 438 CX_EXTERN CX_NODISCARD
437 CX_EXPORT CxJsonWriter cxJsonWriterPretty(bool use_spaces); 439 CxJsonWriter cxJsonWriterPretty(bool use_spaces);
438 440
439 /** 441 /**
440 * Writes a JSON value to a buffer or stream. 442 * Writes a JSON value to a buffer or stream.
441 * 443 *
442 * 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.
452 * @param wfunc the write function to use 454 * @param wfunc the write function to use
453 * @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)
454 * @retval zero success 456 * @retval zero success
455 * @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
456 */ 458 */
457 cx_attr_nonnull_arg(1, 2, 3) 459 CX_EXTERN CX_NONNULL_ARG(1, 2, 3)
458 CX_EXPORT int cxJsonWrite(void* target, const CxJsonValue* value, 460 int cxJsonWrite(void* target, const CxJsonValue* value,
459 cx_write_func wfunc, const CxJsonWriter* settings); 461 cx_write_func wfunc, const CxJsonWriter* settings);
460 462
461 463
462 /** 464 /**
463 * Produces a compact string representation of the specified JSON value. 465 * Produces a compact string representation of the specified JSON value.
467 * @return the produced string 469 * @return the produced string
468 * @see cxJsonWrite() 470 * @see cxJsonWrite()
469 * @see cxJsonWriterCompact() 471 * @see cxJsonWriterCompact()
470 * @see cxJsonToPrettyString() 472 * @see cxJsonToPrettyString()
471 */ 473 */
472 cx_attr_nonnull_arg(2) 474 CX_EXTERN CX_NONNULL_ARG(2) CX_NODISCARD
473 CX_EXPORT cxmutstr cxJsonToString(const CxAllocator *allocator, CxJsonValue *value); 475 cxmutstr cxJsonToString(const CxAllocator *allocator, CxJsonValue *value);
474 476
475 /** 477 /**
476 * Produces a pretty string representation of the specified JSON value. 478 * Produces a pretty string representation of the specified JSON value.
477 * 479 *
478 * @param allocator the allocator for the string 480 * @param allocator the allocator for the string
480 * @return the produced string 482 * @return the produced string
481 * @see cxJsonWrite() 483 * @see cxJsonWrite()
482 * @see cxJsonWriterPretty() 484 * @see cxJsonWriterPretty()
483 * @see cxJsonToString() 485 * @see cxJsonToString()
484 */ 486 */
485 cx_attr_nonnull_arg(2) 487 CX_EXTERN CX_NONNULL_ARG(2) CX_NODISCARD
486 CX_EXPORT cxmutstr cxJsonToPrettyString(const CxAllocator *allocator, CxJsonValue *value); 488 cxmutstr cxJsonToPrettyString(const CxAllocator *allocator, CxJsonValue *value);
487 489
488 /** 490 /**
489 * Initializes the JSON interface. 491 * Initializes the JSON interface.
490 * 492 *
491 * @param json the JSON interface 493 * @param json the JSON interface
492 * @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
493 * @see cxJsonDestroy() 495 * @see cxJsonDestroy()
494 */ 496 */
495 cx_attr_nonnull_arg(1) 497 CX_EXTERN CX_NONNULL_ARG(1)
496 CX_EXPORT void cxJsonInit(CxJson *json, const CxAllocator *allocator); 498 void cxJsonInit(CxJson *json, const CxAllocator *allocator);
497 499
498 /** 500 /**
499 * Destroys the JSON interface. 501 * Destroys the JSON interface.
500 * 502 *
501 * @param json the JSON interface 503 * @param json the JSON interface
502 * @see cxJsonInit() 504 * @see cxJsonInit()
503 */ 505 */
504 cx_attr_nonnull 506 CX_EXTERN CX_NONNULL
505 CX_EXPORT void cxJsonDestroy(CxJson *json); 507 void cxJsonDestroy(CxJson *json);
506 508
507 /** 509 /**
508 * Destroys and re-initializes the JSON interface. 510 * Destroys and re-initializes the JSON interface.
509 * 511 *
510 * 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
511 * if you want to continue using it. 513 * if you want to continue using it.
512 * 514 *
513 * @param json the JSON interface 515 * @param json the JSON interface
514 */ 516 */
515 cx_attr_nonnull 517 CX_EXTERN CX_NONNULL
516 CX_EXPORT void cxJsonReset(CxJson *json); 518 void cxJsonReset(CxJson *json);
517 519
518 /** 520 /**
519 * Fills the input buffer. 521 * Fills the input buffer.
520 * 522 *
521 * @remark The JSON interface tries to avoid copying the input data. 523 * @remark The JSON interface tries to avoid copying the input data.
531 * @param len the length of the source buffer 533 * @param len the length of the source buffer
532 * @retval zero success 534 * @retval zero success
533 * @retval non-zero internal allocation error 535 * @retval non-zero internal allocation error
534 * @see cxJsonFill() 536 * @see cxJsonFill()
535 */ 537 */
536 cx_attr_nonnull_arg(1) cx_attr_access_r(2, 3) 538 CX_EXTERN CX_NONNULL_ARG(1) CX_ACCESS_R(2, 3)
537 CX_EXPORT int cxJsonFilln(CxJson *json, const char *buf, size_t len); 539 int cxJsonFilln(CxJson *json, const char *buf, size_t len);
538 540
539 541
540 /** 542 /**
541 * Internal function, do not use. 543 * Internal function, do not use.
542 * 544 *
543 * @param json the JSON interface 545 * @param json the JSON interface
544 * @param str the string 546 * @param str the string
545 * @retval zero success 547 * @retval zero success
546 * @retval non-zero internal allocation error 548 * @retval non-zero internal allocation error
547 */ 549 */
548 cx_attr_nonnull 550 CX_NONNULL CX_INLINE
549 CX_INLINE int cx_json_fill(CxJson *json, cxstring str) { 551 int cx_json_fill(CxJson *json, cxstring str) {
550 return cxJsonFilln(json, str.ptr, str.length); 552 return cxJsonFilln(json, str.ptr, str.length);
551 } 553 }
552 554
553 /** 555 /**
554 * Fills the input buffer. 556 * Fills the input buffer.
576 * @param allocator the allocator for the JSON value 578 * @param allocator the allocator for the JSON value
577 * @param str the string to parse 579 * @param str the string to parse
578 * @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
579 * @return status code 581 * @return status code
580 */ 582 */
581 cx_attr_nonnull_arg(3) 583 CX_EXTERN CX_NONNULL_ARG(3) CX_ACCESS_W(3)
582 CX_EXPORT CxJsonStatus cx_json_from_string(const CxAllocator *allocator, 584 CxJsonStatus cx_json_from_string(const CxAllocator *allocator,
583 cxstring str, CxJsonValue **value); 585 cxstring str, CxJsonValue **value);
584 586
585 /** 587 /**
586 * Parses a string into a JSON value. 588 * Parses a string into a JSON value.
587 * 589 *
598 */ 600 */
599 #define cxJsonFromString(allocator, str, value) \ 601 #define cxJsonFromString(allocator, str, value) \
600 cx_json_from_string(allocator, cx_strcast(str), value) 602 cx_json_from_string(allocator, cx_strcast(str), value)
601 603
602 /** 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 /**
603 * Creates a new (empty) JSON object. 619 * Creates a new (empty) JSON object.
604 * 620 *
605 * @param allocator the allocator to use 621 * @param allocator the allocator to use
606 * @return the new JSON object or @c NULL if allocation fails 622 * @return the new JSON object or @c NULL if allocation fails
607 * @see cxJsonObjPutObj() 623 * @see cxJsonObjPutObj()
608 * @see cxJsonArrAddValues() 624 * @see cxJsonArrAddValues()
609 */ 625 */
610 cx_attr_nodiscard 626 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
611 CX_EXPORT CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator); 627 CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator);
612 628
613 /** 629 /**
614 * Creates a new (empty) JSON array. 630 * Creates a new (empty) JSON array.
615 * 631 *
616 * Optionally, this function already allocates memory with the given capacity. 632 * Optionally, this function already allocates memory with the given capacity.
619 * @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
620 * @return the new JSON array or @c NULL if allocation fails 636 * @return the new JSON array or @c NULL if allocation fails
621 * @see cxJsonObjPutArr() 637 * @see cxJsonObjPutArr()
622 * @see cxJsonArrAddValues() 638 * @see cxJsonArrAddValues()
623 */ 639 */
624 cx_attr_nodiscard 640 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
625 CX_EXPORT CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator, size_t capacity); 641 CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator, size_t capacity);
626 642
627 /** 643 /**
628 * Creates a new JSON number value. 644 * Creates a new JSON number value.
629 * 645 *
630 * @param allocator the allocator to use 646 * @param allocator the allocator to use
631 * @param num the numeric value 647 * @param num the numeric value
632 * @return the new JSON value or @c NULL if allocation fails 648 * @return the new JSON value or @c NULL if allocation fails
633 * @see cxJsonObjPutNumber() 649 * @see cxJsonObjPutNumber()
634 * @see cxJsonArrAddNumbers() 650 * @see cxJsonArrAddNumbers()
635 */ 651 */
636 cx_attr_nodiscard 652 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
637 CX_EXPORT CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num); 653 CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num);
638 654
639 /** 655 /**
640 * Creates a new JSON number value based on an integer. 656 * Creates a new JSON number value based on an integer.
641 * 657 *
642 * @param allocator the allocator to use 658 * @param allocator the allocator to use
643 * @param num the numeric value 659 * @param num the numeric value
644 * @return the new JSON value or @c NULL if allocation fails 660 * @return the new JSON value or @c NULL if allocation fails
645 * @see cxJsonObjPutInteger() 661 * @see cxJsonObjPutInteger()
646 * @see cxJsonArrAddIntegers() 662 * @see cxJsonArrAddIntegers()
647 */ 663 */
648 cx_attr_nodiscard 664 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
649 CX_EXPORT CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num); 665 CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num);
650 666
651 /** 667 /**
652 * Creates a new JSON string. 668 * Creates a new JSON string.
653 * 669 *
654 * Internal function - use cxJsonCreateString() instead. 670 * Internal function - use cxJsonCreateString() instead.
657 * @param str the string data 673 * @param str the string data
658 * @return the new JSON value or @c NULL if allocation fails 674 * @return the new JSON value or @c NULL if allocation fails
659 * @see cxJsonObjPutString() 675 * @see cxJsonObjPutString()
660 * @see cxJsonArrAddCxStrings() 676 * @see cxJsonArrAddCxStrings()
661 */ 677 */
662 cx_attr_nodiscard 678 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
663 CX_EXPORT CxJsonValue* cx_json_create_string(const CxAllocator* allocator, cxstring str); 679 CxJsonValue* cx_json_create_string(const CxAllocator* allocator, cxstring str);
664 680
665 /** 681 /**
666 * Creates a new JSON string. 682 * Creates a new JSON string.
667 * 683 *
668 * @param allocator (@c CxAllocator*) the allocator to use 684 * @param allocator (@c CxAllocator*) the allocator to use
680 * @param lit the type of literal 696 * @param lit the type of literal
681 * @return the new JSON value or @c NULL if allocation fails 697 * @return the new JSON value or @c NULL if allocation fails
682 * @see cxJsonObjPutLiteral() 698 * @see cxJsonObjPutLiteral()
683 * @see cxJsonArrAddLiterals() 699 * @see cxJsonArrAddLiterals()
684 */ 700 */
685 cx_attr_nodiscard 701 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
686 CX_EXPORT CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit); 702 CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit);
687 703
688 /** 704 /**
689 * Adds number values to a JSON array. 705 * Adds number values to a JSON array.
690 * 706 *
691 * @param arr the JSON array 707 * @param arr the JSON array
692 * @param num the array of values 708 * @param num the array of values
693 * @param count the number of elements 709 * @param count the number of elements
694 * @retval zero success 710 * @retval zero success
695 * @retval non-zero allocation failure 711 * @retval non-zero allocation failure
696 */ 712 */
697 cx_attr_nonnull cx_attr_access_r(2, 3) 713 CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
698 CX_EXPORT int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count); 714 int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count);
699 715
700 /** 716 /**
701 * 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.
702 * 718 *
703 * @param arr the JSON array 719 * @param arr the JSON array
704 * @param num the array of values 720 * @param num the array of values
705 * @param count the number of elements 721 * @param count the number of elements
706 * @retval zero success 722 * @retval zero success
707 * @retval non-zero allocation failure 723 * @retval non-zero allocation failure
708 */ 724 */
709 cx_attr_nonnull cx_attr_access_r(2, 3) 725 CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
710 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);
711 727
712 /** 728 /**
713 * Adds strings to a JSON array. 729 * Adds strings to a JSON array.
714 * 730 *
715 * The strings will be copied with the allocator of the array. 731 * The strings will be copied with the allocator of the array.
719 * @param count the number of elements 735 * @param count the number of elements
720 * @retval zero success 736 * @retval zero success
721 * @retval non-zero allocation failure 737 * @retval non-zero allocation failure
722 * @see cxJsonArrAddCxStrings() 738 * @see cxJsonArrAddCxStrings()
723 */ 739 */
724 cx_attr_nonnull cx_attr_access_r(2, 3) 740 CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
725 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);
726 742
727 /** 743 /**
728 * Adds strings to a JSON array. 744 * Adds strings to a JSON array.
729 * 745 *
730 * The strings will be copied with the allocator of the array. 746 * The strings will be copied with the allocator of the array.
734 * @param count the number of elements 750 * @param count the number of elements
735 * @retval zero success 751 * @retval zero success
736 * @retval non-zero allocation failure 752 * @retval non-zero allocation failure
737 * @see cxJsonArrAddStrings() 753 * @see cxJsonArrAddStrings()
738 */ 754 */
739 cx_attr_nonnull cx_attr_access_r(2, 3) 755 CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
740 CX_EXPORT int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count); 756 int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count);
741 757
742 /** 758 /**
743 * Adds literals to a JSON array. 759 * Adds literals to a JSON array.
744 * 760 *
745 * @param arr the JSON array 761 * @param arr the JSON array
746 * @param lit the array of literal types 762 * @param lit the array of literal types
747 * @param count the number of elements 763 * @param count the number of elements
748 * @retval zero success 764 * @retval zero success
749 * @retval non-zero allocation failure 765 * @retval non-zero allocation failure
750 */ 766 */
751 cx_attr_nonnull cx_attr_access_r(2, 3) 767 CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
752 CX_EXPORT int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count); 768 int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count);
753 769
754 /** 770 /**
755 * Add arbitrary values to a JSON array. 771 * Add arbitrary values to a JSON array.
756 * 772 *
757 * @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
761 * @param val the values 777 * @param val the values
762 * @param count the number of elements 778 * @param count the number of elements
763 * @retval zero success 779 * @retval zero success
764 * @retval non-zero allocation failure 780 * @retval non-zero allocation failure
765 */ 781 */
766 cx_attr_nonnull cx_attr_access_r(2, 3) 782 CX_EXTERN CX_NONNULL CX_ACCESS_R(2, 3)
767 CX_EXPORT int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count); 783 int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count);
768 784
769 /** 785 /**
770 * Adds or replaces a value within a JSON object. 786 * Adds or replaces a value within a JSON object.
771 * 787 *
772 * Internal function - use cxJsonObjPut(). 788 * Internal function - use cxJsonObjPut().
775 * @param name the name of the value 791 * @param name the name of the value
776 * @param child the value 792 * @param child the value
777 * @retval zero success 793 * @retval zero success
778 * @retval non-zero allocation failure 794 * @retval non-zero allocation failure
779 */ 795 */
780 cx_attr_nonnull 796 CX_EXTERN CX_NONNULL
781 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);
782 798
783 /** 799 /**
784 * Adds or replaces a value within a JSON object. 800 * Adds or replaces a value within a JSON object.
785 * 801 *
786 * The value will be directly added and not copied. 802 * The value will be directly added and not copied.
805 * @param name the name of the new value 821 * @param name the name of the new value
806 * @return the new value or @c NULL if allocation fails 822 * @return the new value or @c NULL if allocation fails
807 * @see cxJsonObjPut() 823 * @see cxJsonObjPut()
808 * @see cxJsonCreateObj() 824 * @see cxJsonCreateObj()
809 */ 825 */
810 cx_attr_nonnull 826 CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
811 CX_EXPORT CxJsonValue* cx_json_obj_put_obj(CxJsonValue* obj, cxstring name); 827 CxJsonValue* cx_json_obj_put_obj(CxJsonValue* obj, cxstring name);
812 828
813 /** 829 /**
814 * 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.
815 * 831 *
816 * @param obj (@c CxJsonValue*) the target JSON object 832 * @param obj (@c CxJsonValue*) the target JSON object
831 * @param capacity optional initial capacity 847 * @param capacity optional initial capacity
832 * @return the new value or @c NULL if allocation fails 848 * @return the new value or @c NULL if allocation fails
833 * @see cxJsonObjPut() 849 * @see cxJsonObjPut()
834 * @see cxJsonCreateArr() 850 * @see cxJsonCreateArr()
835 */ 851 */
836 cx_attr_nonnull 852 CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
837 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);
838 854
839 /** 855 /**
840 * Creates a new JSON array and adds it to an object. 856 * Creates a new JSON array and adds it to an object.
841 * 857 *
842 * @param obj (@c CxJsonValue*) the target JSON object 858 * @param obj (@c CxJsonValue*) the target JSON object
858 * @param num the numeric value 874 * @param num the numeric value
859 * @return the new value or @c NULL if allocation fails 875 * @return the new value or @c NULL if allocation fails
860 * @see cxJsonObjPut() 876 * @see cxJsonObjPut()
861 * @see cxJsonCreateNumber() 877 * @see cxJsonCreateNumber()
862 */ 878 */
863 cx_attr_nonnull 879 CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
864 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);
865 881
866 /** 882 /**
867 * Creates a new JSON number and adds it to an object. 883 * Creates a new JSON number and adds it to an object.
868 * 884 *
869 * @param obj (@c CxJsonValue*) the target JSON object 885 * @param obj (@c CxJsonValue*) the target JSON object
885 * @param num the numeric value 901 * @param num the numeric value
886 * @return the new value or @c NULL if allocation fails 902 * @return the new value or @c NULL if allocation fails
887 * @see cxJsonObjPut() 903 * @see cxJsonObjPut()
888 * @see cxJsonCreateInteger() 904 * @see cxJsonCreateInteger()
889 */ 905 */
890 cx_attr_nonnull 906 CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
891 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);
892 908
893 /** 909 /**
894 * 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.
895 * 911 *
896 * @param obj (@c CxJsonValue*) the target JSON object 912 * @param obj (@c CxJsonValue*) the target JSON object
912 * @param str the string data 928 * @param str the string data
913 * @return the new value or @c NULL if allocation fails 929 * @return the new value or @c NULL if allocation fails
914 * @see cxJsonObjPut() 930 * @see cxJsonObjPut()
915 * @see cxJsonCreateString() 931 * @see cxJsonCreateString()
916 */ 932 */
917 cx_attr_nonnull 933 CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
918 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);
919 935
920 /** 936 /**
921 * Creates a new JSON string and adds it to an object. 937 * Creates a new JSON string and adds it to an object.
922 * 938 *
923 * The string data is copied. 939 * The string data is copied.
941 * @param lit the type of literal 957 * @param lit the type of literal
942 * @return the new value or @c NULL if allocation fails 958 * @return the new value or @c NULL if allocation fails
943 * @see cxJsonObjPut() 959 * @see cxJsonObjPut()
944 * @see cxJsonCreateLiteral() 960 * @see cxJsonCreateLiteral()
945 */ 961 */
946 cx_attr_nonnull 962 CX_EXTERN CX_NONNULL CX_MALLOC CX_DEALLOC(cxJsonValueFree, 1)
947 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);
948 964
949 /** 965 /**
950 * Creates a new JSON literal and adds it to an object. 966 * Creates a new JSON literal and adds it to an object.
951 * 967 *
952 * @param obj (@c CxJsonValue*) the target JSON object 968 * @param obj (@c CxJsonValue*) the target JSON object
955 * @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
956 * @see cxJsonObjPut() 972 * @see cxJsonObjPut()
957 * @see cxJsonCreateLiteral() 973 * @see cxJsonCreateLiteral()
958 */ 974 */
959 #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)
960
961 /**
962 * Recursively deallocates the memory of a JSON value.
963 *
964 * @remark The type of each deallocated value will be changed
965 * to #CX_JSON_NOTHING, and values of such a type will be skipped
966 * by the deallocation. That means this function protects
967 * you from double-frees when you are accidentally freeing
968 * a nested value and then the parent value (or vice versa).
969 *
970 * @param value the value
971 */
972 CX_EXPORT void cxJsonValueFree(CxJsonValue *value);
973 976
974 /** 977 /**
975 * Tries to obtain the next JSON value. 978 * Tries to obtain the next JSON value.
976 * 979 *
977 * Before this function can be called, the input buffer needs 980 * Before this function can be called, the input buffer needs
991 * @retval CX_JSON_BUFFER_ALLOC_FAILED allocating internal buffer space failed 994 * @retval CX_JSON_BUFFER_ALLOC_FAILED allocating internal buffer space failed
992 * @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
993 * @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
994 * @retval CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN JSON syntax error 997 * @retval CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN JSON syntax error
995 */ 998 */
996 cx_attr_nonnull cx_attr_access_w(2) 999 CX_EXTERN CX_NONNULL CX_ACCESS_W(2)
997 CX_EXPORT CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value); 1000 CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value);
998 1001
999 /** 1002 /**
1000 * Checks if the specified value is a JSON object. 1003 * Checks if the specified value is a JSON object.
1001 * 1004 *
1002 * @param value a pointer to the value 1005 * @param value a pointer to the value
1003 * @retval true the value is a JSON object 1006 * @retval true the value is a JSON object
1004 * @retval false otherwise 1007 * @retval false otherwise
1005 */ 1008 */
1006 cx_attr_nonnull 1009 CX_NONNULL CX_NODISCARD CX_INLINE
1007 CX_INLINE bool cxJsonIsObject(const CxJsonValue *value) { 1010 bool cxJsonIsObject(const CxJsonValue *value) {
1008 return value->type == CX_JSON_OBJECT; 1011 return value->type == CX_JSON_OBJECT;
1009 } 1012 }
1010 1013
1011 /** 1014 /**
1012 * Checks if the specified value is a JSON array. 1015 * Checks if the specified value is a JSON array.
1013 * 1016 *
1014 * @param value a pointer to the value 1017 * @param value a pointer to the value
1015 * @retval true the value is a JSON array 1018 * @retval true the value is a JSON array
1016 * @retval false otherwise 1019 * @retval false otherwise
1017 */ 1020 */
1018 cx_attr_nonnull 1021 CX_NONNULL CX_NODISCARD CX_INLINE
1019 CX_INLINE bool cxJsonIsArray(const CxJsonValue *value) { 1022 bool cxJsonIsArray(const CxJsonValue *value) {
1020 return value->type == CX_JSON_ARRAY; 1023 return value->type == CX_JSON_ARRAY;
1021 } 1024 }
1022 1025
1023 /** 1026 /**
1024 * Checks if the specified value is a string. 1027 * Checks if the specified value is a string.
1025 * 1028 *
1026 * @param value a pointer to the value 1029 * @param value a pointer to the value
1027 * @retval true the value is a string 1030 * @retval true the value is a string
1028 * @retval false otherwise 1031 * @retval false otherwise
1029 */ 1032 */
1030 cx_attr_nonnull 1033 CX_NONNULL CX_NODISCARD CX_INLINE
1031 CX_INLINE bool cxJsonIsString(const CxJsonValue *value) { 1034 bool cxJsonIsString(const CxJsonValue *value) {
1032 return value->type == CX_JSON_STRING; 1035 return value->type == CX_JSON_STRING;
1033 } 1036 }
1034 1037
1035 /** 1038 /**
1036 * Checks if the specified value is a JSON number. 1039 * Checks if the specified value is a JSON number.
1041 * @param value a pointer to the value 1044 * @param value a pointer to the value
1042 * @retval true the value is a JSON number 1045 * @retval true the value is a JSON number
1043 * @retval false otherwise 1046 * @retval false otherwise
1044 * @see cxJsonIsInteger() 1047 * @see cxJsonIsInteger()
1045 */ 1048 */
1046 cx_attr_nonnull 1049 CX_NONNULL CX_NODISCARD CX_INLINE
1047 CX_INLINE bool cxJsonIsNumber(const CxJsonValue *value) { 1050 bool cxJsonIsNumber(const CxJsonValue *value) {
1048 return value->type == CX_JSON_NUMBER || value->type == CX_JSON_INTEGER; 1051 return value->type == CX_JSON_NUMBER || value->type == CX_JSON_INTEGER;
1049 } 1052 }
1050 1053
1051 /** 1054 /**
1052 * Checks if the specified value is an integer number. 1055 * Checks if the specified value is an integer number.
1054 * @param value a pointer to the value 1057 * @param value a pointer to the value
1055 * @retval true the value is an integer number 1058 * @retval true the value is an integer number
1056 * @retval false otherwise 1059 * @retval false otherwise
1057 * @see cxJsonIsNumber() 1060 * @see cxJsonIsNumber()
1058 */ 1061 */
1059 cx_attr_nonnull 1062 CX_NONNULL CX_NODISCARD CX_INLINE
1060 CX_INLINE bool cxJsonIsInteger(const CxJsonValue *value) { 1063 bool cxJsonIsInteger(const CxJsonValue *value) {
1061 return value->type == CX_JSON_INTEGER; 1064 return value->type == CX_JSON_INTEGER;
1062 } 1065 }
1063 1066
1064 /** 1067 /**
1065 * Checks if the specified value is a JSON literal. 1068 * Checks if the specified value is a JSON literal.
1071 * @retval false otherwise 1074 * @retval false otherwise
1072 * @see cxJsonIsTrue() 1075 * @see cxJsonIsTrue()
1073 * @see cxJsonIsFalse() 1076 * @see cxJsonIsFalse()
1074 * @see cxJsonIsNull() 1077 * @see cxJsonIsNull()
1075 */ 1078 */
1076 cx_attr_nonnull 1079 CX_NONNULL CX_NODISCARD CX_INLINE
1077 CX_INLINE bool cxJsonIsLiteral(const CxJsonValue *value) { 1080 bool cxJsonIsLiteral(const CxJsonValue *value) {
1078 return value->type == CX_JSON_LITERAL; 1081 return value->type == CX_JSON_LITERAL;
1079 } 1082 }
1080 1083
1081 /** 1084 /**
1082 * Checks if the specified value is a Boolean literal. 1085 * Checks if the specified value is a Boolean literal.
1085 * @retval true the value is either @c true or @c false 1088 * @retval true the value is either @c true or @c false
1086 * @retval false otherwise 1089 * @retval false otherwise
1087 * @see cxJsonIsTrue() 1090 * @see cxJsonIsTrue()
1088 * @see cxJsonIsFalse() 1091 * @see cxJsonIsFalse()
1089 */ 1092 */
1090 cx_attr_nonnull 1093 CX_NONNULL CX_NODISCARD CX_INLINE
1091 CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) { 1094 bool cxJsonIsBool(const CxJsonValue *value) {
1092 return cxJsonIsLiteral(value) && value->literal != CX_JSON_NULL; 1095 return cxJsonIsLiteral(value) && value->literal != CX_JSON_NULL;
1093 } 1096 }
1094 1097
1095 /** 1098 /**
1096 * Checks if the specified value is @c true. 1099 * Checks if the specified value is @c true.
1102 * @retval true the value is @c true 1105 * @retval true the value is @c true
1103 * @retval false otherwise 1106 * @retval false otherwise
1104 * @see cxJsonIsBool() 1107 * @see cxJsonIsBool()
1105 * @see cxJsonIsFalse() 1108 * @see cxJsonIsFalse()
1106 */ 1109 */
1107 cx_attr_nonnull 1110 CX_NONNULL CX_NODISCARD CX_INLINE
1108 CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) { 1111 bool cxJsonIsTrue(const CxJsonValue *value) {
1109 return cxJsonIsLiteral(value) && value->literal == CX_JSON_TRUE; 1112 return cxJsonIsLiteral(value) && value->literal == CX_JSON_TRUE;
1110 } 1113 }
1111 1114
1112 /** 1115 /**
1113 * Checks if the specified value is @c false. 1116 * Checks if the specified value is @c false.
1119 * @retval true the value is @c false 1122 * @retval true the value is @c false
1120 * @retval false otherwise 1123 * @retval false otherwise
1121 * @see cxJsonIsBool() 1124 * @see cxJsonIsBool()
1122 * @see cxJsonIsTrue() 1125 * @see cxJsonIsTrue()
1123 */ 1126 */
1124 cx_attr_nonnull 1127 CX_NONNULL CX_NODISCARD CX_INLINE
1125 CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) { 1128 bool cxJsonIsFalse(const CxJsonValue *value) {
1126 return cxJsonIsLiteral(value) && value->literal == CX_JSON_FALSE; 1129 return cxJsonIsLiteral(value) && value->literal == CX_JSON_FALSE;
1127 } 1130 }
1128 1131
1129 /** 1132 /**
1130 * Checks if the specified value is @c null. 1133 * Checks if the specified value is @c null.
1132 * @param value a pointer to the value 1135 * @param value a pointer to the value
1133 * @retval true the value is @c null 1136 * @retval true the value is @c null
1134 * @retval false otherwise 1137 * @retval false otherwise
1135 * @see cxJsonIsLiteral() 1138 * @see cxJsonIsLiteral()
1136 */ 1139 */
1137 cx_attr_nonnull 1140 CX_NONNULL CX_NODISCARD CX_INLINE
1138 CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) { 1141 bool cxJsonIsNull(const CxJsonValue *value) {
1139 return cxJsonIsLiteral(value) && value->literal == CX_JSON_NULL; 1142 return cxJsonIsLiteral(value) && value->literal == CX_JSON_NULL;
1140 } 1143 }
1141 1144
1142 /** 1145 /**
1143 * Obtains a C string from the given JSON value. 1146 * Obtains a C string from the given JSON value.
1146 * 1149 *
1147 * @param value the JSON value 1150 * @param value the JSON value
1148 * @return the value represented as C string 1151 * @return the value represented as C string
1149 * @see cxJsonIsString() 1152 * @see cxJsonIsString()
1150 */ 1153 */
1151 cx_attr_nonnull cx_attr_returns_nonnull 1154 CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL CX_NODISCARD
1152 CX_EXPORT char *cxJsonAsString(const CxJsonValue *value); 1155 char *cxJsonAsString(const CxJsonValue *value);
1153 1156
1154 /** 1157 /**
1155 * Obtains a UCX string from the given JSON value. 1158 * Obtains a UCX string from the given JSON value.
1156 * 1159 *
1157 * 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.
1158 * 1161 *
1159 * @param value the JSON value 1162 * @param value the JSON value
1160 * @return the value represented as UCX string 1163 * @return the value represented as UCX string
1161 * @see cxJsonIsString() 1164 * @see cxJsonIsString()
1162 */ 1165 */
1163 cx_attr_nonnull 1166 CX_EXTERN CX_NONNULL CX_NODISCARD
1164 CX_EXPORT cxstring cxJsonAsCxString(const CxJsonValue *value); 1167 cxstring cxJsonAsCxString(const CxJsonValue *value);
1165 1168
1166 /** 1169 /**
1167 * Obtains a mutable UCX string from the given JSON value. 1170 * Obtains a mutable UCX string from the given JSON value.
1168 * 1171 *
1169 * 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.
1170 * 1173 *
1171 * @param value the JSON value 1174 * @param value the JSON value
1172 * @return the value represented as mutable UCX string 1175 * @return the value represented as mutable UCX string
1173 * @see cxJsonIsString() 1176 * @see cxJsonIsString()
1174 */ 1177 */
1175 cx_attr_nonnull 1178 CX_EXTERN CX_NONNULL CX_NODISCARD
1176 CX_EXPORT cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value); 1179 cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value);
1177 1180
1178 /** 1181 /**
1179 * 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.
1180 * 1183 *
1181 * 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.
1182 * 1185 *
1183 * @param value the JSON value 1186 * @param value the JSON value
1184 * @return the value represented as double 1187 * @return the value represented as double
1185 * @see cxJsonIsNumber() 1188 * @see cxJsonIsNumber()
1186 */ 1189 */
1187 cx_attr_nonnull 1190 CX_EXTERN CX_NONNULL CX_NODISCARD
1188 CX_EXPORT double cxJsonAsDouble(const CxJsonValue *value); 1191 double cxJsonAsDouble(const CxJsonValue *value);
1189 1192
1190 /** 1193 /**
1191 * Obtains a 64-bit signed integer from the given JSON value. 1194 * Obtains a 64-bit signed integer from the given JSON value.
1192 * 1195 *
1193 * 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.
1197 * @param value the JSON value 1200 * @param value the JSON value
1198 * @return the value represented as double 1201 * @return the value represented as double
1199 * @see cxJsonIsNumber() 1202 * @see cxJsonIsNumber()
1200 * @see cxJsonIsInteger() 1203 * @see cxJsonIsInteger()
1201 */ 1204 */
1202 cx_attr_nonnull 1205 CX_EXTERN CX_NONNULL CX_NODISCARD
1203 CX_EXPORT int64_t cxJsonAsInteger(const CxJsonValue *value); 1206 int64_t cxJsonAsInteger(const CxJsonValue *value);
1204 1207
1205 /** 1208 /**
1206 * Obtains a Boolean value from the given JSON value. 1209 * Obtains a Boolean value from the given JSON value.
1207 * 1210 *
1208 * 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.
1210 * 1213 *
1211 * @param value the JSON value 1214 * @param value the JSON value
1212 * @return the value represented as double 1215 * @return the value represented as double
1213 * @see cxJsonIsLiteral() 1216 * @see cxJsonIsLiteral()
1214 */ 1217 */
1215 cx_attr_nonnull 1218 CX_NONNULL CX_NODISCARD CX_INLINE
1216 CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) { 1219 bool cxJsonAsBool(const CxJsonValue *value) {
1217 return value->literal == CX_JSON_TRUE; 1220 return value->literal == CX_JSON_TRUE;
1218 } 1221 }
1219 1222
1220 /** 1223 /**
1221 * Returns the size of a JSON array. 1224 * Returns the size of a JSON array.
1224 * 1227 *
1225 * @param value the JSON value 1228 * @param value the JSON value
1226 * @return the size of the array 1229 * @return the size of the array
1227 * @see cxJsonIsArray() 1230 * @see cxJsonIsArray()
1228 */ 1231 */
1229 cx_attr_nonnull 1232 CX_NONNULL CX_NODISCARD CX_INLINE
1230 CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) { 1233 size_t cxJsonArrSize(const CxJsonValue *value) {
1231 return value->array.size; 1234 return value->array.size;
1232 } 1235 }
1233 1236
1234 /** 1237 /**
1235 * Returns an element from a JSON array. 1238 * Returns an element from a JSON array.
1243 * @param value the JSON value 1246 * @param value the JSON value
1244 * @param index the index in the array 1247 * @param index the index in the array
1245 * @return the value at the specified index 1248 * @return the value at the specified index
1246 * @see cxJsonIsArray() 1249 * @see cxJsonIsArray()
1247 */ 1250 */
1248 cx_attr_nonnull cx_attr_returns_nonnull 1251 CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL CX_NODISCARD
1249 CX_EXPORT CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index); 1252 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index);
1250 1253
1251 /** 1254 /**
1252 * Removes an element from a JSON array. 1255 * Removes an element from a JSON array.
1253 * 1256 *
1254 * 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.
1259 * @param value the JSON value 1262 * @param value the JSON value
1260 * @param index the index in the array 1263 * @param index the index in the array
1261 * @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
1262 * @see cxJsonIsArray() 1265 * @see cxJsonIsArray()
1263 */ 1266 */
1264 cx_attr_nonnull 1267 CX_EXTERN CX_NONNULL
1265 CX_EXPORT CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index); 1268 CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index);
1266 1269
1267 /** 1270 /**
1268 * Returns an iterator over the JSON array elements. 1271 * Returns an iterator over the JSON array elements.
1269 * 1272 *
1270 * The iterator yields values of type @c CxJsonValue* . 1273 * The iterator yields values of type @c CxJsonValue* .
1273 * 1276 *
1274 * @param value the JSON value 1277 * @param value the JSON value
1275 * @return an iterator over the array elements 1278 * @return an iterator over the array elements
1276 * @see cxJsonIsArray() 1279 * @see cxJsonIsArray()
1277 */ 1280 */
1278 cx_attr_nonnull cx_attr_nodiscard 1281 CX_EXTERN CX_NONNULL CX_NODISCARD
1279 CX_EXPORT CxIterator cxJsonArrIter(const CxJsonValue *value); 1282 CxIterator cxJsonArrIter(const CxJsonValue *value);
1280 1283
1281 /** 1284 /**
1282 * Returns the size of a JSON object. 1285 * Returns the size of a JSON object.
1283 * 1286 *
1284 * 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.
1285 * 1288 *
1286 * @param value the JSON value 1289 * @param value the JSON value
1287 * @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
1288 * @see cxJsonIsObject() 1291 * @see cxJsonIsObject()
1289 */ 1292 */
1290 cx_attr_nonnull 1293 CX_NONNULL CX_INLINE
1291 CX_INLINE size_t cxJsonObjSize(const CxJsonValue *value) { 1294 size_t cxJsonObjSize(const CxJsonValue *value) {
1292 return cxCollectionSize(value->object); 1295 return cxCollectionSize(value->object);
1293 } 1296 }
1294 1297
1295 /** 1298 /**
1296 * Returns a map iterator over the JSON object members. 1299 * Returns a map iterator over the JSON object members.
1302 * 1305 *
1303 * @param value the JSON value 1306 * @param value the JSON value
1304 * @return an iterator over the object members 1307 * @return an iterator over the object members
1305 * @see cxJsonIsObject() 1308 * @see cxJsonIsObject()
1306 */ 1309 */
1307 cx_attr_nonnull cx_attr_nodiscard 1310 CX_EXTERN CX_NONNULL CX_NODISCARD
1308 CX_EXPORT CxMapIterator cxJsonObjIter(const CxJsonValue *value); 1311 CxMapIterator cxJsonObjIter(const CxJsonValue *value);
1309 1312
1310 /** 1313 /**
1311 * Internal function, do not use. 1314 * Internal function, do not use.
1312 * @param value the JSON object 1315 * @param value the JSON object
1313 * @param name the key to look up 1316 * @param name the key to look up
1314 * @return the value corresponding to the key 1317 * @return the value corresponding to the key
1315 */ 1318 */
1316 cx_attr_nonnull cx_attr_returns_nonnull 1319 CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL CX_NODISCARD
1317 CX_EXPORT CxJsonValue *cx_json_obj_get(const CxJsonValue *value, cxstring name); 1320 CxJsonValue *cx_json_obj_get(const CxJsonValue *value, cxstring name);
1318 1321
1319 /** 1322 /**
1320 * Returns a value corresponding to a key in a JSON object. 1323 * Returns a value corresponding to a key in a JSON object.
1321 * 1324 *
1322 * 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.
1336 * Internal function, do not use. 1339 * Internal function, do not use.
1337 * @param value the JSON object 1340 * @param value the JSON object
1338 * @param name the key to look up 1341 * @param name the key to look up
1339 * @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
1340 */ 1343 */
1341 cx_attr_nonnull 1344 CX_EXTERN CX_NONNULL
1342 CX_EXPORT CxJsonValue *cx_json_obj_remove(CxJsonValue *value, cxstring name); 1345 CxJsonValue *cx_json_obj_remove(CxJsonValue *value, cxstring name);
1343 1346
1344 /** 1347 /**
1345 * 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.
1346 * 1349 *
1347 * 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.
1364 * @param json the JSON value 1367 * @param json the JSON value
1365 * @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
1366 * @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)
1367 * @retval non-zero the values differ 1370 * @retval non-zero the values differ
1368 */ 1371 */
1369 CX_EXPORT int cxJsonCompare(const CxJsonValue *json, const CxJsonValue *other); 1372 CX_EXTERN CX_NODISCARD
1373 int cxJsonCompare(const CxJsonValue *json, const CxJsonValue *other);
1370 1374
1371 1375
1372 /** 1376 /**
1373 * Creates a deep copy of the specified JSON value. 1377 * Creates a deep copy of the specified JSON value.
1374 * 1378 *
1380 * @param value the value to be cloned 1384 * @param value the value to be cloned
1381 * @param allocator the allocator for the new value 1385 * @param allocator the allocator for the new value
1382 * @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
1383 * @see cxJsonCloneFunc() 1387 * @see cxJsonCloneFunc()
1384 */ 1388 */
1385 cx_attr_nodiscard 1389 CX_EXTERN CX_NODISCARD
1386 CX_EXPORT CxJsonValue* cxJsonClone(const CxJsonValue* value, 1390 CxJsonValue* cxJsonClone(const CxJsonValue* value,
1387 const CxAllocator* allocator); 1391 const CxAllocator* allocator);
1388
1389 1392
1390 /** 1393 /**
1391 * A @c cx_clone_func compatible version of cxJsonClone(). 1394 * A @c cx_clone_func compatible version of cxJsonClone().
1392 * 1395 *
1393 * Internal function - use cxJsonCloneFunc() to get a properly casted function pointer. 1396 * Internal function - use cxJsonCloneFunc() to get a properly casted function pointer.
1397 * @param allocator the allocator for the new value 1400 * @param allocator the allocator for the new value
1398 * @param data unused 1401 * @param data unused
1399 * @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
1400 * @see cxJsonClone() 1403 * @see cxJsonClone()
1401 */ 1404 */
1402 cx_attr_nodiscard 1405 CX_EXTERN CX_NODISCARD
1403 CX_EXPORT CxJsonValue* cx_json_clone_func( 1406 CxJsonValue* cx_json_clone_func(
1404 CxJsonValue* target, const CxJsonValue* source, 1407 CxJsonValue* target, const CxJsonValue* source,
1405 const CxAllocator* allocator, void *data); 1408 const CxAllocator* allocator, void *data);
1406 1409
1407 /** 1410 /**
1408 * A @c cx_clone_func compatible version of cxJsonClone(). 1411 * A @c cx_clone_func compatible version of cxJsonClone().
1414 * @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
1415 * @see cxJsonClone() 1418 * @see cxJsonClone()
1416 */ 1419 */
1417 #define cxJsonCloneFunc ((cx_clone_func) cx_json_clone_func) 1420 #define cxJsonCloneFunc ((cx_clone_func) cx_json_clone_func)
1418 1421
1419 #ifdef __cplusplus
1420 }
1421 #endif
1422
1423 #endif /* UCX_JSON_H */ 1422 #endif /* UCX_JSON_H */
1424 1423

mercurial