ucx/cx/json.h

branch
dav-2
changeset 891
4d58cbcc9efa
parent 889
42cdbf9bbd49
equal deleted inserted replaced
890:e77ccf1c4bb3 891:4d58cbcc9efa
39 #include "common.h" 39 #include "common.h"
40 #include "allocator.h" 40 #include "allocator.h"
41 #include "string.h" 41 #include "string.h"
42 #include "buffer.h" 42 #include "buffer.h"
43 #include "array_list.h" 43 #include "array_list.h"
44 44 #include "map.h"
45 #include <string.h>
46 45
47 #ifdef __cplusplus 46 #ifdef __cplusplus
48 extern "C" { 47 extern "C" {
49 #endif 48 #endif
50 49
182 * Type alias for the JSON value struct. 181 * Type alias for the JSON value struct.
183 */ 182 */
184 typedef struct cx_json_value_s CxJsonValue; 183 typedef struct cx_json_value_s CxJsonValue;
185 184
186 /** 185 /**
187 * Type alias for the JSON array struct. 186 * Type alias for the map representing a JSON object.
188 */ 187 * The map contains pointers of type @c CxJsonValue.
189 typedef struct cx_json_array_s CxJsonArray; 188 */
190 /** 189 typedef CxMap* CxJsonObject;
191 * Type alias for the JSON object struct.
192 */
193 typedef struct cx_json_object_s CxJsonObject;
194 /** 190 /**
195 * Type alias for a JSON string. 191 * Type alias for a JSON string.
196 */ 192 */
197 typedef struct cx_mutstr_s CxJsonString; 193 typedef struct cx_mutstr_s CxJsonString;
198 /** 194 /**
205 typedef double CxJsonNumber; 201 typedef double CxJsonNumber;
206 /** 202 /**
207 * Type alias for a JSON literal. 203 * Type alias for a JSON literal.
208 */ 204 */
209 typedef enum cx_json_literal CxJsonLiteral; 205 typedef enum cx_json_literal CxJsonLiteral;
210
211 /**
212 * Type alias for a key/value pair in a JSON object.
213 */
214 typedef struct cx_json_obj_value_s CxJsonObjValue;
215
216 /**
217 * JSON array structure.
218 */
219 struct cx_json_array_s {
220 /**
221 * The array data.
222 */
223 CX_ARRAY_DECLARE(CxJsonValue*, array);
224 };
225
226 /**
227 * JSON object structure.
228 */
229 struct cx_json_object_s {
230 /**
231 * The key/value entries.
232 */
233 CX_ARRAY_DECLARE(CxJsonObjValue, values);
234 /**
235 * The original indices to reconstruct the order in which the members were added.
236 */
237 size_t *indices;
238 };
239
240 /**
241 * Structure for a key/value entry in a JSON object.
242 */
243 struct cx_json_obj_value_s {
244 /**
245 * The key (or name in JSON terminology) of the value.
246 */
247 cxmutstr name;
248 /**
249 * The value.
250 */
251 CxJsonValue *value;
252 };
253 206
254 /** 207 /**
255 * Structure for a JSON value. 208 * Structure for a JSON value.
256 */ 209 */
257 struct cx_json_value_s { 210 struct cx_json_value_s {
272 */ 225 */
273 union { 226 union {
274 /** 227 /**
275 * The array data if the type is #CX_JSON_ARRAY. 228 * The array data if the type is #CX_JSON_ARRAY.
276 */ 229 */
277 CxJsonArray array; 230 CX_ARRAY(CxJsonValue*, array);
278 /** 231 /**
279 * The object data if the type is #CX_JSON_OBJECT. 232 * The object data if the type is #CX_JSON_OBJECT.
280 */ 233 */
281 CxJsonObject object; 234 CxJsonObject object;
282 /** 235 /**
293 CxJsonNumber number; 246 CxJsonNumber number;
294 /** 247 /**
295 * The literal type if the type is #CX_JSON_LITERAL. 248 * The literal type if the type is #CX_JSON_LITERAL.
296 */ 249 */
297 CxJsonLiteral literal; 250 CxJsonLiteral literal;
298 } value; 251 };
299 }; 252 };
300 253
301 /** 254 /**
302 * Internally used structure for a parsed token. 255 * Internally used structure for a parsed token.
303 * 256 *
327 struct cx_json_s { 280 struct cx_json_s {
328 /** 281 /**
329 * The allocator used for produced JSON values. 282 * The allocator used for produced JSON values.
330 */ 283 */
331 const CxAllocator *allocator; 284 const CxAllocator *allocator;
285
332 /** 286 /**
333 * The input buffer. 287 * The input buffer.
334 */ 288 */
335 CxBuffer buffer; 289 CxBuffer buffer;
336 290
347 * Never access this value manually. 301 * Never access this value manually.
348 */ 302 */
349 CxJsonValue *parsed; 303 CxJsonValue *parsed;
350 304
351 /** 305 /**
352 * A pointer to an intermediate state of a currently parsed object member. 306 * The name of a not yet completely parsed object member.
353 * 307 *
354 * Never access this value manually. 308 * Never access this value manually.
355 */ 309 */
356 CxJsonObjValue uncompleted_member; 310 cxmutstr uncompleted_member_name;
357 311
358 /** 312 /**
359 * State stack. 313 * State stack.
360 */ 314 */
361 CX_ARRAY_DECLARE_SIZED(int, states, unsigned); 315 CX_ARRAY(int, states);
362 316
363 /** 317 /**
364 * Value buffer stack. 318 * Value buffer stack.
365 */ 319 */
366 CX_ARRAY_DECLARE_SIZED(CxJsonValue*, vbuf, unsigned); 320 CX_ARRAY(CxJsonValue*, vbuf);
367 321
368 /** 322 /**
369 * Internally reserved memory for the state stack. 323 * Internally reserved memory for the state stack.
370 */ 324 */
371 int states_internal[8]; 325 int states_internal[8];
436 struct cx_json_writer_s { 390 struct cx_json_writer_s {
437 /** 391 /**
438 * Set true to enable pretty output. 392 * Set true to enable pretty output.
439 */ 393 */
440 bool pretty; 394 bool pretty;
441 /**
442 * Set false to output the members in the order in which they were added.
443 */
444 bool sort_members;
445 /** 395 /**
446 * The maximum number of fractional digits in a number value. 396 * The maximum number of fractional digits in a number value.
447 * The default value is 6 and values larger than 15 are reduced to 15. 397 * The default value is 6 and values larger than 15 are reduced to 15.
448 * Note that the actual number of digits may be lower, depending on the concrete number. 398 * Note that the actual number of digits may be lower, depending on the concrete number.
449 */ 399 */
506 */ 456 */
507 cx_attr_nonnull_arg(1, 2, 3) 457 cx_attr_nonnull_arg(1, 2, 3)
508 CX_EXPORT int cxJsonWrite(void* target, const CxJsonValue* value, 458 CX_EXPORT int cxJsonWrite(void* target, const CxJsonValue* value,
509 cx_write_func wfunc, const CxJsonWriter* settings); 459 cx_write_func wfunc, const CxJsonWriter* settings);
510 460
461
462 /**
463 * Produces a compact string representation of the specified JSON value.
464 *
465 * @param allocator the allocator for the string
466 * @param value the JSON value
467 * @return the produced string
468 * @see cxJsonWrite()
469 * @see cxJsonWriterCompact()
470 * @see cxJsonToPrettyString()
471 */
472 cx_attr_nonnull_arg(2)
473 CX_EXPORT cxmutstr cxJsonToString(const CxAllocator *allocator, CxJsonValue *value);
474
475 /**
476 * Produces a pretty string representation of the specified JSON value.
477 *
478 * @param allocator the allocator for the string
479 * @param value the JSON value
480 * @return the produced string
481 * @see cxJsonWrite()
482 * @see cxJsonWriterPretty()
483 * @see cxJsonToString()
484 */
485 cx_attr_nonnull_arg(2)
486 CX_EXPORT cxmutstr cxJsonToPrettyString(const CxAllocator *allocator, CxJsonValue *value);
487
511 /** 488 /**
512 * Initializes the JSON interface. 489 * Initializes the JSON interface.
513 * 490 *
514 * @param json the JSON interface 491 * @param json the JSON interface
515 * @param allocator the allocator that shall be used for the produced values 492 * @param allocator the allocator that shall be used for the produced values
528 CX_EXPORT void cxJsonDestroy(CxJson *json); 505 CX_EXPORT void cxJsonDestroy(CxJson *json);
529 506
530 /** 507 /**
531 * Destroys and re-initializes the JSON interface. 508 * Destroys and re-initializes the JSON interface.
532 * 509 *
533 * You might want to use this to reset the parser after 510 * You must use this to reset the parser after encountering a syntax error
534 * encountering a syntax error. 511 * if you want to continue using it.
535 * 512 *
536 * @param json the JSON interface 513 * @param json the JSON interface
537 */ 514 */
538 cx_attr_nonnull 515 cx_attr_nonnull
539 CX_EXPORT void cxJsonReset(CxJson *json); 516 CX_EXPORT void cxJsonReset(CxJson *json);
554 * @param len the length of the source buffer 531 * @param len the length of the source buffer
555 * @retval zero success 532 * @retval zero success
556 * @retval non-zero internal allocation error 533 * @retval non-zero internal allocation error
557 * @see cxJsonFill() 534 * @see cxJsonFill()
558 */ 535 */
559 cx_attr_nonnull cx_attr_access_r(2, 3) 536 cx_attr_nonnull_arg(1) cx_attr_access_r(2, 3)
560 CX_EXPORT int cxJsonFilln(CxJson *json, const char *buf, size_t len); 537 CX_EXPORT int cxJsonFilln(CxJson *json, const char *buf, size_t len);
561 538
562 539
563 /** 540 /**
564 * Internal function, do not use. 541 * Internal function, do not use.
590 * @retval non-zero internal allocation error 567 * @retval non-zero internal allocation error
591 * @see cxJsonFilln() 568 * @see cxJsonFilln()
592 */ 569 */
593 #define cxJsonFill(json, str) cx_json_fill(json, cx_strcast(str)) 570 #define cxJsonFill(json, str) cx_json_fill(json, cx_strcast(str))
594 571
572
573 /**
574 * Internal function - use cxJsonFromString() instead.
575 *
576 * @param allocator the allocator for the JSON value
577 * @param str the string to parse
578 * @param value a pointer where the JSON value shall be stored to
579 * @return status code
580 */
581 cx_attr_nonnull_arg(3)
582 CX_EXPORT CxJsonStatus cx_json_from_string(const CxAllocator *allocator,
583 cxstring str, CxJsonValue **value);
584
585 /**
586 * Parses a string into a JSON value.
587 *
588 * @param allocator (@c CxAllocator*) the allocator for the JSON value
589 * @param str (any string) the string to parse
590 * @param value (@c CxJsonValue**) a pointer where the JSON value shall be stored to
591 * @retval CX_JSON_NO_ERROR success
592 * @retval CX_JSON_NO_DATA the string was empty or blank
593 * @retval CX_JSON_INCOMPLETE_DATA the string unexpectedly ended
594 * @retval CX_JSON_BUFFER_ALLOC_FAILED allocating internal buffer space failed
595 * @retval CX_JSON_VALUE_ALLOC_FAILED allocating memory for the CxJsonValue failed
596 * @retval CX_JSON_FORMAT_ERROR_NUMBER the JSON text contains an illegally formatted number
597 * @retval CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN JSON syntax error
598 */
599 #define cxJsonFromString(allocator, str, value) \
600 cx_json_from_string(allocator, cx_strcast(str), value)
601
595 /** 602 /**
596 * Creates a new (empty) JSON object. 603 * Creates a new (empty) JSON object.
597 * 604 *
598 * @param allocator the allocator to use 605 * @param allocator the allocator to use
599 * @return the new JSON object or @c NULL if allocation fails 606 * @return the new JSON object or @c NULL if allocation fails
604 CX_EXPORT CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator); 611 CX_EXPORT CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator);
605 612
606 /** 613 /**
607 * Creates a new (empty) JSON array. 614 * Creates a new (empty) JSON array.
608 * 615 *
616 * Optionally, this function already allocates memory with the given capacity.
617 *
609 * @param allocator the allocator to use 618 * @param allocator the allocator to use
619 * @param capacity optional capacity or zero if it's unknown how many elements the array will have
610 * @return the new JSON array or @c NULL if allocation fails 620 * @return the new JSON array or @c NULL if allocation fails
611 * @see cxJsonObjPutArr() 621 * @see cxJsonObjPutArr()
612 * @see cxJsonArrAddValues() 622 * @see cxJsonArrAddValues()
613 */ 623 */
614 cx_attr_nodiscard 624 cx_attr_nodiscard
615 CX_EXPORT CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator); 625 CX_EXPORT CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator, size_t capacity);
616 626
617 /** 627 /**
618 * Creates a new JSON number value. 628 * Creates a new JSON number value.
619 * 629 *
620 * @param allocator the allocator to use 630 * @param allocator the allocator to use
639 CX_EXPORT CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num); 649 CX_EXPORT CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num);
640 650
641 /** 651 /**
642 * Creates a new JSON string. 652 * Creates a new JSON string.
643 * 653 *
654 * Internal function - use cxJsonCreateString() instead.
655 *
644 * @param allocator the allocator to use 656 * @param allocator the allocator to use
645 * @param str the string data 657 * @param str the string data
646 * @return the new JSON value or @c NULL if allocation fails 658 * @return the new JSON value or @c NULL if allocation fails
647 * @see cxJsonCreateString()
648 * @see cxJsonObjPutString() 659 * @see cxJsonObjPutString()
649 * @see cxJsonArrAddStrings() 660 * @see cxJsonArrAddCxStrings()
650 */ 661 */
651 cx_attr_nodiscard cx_attr_nonnull_arg(2) cx_attr_cstr_arg(2) 662 cx_attr_nodiscard
652 CX_EXPORT CxJsonValue* cxJsonCreateString(const CxAllocator* allocator, const char *str); 663 CX_EXPORT CxJsonValue* cx_json_create_string(const CxAllocator* allocator, cxstring str);
653 664
654 /** 665 /**
655 * Creates a new JSON string. 666 * Creates a new JSON string.
656 * 667 *
657 * @param allocator the allocator to use 668 * @param allocator (@c CxAllocator*) the allocator to use
658 * @param str the string data 669 * @param str the string
659 * @return the new JSON value or @c NULL if allocation fails 670 * @return (@c CxJsonValue*) the new JSON value or @c NULL if allocation fails
660 * @see cxJsonCreateCxString() 671 * @see cxJsonObjPutString()
661 * @see cxJsonObjPutCxString()
662 * @see cxJsonArrAddCxStrings() 672 * @see cxJsonArrAddCxStrings()
663 */ 673 */
664 cx_attr_nodiscard 674 #define cxJsonCreateString(allocator, str) cx_json_create_string(allocator, cx_strcast(str))
665 CX_EXPORT CxJsonValue* cxJsonCreateCxString(const CxAllocator* allocator, cxstring str);
666 675
667 /** 676 /**
668 * Creates a new JSON literal. 677 * Creates a new JSON literal.
669 * 678 *
670 * @param allocator the allocator to use 679 * @param allocator the allocator to use
758 CX_EXPORT int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count); 767 CX_EXPORT int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count);
759 768
760 /** 769 /**
761 * Adds or replaces a value within a JSON object. 770 * Adds or replaces a value within a JSON object.
762 * 771 *
763 * The value will be directly added and not copied. 772 * Internal function - use cxJsonObjPut().
764 *
765 * @note If a value with the specified @p name already exists,
766 * it will be (recursively) freed with its own allocator.
767 * 773 *
768 * @param obj the JSON object 774 * @param obj the JSON object
769 * @param name the name of the value 775 * @param name the name of the value
770 * @param child the value 776 * @param child the value
771 * @retval zero success 777 * @retval zero success
772 * @retval non-zero allocation failure 778 * @retval non-zero allocation failure
773 */ 779 */
774 cx_attr_nonnull 780 cx_attr_nonnull
775 CX_EXPORT int cxJsonObjPut(CxJsonValue* obj, cxstring name, CxJsonValue* child); 781 CX_EXPORT int cx_json_obj_put(CxJsonValue* obj, cxstring name, CxJsonValue* child);
782
783 /**
784 * Adds or replaces a value within a JSON object.
785 *
786 * The value will be directly added and not copied.
787 *
788 * @note If a value with the specified @p name already exists,
789 * it will be (recursively) freed with its own allocator.
790 *
791 * @param obj (@c CxJsonValue*) the JSON object
792 * @param name (any string) the name of the value
793 * @param child (@c CxJsonValue*) the value
794 * @retval zero success
795 * @retval non-zero allocation failure
796 */
797 #define cxJsonObjPut(obj, name, child) cx_json_obj_put(obj, cx_strcast(name), child)
776 798
777 /** 799 /**
778 * Creates a new JSON object and adds it to an existing object. 800 * Creates a new JSON object and adds it to an existing object.
801 *
802 * Internal function - use cxJsonObjPutObj().
779 * 803 *
780 * @param obj the target JSON object 804 * @param obj the target JSON object
781 * @param name the name of the new value 805 * @param name the name of the new value
782 * @return the new value or @c NULL if allocation fails 806 * @return the new value or @c NULL if allocation fails
783 * @see cxJsonObjPut() 807 * @see cxJsonObjPut()
784 * @see cxJsonCreateObj() 808 * @see cxJsonCreateObj()
785 */ 809 */
786 cx_attr_nonnull 810 cx_attr_nonnull
787 CX_EXPORT CxJsonValue* cxJsonObjPutObj(CxJsonValue* obj, cxstring name); 811 CX_EXPORT CxJsonValue* cx_json_obj_put_obj(CxJsonValue* obj, cxstring name);
812
813 /**
814 * Creates a new JSON object and adds it to an existing object.
815 *
816 * @param obj (@c CxJsonValue*) the target JSON object
817 * @param name (any string) the name of the new value
818 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails
819 * @see cxJsonObjPut()
820 * @see cxJsonCreateObj()
821 */
822 #define cxJsonObjPutObj(obj, name) cx_json_obj_put_obj(obj, cx_strcast(name))
788 823
789 /** 824 /**
790 * Creates a new JSON array and adds it to an object. 825 * Creates a new JSON array and adds it to an object.
826 *
827 * Internal function - use cxJsonObjPutArr().
791 * 828 *
792 * @param obj the target JSON object 829 * @param obj the target JSON object
793 * @param name the name of the new value 830 * @param name the name of the new value
831 * @param capacity optional initial capacity
794 * @return the new value or @c NULL if allocation fails 832 * @return the new value or @c NULL if allocation fails
795 * @see cxJsonObjPut() 833 * @see cxJsonObjPut()
796 * @see cxJsonCreateArr() 834 * @see cxJsonCreateArr()
797 */ 835 */
798 cx_attr_nonnull 836 cx_attr_nonnull
799 CX_EXPORT CxJsonValue* cxJsonObjPutArr(CxJsonValue* obj, cxstring name); 837 CX_EXPORT CxJsonValue* cx_json_obj_put_arr(CxJsonValue* obj, cxstring name, size_t capacity);
838
839 /**
840 * Creates a new JSON array and adds it to an object.
841 *
842 * @param obj (@c CxJsonValue*) the target JSON object
843 * @param name (any string) the name of the new value
844 * @param capacity (@c size_t) optional initial capacity
845 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails
846 * @see cxJsonObjPut()
847 * @see cxJsonCreateArr()
848 */
849 #define cxJsonObjPutArr(obj, name, capacity) cx_json_obj_put_arr(obj, cx_strcast(name), capacity)
800 850
801 /** 851 /**
802 * Creates a new JSON number and adds it to an object. 852 * Creates a new JSON number and adds it to an object.
853 *
854 * Internal function - use cxJsonObjPutNumber().
803 * 855 *
804 * @param obj the target JSON object 856 * @param obj the target JSON object
805 * @param name the name of the new value 857 * @param name the name of the new value
806 * @param num the numeric value 858 * @param num the numeric value
807 * @return the new value or @c NULL if allocation fails 859 * @return the new value or @c NULL if allocation fails
808 * @see cxJsonObjPut() 860 * @see cxJsonObjPut()
809 * @see cxJsonCreateNumber() 861 * @see cxJsonCreateNumber()
810 */ 862 */
811 cx_attr_nonnull 863 cx_attr_nonnull
812 CX_EXPORT CxJsonValue* cxJsonObjPutNumber(CxJsonValue* obj, cxstring name, double num); 864 CX_EXPORT CxJsonValue* cx_json_obj_put_number(CxJsonValue* obj, cxstring name, double num);
865
866 /**
867 * Creates a new JSON number and adds it to an object.
868 *
869 * @param obj (@c CxJsonValue*) the target JSON object
870 * @param name (any string) the name of the new value
871 * @param num (@c double) the numeric value
872 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails
873 * @see cxJsonObjPut()
874 * @see cxJsonCreateNumber()
875 */
876 #define cxJsonObjPutNumber(obj, name, num) cx_json_obj_put_number(obj, cx_strcast(name), num)
813 877
814 /** 878 /**
815 * Creates a new JSON number, based on an integer, and adds it to an object. 879 * Creates a new JSON number, based on an integer, and adds it to an object.
880 *
881 * Internal function - use cxJsonObjPutInteger().
816 * 882 *
817 * @param obj the target JSON object 883 * @param obj the target JSON object
818 * @param name the name of the new value 884 * @param name the name of the new value
819 * @param num the numeric value 885 * @param num the numeric value
820 * @return the new value or @c NULL if allocation fails 886 * @return the new value or @c NULL if allocation fails
821 * @see cxJsonObjPut() 887 * @see cxJsonObjPut()
822 * @see cxJsonCreateInteger() 888 * @see cxJsonCreateInteger()
823 */ 889 */
824 cx_attr_nonnull 890 cx_attr_nonnull
825 CX_EXPORT CxJsonValue* cxJsonObjPutInteger(CxJsonValue* obj, cxstring name, int64_t num); 891 CX_EXPORT CxJsonValue* cx_json_obj_put_integer(CxJsonValue* obj, cxstring name, int64_t num);
892
893 /**
894 * Creates a new JSON number, based on an integer, and adds it to an object.
895 *
896 * @param obj (@c CxJsonValue*) the target JSON object
897 * @param name (any string) the name of the new value
898 * @param num (@c int64_t) the numeric value
899 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails
900 * @see cxJsonObjPut()
901 * @see cxJsonCreateInteger()
902 */
903 #define cxJsonObjPutInteger(obj, name, num) cx_json_obj_put_integer(obj, cx_strcast(name), num)
826 904
827 /** 905 /**
828 * Creates a new JSON string and adds it to an object. 906 * Creates a new JSON string and adds it to an object.
829 * 907 *
830 * The string data is copied. 908 * Internal function - use cxJsonObjPutString()
831 * 909 *
832 * @param obj the target JSON object 910 * @param obj the target JSON object
833 * @param name the name of the new value 911 * @param name the name of the new value
834 * @param str the string data 912 * @param str the string data
835 * @return the new value or @c NULL if allocation fails 913 * @return the new value or @c NULL if allocation fails
836 * @see cxJsonObjPut() 914 * @see cxJsonObjPut()
837 * @see cxJsonCreateString() 915 * @see cxJsonCreateString()
838 */ 916 */
839 cx_attr_nonnull cx_attr_cstr_arg(3) 917 cx_attr_nonnull
840 CX_EXPORT CxJsonValue* cxJsonObjPutString(CxJsonValue* obj, cxstring name, const char* str); 918 CX_EXPORT CxJsonValue* cx_json_obj_put_string(CxJsonValue* obj, cxstring name, cxstring str);
841 919
842 /** 920 /**
843 * Creates a new JSON string and adds it to an object. 921 * Creates a new JSON string and adds it to an object.
844 * 922 *
845 * The string data is copied. 923 * The string data is copied.
846 * 924 *
847 * @param obj the target JSON object 925 * @param obj (@c CxJsonValue*) the target JSON object
848 * @param name the name of the new value 926 * @param name (any string) the name of the new value
849 * @param str the string data 927 * @param str (any string) the string data
850 * @return the new value or @c NULL if allocation fails 928 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails
851 * @see cxJsonObjPut() 929 * @see cxJsonObjPut()
852 * @see cxJsonCreateCxString() 930 * @see cxJsonCreateString()
853 */ 931 */
854 cx_attr_nonnull 932 #define cxJsonObjPutString(obj, name, str) cx_json_obj_put_string(obj, cx_strcast(name), cx_strcast(str))
855 CX_EXPORT CxJsonValue* cxJsonObjPutCxString(CxJsonValue* obj, cxstring name, cxstring str);
856 933
857 /** 934 /**
858 * Creates a new JSON literal and adds it to an object. 935 * Creates a new JSON literal and adds it to an object.
936 *
937 * Internal function - use cxJsonObjPutLiteral().
859 * 938 *
860 * @param obj the target JSON object 939 * @param obj the target JSON object
861 * @param name the name of the new value 940 * @param name the name of the new value
862 * @param lit the type of literal 941 * @param lit the type of literal
863 * @return the new value or @c NULL if allocation fails 942 * @return the new value or @c NULL if allocation fails
864 * @see cxJsonObjPut() 943 * @see cxJsonObjPut()
865 * @see cxJsonCreateLiteral() 944 * @see cxJsonCreateLiteral()
866 */ 945 */
867 cx_attr_nonnull 946 cx_attr_nonnull
868 CX_EXPORT CxJsonValue* cxJsonObjPutLiteral(CxJsonValue* obj, cxstring name, CxJsonLiteral lit); 947 CX_EXPORT CxJsonValue* cx_json_obj_put_literal(CxJsonValue* obj, cxstring name, CxJsonLiteral lit);
948
949 /**
950 * Creates a new JSON literal and adds it to an object.
951 *
952 * @param obj (@c CxJsonValue*) the target JSON object
953 * @param name (any string) the name of the new value
954 * @param lit (@c CxJsonLiteral) the type of literal
955 * @return (@c CxJsonValue*) the new value or @c NULL if allocation fails
956 * @see cxJsonObjPut()
957 * @see cxJsonCreateLiteral()
958 */
959 #define cxJsonObjPutLiteral(obj, name, lit) cx_json_obj_put_literal(obj, cx_strcast(name), lit)
869 960
870 /** 961 /**
871 * Recursively deallocates the memory of a JSON value. 962 * Recursively deallocates the memory of a JSON value.
872 * 963 *
873 * @remark The type of each deallocated value will be changed 964 * @remark The type of each deallocated value will be changed
996 * @see cxJsonIsTrue() 1087 * @see cxJsonIsTrue()
997 * @see cxJsonIsFalse() 1088 * @see cxJsonIsFalse()
998 */ 1089 */
999 cx_attr_nonnull 1090 cx_attr_nonnull
1000 CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) { 1091 CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) {
1001 return cxJsonIsLiteral(value) && value->value.literal != CX_JSON_NULL; 1092 return cxJsonIsLiteral(value) && value->literal != CX_JSON_NULL;
1002 } 1093 }
1003 1094
1004 /** 1095 /**
1005 * Checks if the specified value is @c true. 1096 * Checks if the specified value is @c true.
1006 * 1097 *
1013 * @see cxJsonIsBool() 1104 * @see cxJsonIsBool()
1014 * @see cxJsonIsFalse() 1105 * @see cxJsonIsFalse()
1015 */ 1106 */
1016 cx_attr_nonnull 1107 cx_attr_nonnull
1017 CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) { 1108 CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) {
1018 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_TRUE; 1109 return cxJsonIsLiteral(value) && value->literal == CX_JSON_TRUE;
1019 } 1110 }
1020 1111
1021 /** 1112 /**
1022 * Checks if the specified value is @c false. 1113 * Checks if the specified value is @c false.
1023 * 1114 *
1030 * @see cxJsonIsBool() 1121 * @see cxJsonIsBool()
1031 * @see cxJsonIsTrue() 1122 * @see cxJsonIsTrue()
1032 */ 1123 */
1033 cx_attr_nonnull 1124 cx_attr_nonnull
1034 CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) { 1125 CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) {
1035 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_FALSE; 1126 return cxJsonIsLiteral(value) && value->literal == CX_JSON_FALSE;
1036 } 1127 }
1037 1128
1038 /** 1129 /**
1039 * Checks if the specified value is @c null. 1130 * Checks if the specified value is @c null.
1040 * 1131 *
1043 * @retval false otherwise 1134 * @retval false otherwise
1044 * @see cxJsonIsLiteral() 1135 * @see cxJsonIsLiteral()
1045 */ 1136 */
1046 cx_attr_nonnull 1137 cx_attr_nonnull
1047 CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) { 1138 CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) {
1048 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_NULL; 1139 return cxJsonIsLiteral(value) && value->literal == CX_JSON_NULL;
1049 } 1140 }
1050 1141
1051 /** 1142 /**
1052 * Obtains a C string from the given JSON value. 1143 * Obtains a C string from the given JSON value.
1053 * 1144 *
1121 * @return the value represented as double 1212 * @return the value represented as double
1122 * @see cxJsonIsLiteral() 1213 * @see cxJsonIsLiteral()
1123 */ 1214 */
1124 cx_attr_nonnull 1215 cx_attr_nonnull
1125 CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) { 1216 CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) {
1126 return value->value.literal == CX_JSON_TRUE; 1217 return value->literal == CX_JSON_TRUE;
1127 } 1218 }
1128 1219
1129 /** 1220 /**
1130 * Returns the size of a JSON array. 1221 * Returns the size of a JSON array.
1131 * 1222 *
1135 * @return the size of the array 1226 * @return the size of the array
1136 * @see cxJsonIsArray() 1227 * @see cxJsonIsArray()
1137 */ 1228 */
1138 cx_attr_nonnull 1229 cx_attr_nonnull
1139 CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) { 1230 CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) {
1140 return value->value.array.array_size; 1231 return value->array.size;
1141 } 1232 }
1142 1233
1143 /** 1234 /**
1144 * Returns an element from a JSON array. 1235 * Returns an element from a JSON array.
1145 * 1236 *
1186 */ 1277 */
1187 cx_attr_nonnull cx_attr_nodiscard 1278 cx_attr_nonnull cx_attr_nodiscard
1188 CX_EXPORT CxIterator cxJsonArrIter(const CxJsonValue *value); 1279 CX_EXPORT CxIterator cxJsonArrIter(const CxJsonValue *value);
1189 1280
1190 /** 1281 /**
1191 * Returns an iterator over the JSON object members. 1282 * Returns the size of a JSON object.
1192 * 1283 *
1193 * The iterator yields values of type @c CxJsonObjValue* which 1284 * If the @p value is not a JSON object, the behavior is undefined.
1194 * contain the name and value of the member. 1285 *
1286 * @param value the JSON value
1287 * @return the size of the object, i.e., the number of key/value pairs
1288 * @see cxJsonIsObject()
1289 */
1290 cx_attr_nonnull
1291 CX_INLINE size_t cxJsonObjSize(const CxJsonValue *value) {
1292 return cxCollectionSize(value->object);
1293 }
1294
1295 /**
1296 * Returns a map iterator over the JSON object members.
1297 *
1298 * The iterator yields values of type @c CxMapEntry* which
1299 * contain the name and the @c CxJsonObjValue* of the member.
1195 * 1300 *
1196 * If the @p value is not a JSON object, the behavior is undefined. 1301 * If the @p value is not a JSON object, the behavior is undefined.
1197 * 1302 *
1198 * @param value the JSON value 1303 * @param value the JSON value
1199 * @return an iterator over the object members 1304 * @return an iterator over the object members
1200 * @see cxJsonIsObject() 1305 * @see cxJsonIsObject()
1201 */ 1306 */
1202 cx_attr_nonnull cx_attr_nodiscard 1307 cx_attr_nonnull cx_attr_nodiscard
1203 CX_EXPORT CxIterator cxJsonObjIter(const CxJsonValue *value); 1308 CX_EXPORT CxMapIterator cxJsonObjIter(const CxJsonValue *value);
1204 1309
1205 /** 1310 /**
1206 * Internal function, do not use. 1311 * Internal function, do not use.
1207 * @param value the JSON object 1312 * @param value the JSON object
1208 * @param name the key to look up 1313 * @param name the key to look up
1249 * @return the value corresponding to the key or @c NULL when the key is not part of the object 1354 * @return the value corresponding to the key or @c NULL when the key is not part of the object
1250 * @see cxJsonIsObject() 1355 * @see cxJsonIsObject()
1251 */ 1356 */
1252 #define cxJsonObjRemove(value, name) cx_json_obj_remove(value, cx_strcast(name)) 1357 #define cxJsonObjRemove(value, name) cx_json_obj_remove(value, cx_strcast(name))
1253 1358
1359 /**
1360 * Performs a deep comparison of two JSON values.
1361 *
1362 * The order of object members is ignored during comparison.
1363 *
1364 * @param json the JSON value
1365 * @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)
1367 * @retval non-zero the values differ
1368 */
1369 CX_EXPORT int cxJsonCompare(const CxJsonValue *json, const CxJsonValue *other);
1370
1371
1372 /**
1373 * Creates a deep copy of the specified JSON value.
1374 *
1375 * If you need a @c cx_clone_func compatible version, see cxJsonCloneFunc().
1376 *
1377 * @note when you are cloning @c NULL, you will get a pointer to a statically
1378 * allocated value which represents nothing.
1379 *
1380 * @param value the value to be cloned
1381 * @param allocator the allocator for the new value
1382 * @return the new value or @c NULL if any allocation was unsuccessful
1383 * @see cxJsonCloneFunc()
1384 */
1385 cx_attr_nodiscard
1386 CX_EXPORT CxJsonValue* cxJsonClone(const CxJsonValue* value,
1387 const CxAllocator* allocator);
1388
1389
1390 /**
1391 * A @c cx_clone_func compatible version of cxJsonClone().
1392 *
1393 * Internal function - use cxJsonCloneFunc() to get a properly casted function pointer.
1394 *
1395 * @param target the target memory or @c NULL
1396 * @param source the value to be cloned
1397 * @param allocator the allocator for the new value
1398 * @param data unused
1399 * @return the new value or @c NULL if any allocation was unsuccessful
1400 * @see cxJsonClone()
1401 */
1402 cx_attr_nodiscard
1403 CX_EXPORT CxJsonValue* cx_json_clone_func(
1404 CxJsonValue* target, const CxJsonValue* source,
1405 const CxAllocator* allocator, void *data);
1406
1407 /**
1408 * A @c cx_clone_func compatible version of cxJsonClone().
1409 *
1410 * @param target (@c CxJsonValue*) the target memory or @c NULL
1411 * @param source (@c CxJsonValue*) the value to be cloned
1412 * @param allocator (@c CxAllocator*) the allocator for the new value
1413 * @param data unused
1414 * @return the new value or @c NULL if any allocation was unsuccessful
1415 * @see cxJsonClone()
1416 */
1417 #define cxJsonCloneFunc ((cx_clone_func) cx_json_clone_func)
1418
1254 #ifdef __cplusplus 1419 #ifdef __cplusplus
1255 } 1420 }
1256 #endif 1421 #endif
1257 1422
1258 #endif /* UCX_JSON_H */ 1423 #endif /* UCX_JSON_H */

mercurial