ucx/cx/json.h

changeset 888
af685cc9d623
parent 854
1c8401ece69e
equal deleted inserted replaced
877:b60487c3ec36 888:af685cc9d623
88 /** 88 /**
89 * A string token. 89 * A string token.
90 */ 90 */
91 CX_JSON_TOKEN_STRING, 91 CX_JSON_TOKEN_STRING,
92 /** 92 /**
93 * A number token that can be represented as integer. 93 * A number token that can be represented as an integer.
94 */ 94 */
95 CX_JSON_TOKEN_INTEGER, 95 CX_JSON_TOKEN_INTEGER,
96 /** 96 /**
97 * A number token that cannot be represented as integer. 97 * A number token that cannot be represented as an integer.
98 */ 98 */
99 CX_JSON_TOKEN_NUMBER, 99 CX_JSON_TOKEN_NUMBER,
100 /** 100 /**
101 * A literal token. 101 * A literal token.
102 */ 102 */
194 /** 194 /**
195 * Type alias for a JSON string. 195 * Type alias for a JSON string.
196 */ 196 */
197 typedef struct cx_mutstr_s CxJsonString; 197 typedef struct cx_mutstr_s CxJsonString;
198 /** 198 /**
199 * Type alias for a number that can be represented as 64-bit signed integer. 199 * Type alias for a number that can be represented as a 64-bit signed integer.
200 */ 200 */
201 typedef int64_t CxJsonInteger; 201 typedef int64_t CxJsonInteger;
202 /** 202 /**
203 * Type alias for number that is not an integer. 203 * Type alias for a number that is not an integer.
204 */ 204 */
205 typedef double CxJsonNumber; 205 typedef double CxJsonNumber;
206 /** 206 /**
207 * Type alias for a JSON literal. 207 * Type alias for a JSON literal.
208 */ 208 */
270 /** 270 /**
271 * The value data. 271 * The value data.
272 */ 272 */
273 union { 273 union {
274 /** 274 /**
275 * The array data if type is #CX_JSON_ARRAY. 275 * The array data if the type is #CX_JSON_ARRAY.
276 */ 276 */
277 CxJsonArray array; 277 CxJsonArray array;
278 /** 278 /**
279 * The object data if type is #CX_JSON_OBJECT. 279 * The object data if the type is #CX_JSON_OBJECT.
280 */ 280 */
281 CxJsonObject object; 281 CxJsonObject object;
282 /** 282 /**
283 * The string data if type is #CX_JSON_STRING. 283 * The string data if the type is #CX_JSON_STRING.
284 */ 284 */
285 CxJsonString string; 285 CxJsonString string;
286 /** 286 /**
287 * The integer if type is #CX_JSON_INTEGER. 287 * The integer if the type is #CX_JSON_INTEGER.
288 */ 288 */
289 CxJsonInteger integer; 289 CxJsonInteger integer;
290 /** 290 /**
291 * The number if type is #CX_JSON_NUMBER. 291 * The number if the type is #CX_JSON_NUMBER.
292 */ 292 */
293 CxJsonNumber number; 293 CxJsonNumber number;
294 /** 294 /**
295 * The literal type if type is #CX_JSON_LITERAL. 295 * The literal type if the type is #CX_JSON_LITERAL.
296 */ 296 */
297 CxJsonLiteral literal; 297 CxJsonLiteral literal;
298 } value; 298 } value;
299 }; 299 };
300 300
375 */ 375 */
376 CxJsonValue* vbuf_internal[8]; 376 CxJsonValue* vbuf_internal[8];
377 }; 377 };
378 378
379 /** 379 /**
380 * Status codes for the json interface. 380 * Status codes for the JSON interface.
381 */ 381 */
382 enum cx_json_status { 382 enum cx_json_status {
383 /** 383 /**
384 * Everything is fine. 384 * Everything is fine.
385 */ 385 */
389 */ 389 */
390 CX_JSON_NO_DATA, 390 CX_JSON_NO_DATA,
391 /** 391 /**
392 * The input ends unexpectedly. 392 * The input ends unexpectedly.
393 * 393 *
394 * Refill the buffer with cxJsonFill() to complete the json data. 394 * Refill the buffer with cxJsonFill() to complete the JSON data.
395 */ 395 */
396 CX_JSON_INCOMPLETE_DATA, 396 CX_JSON_INCOMPLETE_DATA,
397 /** 397 /**
398 * Not used as a status and never returned by any function. 398 * Not used as a status and never returned by any function.
399 * 399 *
400 * You can use this enumerator to check for all "good" status results 400 * You can use this enumerator to check for all "good" status results
401 * by checking if the status is less than @c CX_JSON_OK. 401 * by checking if the status is less than @c CX_JSON_OK.
402 * 402 *
403 * A "good" status means, that you can refill data and continue parsing. 403 * A "good" status means that you can refill data and continue parsing.
404 */ 404 */
405 CX_JSON_OK, 405 CX_JSON_OK,
406 /** 406 /**
407 * The input buffer has never been filled. 407 * The input buffer has never been filled.
408 */ 408 */
410 /** 410 /**
411 * Allocating memory for the internal buffer failed. 411 * Allocating memory for the internal buffer failed.
412 */ 412 */
413 CX_JSON_BUFFER_ALLOC_FAILED, 413 CX_JSON_BUFFER_ALLOC_FAILED,
414 /** 414 /**
415 * Allocating memory for a json value failed. 415 * Allocating memory for a JSON value failed.
416 */ 416 */
417 CX_JSON_VALUE_ALLOC_FAILED, 417 CX_JSON_VALUE_ALLOC_FAILED,
418 /** 418 /**
419 * A number value is incorrectly formatted. 419 * A number value is incorrectly formatted.
420 */ 420 */
424 */ 424 */
425 CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN 425 CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN
426 }; 426 };
427 427
428 /** 428 /**
429 * Typedef for the json status enum. 429 * Typedef for the JSON status enum.
430 */ 430 */
431 typedef enum cx_json_status CxJsonStatus; 431 typedef enum cx_json_status CxJsonStatus;
432 432
433 /** 433 /**
434 * The JSON writer settings. 434 * The JSON writer settings.
443 */ 443 */
444 bool sort_members; 444 bool sort_members;
445 /** 445 /**
446 * The maximum number of fractional digits in a number value. 446 * The maximum number of fractional digits in a number value.
447 * The default value is 6 and values larger than 15 are reduced to 15. 447 * The default value is 6 and values larger than 15 are reduced to 15.
448 * Note, that the actual number of digits may be lower, depending on the concrete number. 448 * Note that the actual number of digits may be lower, depending on the concrete number.
449 */ 449 */
450 uint8_t frac_max_digits; 450 uint8_t frac_max_digits;
451 /** 451 /**
452 * Set true to use spaces instead of tab characters. 452 * Set true to use spaces instead of tab characters.
453 * Indentation is only used in pretty output. 453 * Indentation is only used in pretty output.
463 */ 463 */
464 bool escape_slash; 464 bool escape_slash;
465 }; 465 };
466 466
467 /** 467 /**
468 * Typedef for the json writer. 468 * Typedef for the JSON writer.
469 */ 469 */
470 typedef struct cx_json_writer_s CxJsonWriter; 470 typedef struct cx_json_writer_s CxJsonWriter;
471 471
472 /** 472 /**
473 * Creates a default writer configuration for compact output. 473 * Creates a default writer configuration for compact output.
474 * 474 *
475 * @return new JSON writer settings 475 * @return new JSON writer settings
476 */ 476 */
477 cx_attr_nodiscard 477 cx_attr_nodiscard
478 cx_attr_export 478 CX_EXPORT CxJsonWriter cxJsonWriterCompact(void);
479 CxJsonWriter cxJsonWriterCompact(void);
480 479
481 /** 480 /**
482 * Creates a default writer configuration for pretty output. 481 * Creates a default writer configuration for pretty output.
483 * 482 *
484 * @param use_spaces false if you want tabs, true if you want four spaces instead 483 * @param use_spaces false if you want tabs, true if you want four spaces instead
485 * @return new JSON writer settings 484 * @return new JSON writer settings
486 */ 485 */
487 cx_attr_nodiscard 486 cx_attr_nodiscard
488 cx_attr_export 487 CX_EXPORT CxJsonWriter cxJsonWriterPretty(bool use_spaces);
489 CxJsonWriter cxJsonWriterPretty(bool use_spaces);
490 488
491 /** 489 /**
492 * Writes a JSON value to a buffer or stream. 490 * Writes a JSON value to a buffer or stream.
493 * 491 *
494 * This function blocks until either all data is written, or an error occurs. 492 * This function blocks until either all data is written, or an error occurs.
495 * The write operation is not atomic in the sense that it might happen 493 * The write operation is not atomic in the sense that it might happen
496 * that the data is only partially written when an error occurs with no 494 * that the data is only partially written when an error occurs with no
497 * way to indicate how much data was written. 495 * way to indicate how much data was written.
498 * To avoid this problem, you can use a CxBuffer as @p target which is 496 * To avoid this problem, you can use a CxBuffer as @p target which is
499 * unlikely to fail a write operation and either use the buffer's flush 497 * unlikely to fail a write operation. You can, for example, use the buffer's flush
500 * feature to relay the data or use the data in the buffer manually to 498 * feature to relay the data.
501 * write it to the actual target.
502 * 499 *
503 * @param target the buffer or stream where to write to 500 * @param target the buffer or stream where to write to
504 * @param value the value that shall be written 501 * @param value the value that shall be written
505 * @param wfunc the write function to use 502 * @param wfunc the write function to use
506 * @param settings formatting settings (or @c NULL to use a compact default) 503 * @param settings formatting settings (or @c NULL to use a compact default)
507 * @retval zero success 504 * @retval zero success
508 * @retval non-zero when no or not all data could be written 505 * @retval non-zero when no or not all data could be written
509 */ 506 */
510 cx_attr_nonnull_arg(1, 2, 3) 507 cx_attr_nonnull_arg(1, 2, 3)
511 cx_attr_export 508 CX_EXPORT int cxJsonWrite(void* target, const CxJsonValue* value,
512 int cxJsonWrite( 509 cx_write_func wfunc, const CxJsonWriter* settings);
513 void* target, 510
514 const CxJsonValue* value, 511 /**
515 cx_write_func wfunc, 512 * Initializes the JSON interface.
516 const CxJsonWriter* settings 513 *
517 ); 514 * @param json the JSON interface
518
519 /**
520 * Initializes the json interface.
521 *
522 * @param json the json interface
523 * @param allocator the allocator that shall be used for the produced values 515 * @param allocator the allocator that shall be used for the produced values
524 * @see cxJsonDestroy() 516 * @see cxJsonDestroy()
525 */ 517 */
526 cx_attr_nonnull_arg(1) 518 cx_attr_nonnull_arg(1)
527 cx_attr_export 519 CX_EXPORT void cxJsonInit(CxJson *json, const CxAllocator *allocator);
528 void cxJsonInit(CxJson *json, const CxAllocator *allocator); 520
529 521 /**
530 /** 522 * Destroys the JSON interface.
531 * Destroys the json interface. 523 *
532 * 524 * @param json the JSON interface
533 * @param json the json interface
534 * @see cxJsonInit() 525 * @see cxJsonInit()
535 */ 526 */
536 cx_attr_nonnull 527 cx_attr_nonnull
537 cx_attr_export 528 CX_EXPORT void cxJsonDestroy(CxJson *json);
538 void cxJsonDestroy(CxJson *json); 529
539 530 /**
540 /** 531 * Destroys and re-initializes the JSON interface.
541 * Destroys and re-initializes the json interface. 532 *
542 * 533 * You might want to use this to reset the parser after
543 * You might want to use this, to reset the parser after
544 * encountering a syntax error. 534 * encountering a syntax error.
545 * 535 *
546 * @param json the json interface 536 * @param json the JSON interface
547 */ 537 */
548 cx_attr_nonnull 538 cx_attr_nonnull
549 static inline void cxJsonReset(CxJson *json) { 539 CX_EXPORT void cxJsonReset(CxJson *json);
550 const CxAllocator *allocator = json->allocator;
551 cxJsonDestroy(json);
552 cxJsonInit(json, allocator);
553 }
554 540
555 /** 541 /**
556 * Fills the input buffer. 542 * Fills the input buffer.
557 * 543 *
558 * @remark The JSON interface tries to avoid copying the input data. 544 * @remark The JSON interface tries to avoid copying the input data.
561 * pointer to the data in that case. When you invoke the fill 547 * pointer to the data in that case. When you invoke the fill
562 * function more than once before calling cxJsonNext(), 548 * function more than once before calling cxJsonNext(),
563 * the additional data is appended - inevitably leading to 549 * the additional data is appended - inevitably leading to
564 * an allocation of a new buffer and copying the previous contents. 550 * an allocation of a new buffer and copying the previous contents.
565 * 551 *
566 * @param json the json interface 552 * @param json the JSON interface
567 * @param buf the source buffer 553 * @param buf the source buffer
568 * @param len the length of the source buffer 554 * @param len the length of the source buffer
569 * @retval zero success 555 * @retval zero success
570 * @retval non-zero internal allocation error 556 * @retval non-zero internal allocation error
571 * @see cxJsonFill() 557 * @see cxJsonFill()
572 */ 558 */
573 cx_attr_nonnull 559 cx_attr_nonnull cx_attr_access_r(2, 3)
574 cx_attr_access_r(2, 3) 560 CX_EXPORT int cxJsonFilln(CxJson *json, const char *buf, size_t len);
575 cx_attr_export 561
576 int cxJsonFilln(CxJson *json, const char *buf, size_t len); 562
577 563 /**
578 #ifdef __cplusplus 564 * Internal function, do not use.
579 } // extern "C" 565 *
580 566 * @param json the JSON interface
581 cx_attr_nonnull 567 * @param str the string
582 static inline int cxJsonFill( 568 * @retval zero success
583 CxJson *json, 569 * @retval non-zero internal allocation error
584 cxstring str 570 */
585 ) { 571 cx_attr_nonnull
572 CX_INLINE int cx_json_fill(CxJson *json, cxstring str) {
586 return cxJsonFilln(json, str.ptr, str.length); 573 return cxJsonFilln(json, str.ptr, str.length);
587 } 574 }
588 575
589 cx_attr_nonnull
590 static inline int cxJsonFill(
591 CxJson *json,
592 cxmutstr str
593 ) {
594 return cxJsonFilln(json, str.ptr, str.length);
595 }
596
597 cx_attr_nonnull
598 cx_attr_cstr_arg(2)
599 static inline int cxJsonFill(
600 CxJson *json,
601 const char *str
602 ) {
603 return cxJsonFilln(json, str, strlen(str));
604 }
605
606 extern "C" {
607 #else // __cplusplus
608 /** 576 /**
609 * Fills the input buffer. 577 * Fills the input buffer.
610 * 578 *
611 * The JSON interface tries to avoid copying the input data. 579 * The JSON interface tries to avoid copying the input data.
612 * When you use this function and cxJsonNext() interleaving, 580 * When you use this function and cxJsonNext() interleaving,
614 * pointer to the data in that case. When you invoke the fill 582 * pointer to the data in that case. When you invoke the fill
615 * function more than once before calling cxJsonNext(), 583 * function more than once before calling cxJsonNext(),
616 * the additional data is appended - inevitably leading to 584 * the additional data is appended - inevitably leading to
617 * an allocation of a new buffer and copying the previous contents. 585 * an allocation of a new buffer and copying the previous contents.
618 * 586 *
619 * @param json the json interface 587 * @param json the JSON interface
620 * @param str the source string 588 * @param str the source string
621 * @retval zero success 589 * @retval zero success
622 * @retval non-zero internal allocation error 590 * @retval non-zero internal allocation error
623 * @see cxJsonFilln() 591 * @see cxJsonFilln()
624 */ 592 */
625 #define cxJsonFill(json, str) _Generic((str), \ 593 #define cxJsonFill(json, str) cx_json_fill(json, cx_strcast(str))
626 cxstring: cx_json_fill_cxstr, \
627 cxmutstr: cx_json_fill_mutstr, \
628 char*: cx_json_fill_str, \
629 const char*: cx_json_fill_str) \
630 (json, str)
631
632 /**
633 * @copydoc cxJsonFill()
634 */
635 cx_attr_nonnull
636 static inline int cx_json_fill_cxstr(
637 CxJson *json,
638 cxstring str
639 ) {
640 return cxJsonFilln(json, str.ptr, str.length);
641 }
642
643 /**
644 * @copydoc cxJsonFill()
645 */
646 cx_attr_nonnull
647 static inline int cx_json_fill_mutstr(
648 CxJson *json,
649 cxmutstr str
650 ) {
651 return cxJsonFilln(json, str.ptr, str.length);
652 }
653
654 /**
655 * @copydoc cxJsonFill()
656 */
657 cx_attr_nonnull
658 cx_attr_cstr_arg(2)
659 static inline int cx_json_fill_str(
660 CxJson *json,
661 const char *str
662 ) {
663 return cxJsonFilln(json, str, strlen(str));
664 }
665 #endif
666 594
667 /** 595 /**
668 * Creates a new (empty) JSON object. 596 * Creates a new (empty) JSON object.
669 * 597 *
670 * @param allocator the allocator to use 598 * @param allocator the allocator to use
671 * @return the new JSON object or @c NULL if allocation fails 599 * @return the new JSON object or @c NULL if allocation fails
672 * @see cxJsonObjPutObj() 600 * @see cxJsonObjPutObj()
673 * @see cxJsonArrAddValues() 601 * @see cxJsonArrAddValues()
674 */ 602 */
675 cx_attr_nodiscard 603 cx_attr_nodiscard
676 cx_attr_export 604 CX_EXPORT CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator);
677 CxJsonValue* cxJsonCreateObj(const CxAllocator* allocator);
678 605
679 /** 606 /**
680 * Creates a new (empty) JSON array. 607 * Creates a new (empty) JSON array.
681 * 608 *
682 * @param allocator the allocator to use 609 * @param allocator the allocator to use
683 * @return the new JSON array or @c NULL if allocation fails 610 * @return the new JSON array or @c NULL if allocation fails
684 * @see cxJsonObjPutArr() 611 * @see cxJsonObjPutArr()
685 * @see cxJsonArrAddValues() 612 * @see cxJsonArrAddValues()
686 */ 613 */
687 cx_attr_nodiscard 614 cx_attr_nodiscard
688 cx_attr_export 615 CX_EXPORT CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator);
689 CxJsonValue* cxJsonCreateArr(const CxAllocator* allocator);
690 616
691 /** 617 /**
692 * Creates a new JSON number value. 618 * Creates a new JSON number value.
693 * 619 *
694 * @param allocator the allocator to use 620 * @param allocator the allocator to use
696 * @return the new JSON value or @c NULL if allocation fails 622 * @return the new JSON value or @c NULL if allocation fails
697 * @see cxJsonObjPutNumber() 623 * @see cxJsonObjPutNumber()
698 * @see cxJsonArrAddNumbers() 624 * @see cxJsonArrAddNumbers()
699 */ 625 */
700 cx_attr_nodiscard 626 cx_attr_nodiscard
701 cx_attr_export 627 CX_EXPORT CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num);
702 CxJsonValue* cxJsonCreateNumber(const CxAllocator* allocator, double num);
703 628
704 /** 629 /**
705 * Creates a new JSON number value based on an integer. 630 * Creates a new JSON number value based on an integer.
706 * 631 *
707 * @param allocator the allocator to use 632 * @param allocator the allocator to use
709 * @return the new JSON value or @c NULL if allocation fails 634 * @return the new JSON value or @c NULL if allocation fails
710 * @see cxJsonObjPutInteger() 635 * @see cxJsonObjPutInteger()
711 * @see cxJsonArrAddIntegers() 636 * @see cxJsonArrAddIntegers()
712 */ 637 */
713 cx_attr_nodiscard 638 cx_attr_nodiscard
714 cx_attr_export 639 CX_EXPORT CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num);
715 CxJsonValue* cxJsonCreateInteger(const CxAllocator* allocator, int64_t num);
716 640
717 /** 641 /**
718 * Creates a new JSON string. 642 * Creates a new JSON string.
719 * 643 *
720 * @param allocator the allocator to use 644 * @param allocator the allocator to use
722 * @return the new JSON value or @c NULL if allocation fails 646 * @return the new JSON value or @c NULL if allocation fails
723 * @see cxJsonCreateString() 647 * @see cxJsonCreateString()
724 * @see cxJsonObjPutString() 648 * @see cxJsonObjPutString()
725 * @see cxJsonArrAddStrings() 649 * @see cxJsonArrAddStrings()
726 */ 650 */
727 cx_attr_nodiscard 651 cx_attr_nodiscard cx_attr_nonnull_arg(2) cx_attr_cstr_arg(2)
728 cx_attr_nonnull_arg(2) 652 CX_EXPORT CxJsonValue* cxJsonCreateString(const CxAllocator* allocator, const char *str);
729 cx_attr_cstr_arg(2)
730 cx_attr_export
731 CxJsonValue* cxJsonCreateString(const CxAllocator* allocator, const char *str);
732 653
733 /** 654 /**
734 * Creates a new JSON string. 655 * Creates a new JSON string.
735 * 656 *
736 * @param allocator the allocator to use 657 * @param allocator the allocator to use
739 * @see cxJsonCreateCxString() 660 * @see cxJsonCreateCxString()
740 * @see cxJsonObjPutCxString() 661 * @see cxJsonObjPutCxString()
741 * @see cxJsonArrAddCxStrings() 662 * @see cxJsonArrAddCxStrings()
742 */ 663 */
743 cx_attr_nodiscard 664 cx_attr_nodiscard
744 cx_attr_export 665 CX_EXPORT CxJsonValue* cxJsonCreateCxString(const CxAllocator* allocator, cxstring str);
745 CxJsonValue* cxJsonCreateCxString(const CxAllocator* allocator, cxstring str);
746 666
747 /** 667 /**
748 * Creates a new JSON literal. 668 * Creates a new JSON literal.
749 * 669 *
750 * @param allocator the allocator to use 670 * @param allocator the allocator to use
752 * @return the new JSON value or @c NULL if allocation fails 672 * @return the new JSON value or @c NULL if allocation fails
753 * @see cxJsonObjPutLiteral() 673 * @see cxJsonObjPutLiteral()
754 * @see cxJsonArrAddLiterals() 674 * @see cxJsonArrAddLiterals()
755 */ 675 */
756 cx_attr_nodiscard 676 cx_attr_nodiscard
757 cx_attr_export 677 CX_EXPORT CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit);
758 CxJsonValue* cxJsonCreateLiteral(const CxAllocator* allocator, CxJsonLiteral lit);
759 678
760 /** 679 /**
761 * Adds number values to a JSON array. 680 * Adds number values to a JSON array.
762 * 681 *
763 * @param arr the JSON array 682 * @param arr the JSON array
764 * @param num the array of values 683 * @param num the array of values
765 * @param count the number of elements 684 * @param count the number of elements
766 * @retval zero success 685 * @retval zero success
767 * @retval non-zero allocation failure 686 * @retval non-zero allocation failure
768 */ 687 */
769 cx_attr_nonnull 688 cx_attr_nonnull cx_attr_access_r(2, 3)
770 cx_attr_access_r(2, 3) 689 CX_EXPORT int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count);
771 cx_attr_export
772 int cxJsonArrAddNumbers(CxJsonValue* arr, const double* num, size_t count);
773 690
774 /** 691 /**
775 * Adds number values, of which all are integers, to a JSON array. 692 * Adds number values, of which all are integers, to a JSON array.
776 * 693 *
777 * @param arr the JSON array 694 * @param arr the JSON array
778 * @param num the array of values 695 * @param num the array of values
779 * @param count the number of elements 696 * @param count the number of elements
780 * @retval zero success 697 * @retval zero success
781 * @retval non-zero allocation failure 698 * @retval non-zero allocation failure
782 */ 699 */
783 cx_attr_nonnull 700 cx_attr_nonnull cx_attr_access_r(2, 3)
784 cx_attr_access_r(2, 3) 701 CX_EXPORT int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count);
785 cx_attr_export
786 int cxJsonArrAddIntegers(CxJsonValue* arr, const int64_t* num, size_t count);
787 702
788 /** 703 /**
789 * Adds strings to a JSON array. 704 * Adds strings to a JSON array.
790 * 705 *
791 * The strings will be copied with the allocator of the array. 706 * The strings will be copied with the allocator of the array.
795 * @param count the number of elements 710 * @param count the number of elements
796 * @retval zero success 711 * @retval zero success
797 * @retval non-zero allocation failure 712 * @retval non-zero allocation failure
798 * @see cxJsonArrAddCxStrings() 713 * @see cxJsonArrAddCxStrings()
799 */ 714 */
800 cx_attr_nonnull 715 cx_attr_nonnull cx_attr_access_r(2, 3)
801 cx_attr_access_r(2, 3) 716 CX_EXPORT int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count);
802 cx_attr_export
803 int cxJsonArrAddStrings(CxJsonValue* arr, const char* const* str, size_t count);
804 717
805 /** 718 /**
806 * Adds strings to a JSON array. 719 * Adds strings to a JSON array.
807 * 720 *
808 * The strings will be copied with the allocator of the array. 721 * The strings will be copied with the allocator of the array.
812 * @param count the number of elements 725 * @param count the number of elements
813 * @retval zero success 726 * @retval zero success
814 * @retval non-zero allocation failure 727 * @retval non-zero allocation failure
815 * @see cxJsonArrAddStrings() 728 * @see cxJsonArrAddStrings()
816 */ 729 */
817 cx_attr_nonnull 730 cx_attr_nonnull cx_attr_access_r(2, 3)
818 cx_attr_access_r(2, 3) 731 CX_EXPORT int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count);
819 cx_attr_export
820 int cxJsonArrAddCxStrings(CxJsonValue* arr, const cxstring* str, size_t count);
821 732
822 /** 733 /**
823 * Adds literals to a JSON array. 734 * Adds literals to a JSON array.
824 * 735 *
825 * @param arr the JSON array 736 * @param arr the JSON array
826 * @param lit the array of literal types 737 * @param lit the array of literal types
827 * @param count the number of elements 738 * @param count the number of elements
828 * @retval zero success 739 * @retval zero success
829 * @retval non-zero allocation failure 740 * @retval non-zero allocation failure
830 */ 741 */
831 cx_attr_nonnull 742 cx_attr_nonnull cx_attr_access_r(2, 3)
832 cx_attr_access_r(2, 3) 743 CX_EXPORT int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count);
833 cx_attr_export
834 int cxJsonArrAddLiterals(CxJsonValue* arr, const CxJsonLiteral* lit, size_t count);
835 744
836 /** 745 /**
837 * Add arbitrary values to a JSON array. 746 * Add arbitrary values to a JSON array.
838 * 747 *
839 * @attention In contrast to all other add functions, this function adds the values 748 * @attention In contrast to all other add functions, this function adds the values
843 * @param val the values 752 * @param val the values
844 * @param count the number of elements 753 * @param count the number of elements
845 * @retval zero success 754 * @retval zero success
846 * @retval non-zero allocation failure 755 * @retval non-zero allocation failure
847 */ 756 */
848 cx_attr_nonnull 757 cx_attr_nonnull cx_attr_access_r(2, 3)
849 cx_attr_access_r(2, 3) 758 CX_EXPORT int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count);
850 cx_attr_export
851 int cxJsonArrAddValues(CxJsonValue* arr, CxJsonValue* const* val, size_t count);
852 759
853 /** 760 /**
854 * Adds or replaces a value within a JSON object. 761 * Adds or replaces a value within a JSON object.
855 * 762 *
856 * The value will be directly added and not copied. 763 * The value will be directly added and not copied.
863 * @param child the value 770 * @param child the value
864 * @retval zero success 771 * @retval zero success
865 * @retval non-zero allocation failure 772 * @retval non-zero allocation failure
866 */ 773 */
867 cx_attr_nonnull 774 cx_attr_nonnull
868 cx_attr_export 775 CX_EXPORT int cxJsonObjPut(CxJsonValue* obj, cxstring name, CxJsonValue* child);
869 int cxJsonObjPut(CxJsonValue* obj, cxstring name, CxJsonValue* child);
870 776
871 /** 777 /**
872 * Creates a new JSON object and adds it to an existing object. 778 * Creates a new JSON object and adds it to an existing object.
873 * 779 *
874 * @param obj the target JSON object 780 * @param obj the target JSON object
876 * @return the new value or @c NULL if allocation fails 782 * @return the new value or @c NULL if allocation fails
877 * @see cxJsonObjPut() 783 * @see cxJsonObjPut()
878 * @see cxJsonCreateObj() 784 * @see cxJsonCreateObj()
879 */ 785 */
880 cx_attr_nonnull 786 cx_attr_nonnull
881 cx_attr_export 787 CX_EXPORT CxJsonValue* cxJsonObjPutObj(CxJsonValue* obj, cxstring name);
882 CxJsonValue* cxJsonObjPutObj(CxJsonValue* obj, cxstring name);
883 788
884 /** 789 /**
885 * Creates a new JSON array and adds it to an object. 790 * Creates a new JSON array and adds it to an object.
886 * 791 *
887 * @param obj the target JSON object 792 * @param obj the target JSON object
889 * @return the new value or @c NULL if allocation fails 794 * @return the new value or @c NULL if allocation fails
890 * @see cxJsonObjPut() 795 * @see cxJsonObjPut()
891 * @see cxJsonCreateArr() 796 * @see cxJsonCreateArr()
892 */ 797 */
893 cx_attr_nonnull 798 cx_attr_nonnull
894 cx_attr_export 799 CX_EXPORT CxJsonValue* cxJsonObjPutArr(CxJsonValue* obj, cxstring name);
895 CxJsonValue* cxJsonObjPutArr(CxJsonValue* obj, cxstring name);
896 800
897 /** 801 /**
898 * Creates a new JSON number and adds it to an object. 802 * Creates a new JSON number and adds it to an object.
899 * 803 *
900 * @param obj the target JSON object 804 * @param obj the target JSON object
903 * @return the new value or @c NULL if allocation fails 807 * @return the new value or @c NULL if allocation fails
904 * @see cxJsonObjPut() 808 * @see cxJsonObjPut()
905 * @see cxJsonCreateNumber() 809 * @see cxJsonCreateNumber()
906 */ 810 */
907 cx_attr_nonnull 811 cx_attr_nonnull
908 cx_attr_export 812 CX_EXPORT CxJsonValue* cxJsonObjPutNumber(CxJsonValue* obj, cxstring name, double num);
909 CxJsonValue* cxJsonObjPutNumber(CxJsonValue* obj, cxstring name, double num);
910 813
911 /** 814 /**
912 * Creates a new JSON number, based on an integer, and adds it to an object. 815 * Creates a new JSON number, based on an integer, and adds it to an object.
913 * 816 *
914 * @param obj the target JSON object 817 * @param obj the target JSON object
917 * @return the new value or @c NULL if allocation fails 820 * @return the new value or @c NULL if allocation fails
918 * @see cxJsonObjPut() 821 * @see cxJsonObjPut()
919 * @see cxJsonCreateInteger() 822 * @see cxJsonCreateInteger()
920 */ 823 */
921 cx_attr_nonnull 824 cx_attr_nonnull
922 cx_attr_export 825 CX_EXPORT CxJsonValue* cxJsonObjPutInteger(CxJsonValue* obj, cxstring name, int64_t num);
923 CxJsonValue* cxJsonObjPutInteger(CxJsonValue* obj, cxstring name, int64_t num);
924 826
925 /** 827 /**
926 * Creates a new JSON string and adds it to an object. 828 * Creates a new JSON string and adds it to an object.
927 * 829 *
928 * The string data is copied. 830 * The string data is copied.
932 * @param str the string data 834 * @param str the string data
933 * @return the new value or @c NULL if allocation fails 835 * @return the new value or @c NULL if allocation fails
934 * @see cxJsonObjPut() 836 * @see cxJsonObjPut()
935 * @see cxJsonCreateString() 837 * @see cxJsonCreateString()
936 */ 838 */
937 cx_attr_nonnull 839 cx_attr_nonnull cx_attr_cstr_arg(3)
938 cx_attr_cstr_arg(3) 840 CX_EXPORT CxJsonValue* cxJsonObjPutString(CxJsonValue* obj, cxstring name, const char* str);
939 cx_attr_export
940 CxJsonValue* cxJsonObjPutString(CxJsonValue* obj, cxstring name, const char* str);
941 841
942 /** 842 /**
943 * Creates a new JSON string and adds it to an object. 843 * Creates a new JSON string and adds it to an object.
944 * 844 *
945 * The string data is copied. 845 * The string data is copied.
950 * @return the new value or @c NULL if allocation fails 850 * @return the new value or @c NULL if allocation fails
951 * @see cxJsonObjPut() 851 * @see cxJsonObjPut()
952 * @see cxJsonCreateCxString() 852 * @see cxJsonCreateCxString()
953 */ 853 */
954 cx_attr_nonnull 854 cx_attr_nonnull
955 cx_attr_export 855 CX_EXPORT CxJsonValue* cxJsonObjPutCxString(CxJsonValue* obj, cxstring name, cxstring str);
956 CxJsonValue* cxJsonObjPutCxString(CxJsonValue* obj, cxstring name, cxstring str);
957 856
958 /** 857 /**
959 * Creates a new JSON literal and adds it to an object. 858 * Creates a new JSON literal and adds it to an object.
960 * 859 *
961 * @param obj the target JSON object 860 * @param obj the target JSON object
964 * @return the new value or @c NULL if allocation fails 863 * @return the new value or @c NULL if allocation fails
965 * @see cxJsonObjPut() 864 * @see cxJsonObjPut()
966 * @see cxJsonCreateLiteral() 865 * @see cxJsonCreateLiteral()
967 */ 866 */
968 cx_attr_nonnull 867 cx_attr_nonnull
969 cx_attr_export 868 CX_EXPORT CxJsonValue* cxJsonObjPutLiteral(CxJsonValue* obj, cxstring name, CxJsonLiteral lit);
970 CxJsonValue* cxJsonObjPutLiteral(CxJsonValue* obj, cxstring name, CxJsonLiteral lit);
971 869
972 /** 870 /**
973 * Recursively deallocates the memory of a JSON value. 871 * Recursively deallocates the memory of a JSON value.
974 * 872 *
975 * @remark The type of each deallocated value will be changed 873 * @remark The type of each deallocated value will be changed
976 * to #CX_JSON_NOTHING and values of such type will be skipped 874 * to #CX_JSON_NOTHING, and values of such a type will be skipped
977 * by the de-allocation. That means, this function protects 875 * by the deallocation. That means this function protects
978 * you from double-frees when you are accidentally freeing 876 * you from double-frees when you are accidentally freeing
979 * a nested value and then the parent value (or vice versa). 877 * a nested value and then the parent value (or vice versa).
980 * 878 *
981 * @param value the value 879 * @param value the value
982 */ 880 */
983 cx_attr_export 881 CX_EXPORT void cxJsonValueFree(CxJsonValue *value);
984 void cxJsonValueFree(CxJsonValue *value);
985 882
986 /** 883 /**
987 * Tries to obtain the next JSON value. 884 * Tries to obtain the next JSON value.
988 * 885 *
989 * Before this function can be called, the input buffer needs 886 * Before this function can be called, the input buffer needs
991 * 888 *
992 * When this function returns #CX_JSON_INCOMPLETE_DATA, you can 889 * When this function returns #CX_JSON_INCOMPLETE_DATA, you can
993 * add the missing data with another invocation of cxJsonFill() 890 * add the missing data with another invocation of cxJsonFill()
994 * and then repeat the call to cxJsonNext(). 891 * and then repeat the call to cxJsonNext().
995 * 892 *
996 * @param json the json interface 893 * @param json the JSON interface
997 * @param value a pointer where the next value shall be stored 894 * @param value a pointer where the next value shall be stored
998 * @retval CX_JSON_NO_ERROR successfully retrieve the @p value 895 * @retval CX_JSON_NO_ERROR successfully retrieve the @p value
999 * @retval CX_JSON_NO_DATA there is no (more) data in the buffer to read from 896 * @retval CX_JSON_NO_DATA there is no (more) data in the buffer to read from
1000 * @retval CX_JSON_INCOMPLETE_DATA an incomplete value was read 897 * @retval CX_JSON_INCOMPLETE_DATA an incomplete value was read
1001 * and more data needs to be filled 898 * and more data needs to be filled
1003 * @retval CX_JSON_BUFFER_ALLOC_FAILED allocating internal buffer space failed 900 * @retval CX_JSON_BUFFER_ALLOC_FAILED allocating internal buffer space failed
1004 * @retval CX_JSON_VALUE_ALLOC_FAILED allocating memory for a CxJsonValue failed 901 * @retval CX_JSON_VALUE_ALLOC_FAILED allocating memory for a CxJsonValue failed
1005 * @retval CX_JSON_FORMAT_ERROR_NUMBER the JSON text contains an illegally formatted number 902 * @retval CX_JSON_FORMAT_ERROR_NUMBER the JSON text contains an illegally formatted number
1006 * @retval CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN JSON syntax error 903 * @retval CX_JSON_FORMAT_ERROR_UNEXPECTED_TOKEN JSON syntax error
1007 */ 904 */
1008 cx_attr_nonnull 905 cx_attr_nonnull cx_attr_access_w(2)
1009 cx_attr_access_w(2) 906 CX_EXPORT CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value);
1010 cx_attr_export
1011 CxJsonStatus cxJsonNext(CxJson *json, CxJsonValue **value);
1012 907
1013 /** 908 /**
1014 * Checks if the specified value is a JSON object. 909 * Checks if the specified value is a JSON object.
1015 * 910 *
1016 * @param value a pointer to the value 911 * @param value a pointer to the value
1017 * @retval true the value is a JSON object 912 * @retval true the value is a JSON object
1018 * @retval false otherwise 913 * @retval false otherwise
1019 */ 914 */
1020 cx_attr_nonnull 915 cx_attr_nonnull
1021 static inline bool cxJsonIsObject(const CxJsonValue *value) { 916 CX_INLINE bool cxJsonIsObject(const CxJsonValue *value) {
1022 return value->type == CX_JSON_OBJECT; 917 return value->type == CX_JSON_OBJECT;
1023 } 918 }
1024 919
1025 /** 920 /**
1026 * Checks if the specified value is a JSON array. 921 * Checks if the specified value is a JSON array.
1028 * @param value a pointer to the value 923 * @param value a pointer to the value
1029 * @retval true the value is a JSON array 924 * @retval true the value is a JSON array
1030 * @retval false otherwise 925 * @retval false otherwise
1031 */ 926 */
1032 cx_attr_nonnull 927 cx_attr_nonnull
1033 static inline bool cxJsonIsArray(const CxJsonValue *value) { 928 CX_INLINE bool cxJsonIsArray(const CxJsonValue *value) {
1034 return value->type == CX_JSON_ARRAY; 929 return value->type == CX_JSON_ARRAY;
1035 } 930 }
1036 931
1037 /** 932 /**
1038 * Checks if the specified value is a string. 933 * Checks if the specified value is a string.
1040 * @param value a pointer to the value 935 * @param value a pointer to the value
1041 * @retval true the value is a string 936 * @retval true the value is a string
1042 * @retval false otherwise 937 * @retval false otherwise
1043 */ 938 */
1044 cx_attr_nonnull 939 cx_attr_nonnull
1045 static inline bool cxJsonIsString(const CxJsonValue *value) { 940 CX_INLINE bool cxJsonIsString(const CxJsonValue *value) {
1046 return value->type == CX_JSON_STRING; 941 return value->type == CX_JSON_STRING;
1047 } 942 }
1048 943
1049 /** 944 /**
1050 * Checks if the specified value is a JSON number. 945 * Checks if the specified value is a JSON number.
1051 * 946 *
1052 * This function will return true for both floating point and 947 * This function will return true for both floating-point and
1053 * integer numbers. 948 * integer numbers.
1054 * 949 *
1055 * @param value a pointer to the value 950 * @param value a pointer to the value
1056 * @retval true the value is a JSON number 951 * @retval true the value is a JSON number
1057 * @retval false otherwise 952 * @retval false otherwise
1058 * @see cxJsonIsInteger() 953 * @see cxJsonIsInteger()
1059 */ 954 */
1060 cx_attr_nonnull 955 cx_attr_nonnull
1061 static inline bool cxJsonIsNumber(const CxJsonValue *value) { 956 CX_INLINE bool cxJsonIsNumber(const CxJsonValue *value) {
1062 return value->type == CX_JSON_NUMBER || value->type == CX_JSON_INTEGER; 957 return value->type == CX_JSON_NUMBER || value->type == CX_JSON_INTEGER;
1063 } 958 }
1064 959
1065 /** 960 /**
1066 * Checks if the specified value is an integer number. 961 * Checks if the specified value is an integer number.
1069 * @retval true the value is an integer number 964 * @retval true the value is an integer number
1070 * @retval false otherwise 965 * @retval false otherwise
1071 * @see cxJsonIsNumber() 966 * @see cxJsonIsNumber()
1072 */ 967 */
1073 cx_attr_nonnull 968 cx_attr_nonnull
1074 static inline bool cxJsonIsInteger(const CxJsonValue *value) { 969 CX_INLINE bool cxJsonIsInteger(const CxJsonValue *value) {
1075 return value->type == CX_JSON_INTEGER; 970 return value->type == CX_JSON_INTEGER;
1076 } 971 }
1077 972
1078 /** 973 /**
1079 * Checks if the specified value is a JSON literal. 974 * Checks if the specified value is a JSON literal.
1086 * @see cxJsonIsTrue() 981 * @see cxJsonIsTrue()
1087 * @see cxJsonIsFalse() 982 * @see cxJsonIsFalse()
1088 * @see cxJsonIsNull() 983 * @see cxJsonIsNull()
1089 */ 984 */
1090 cx_attr_nonnull 985 cx_attr_nonnull
1091 static inline bool cxJsonIsLiteral(const CxJsonValue *value) { 986 CX_INLINE bool cxJsonIsLiteral(const CxJsonValue *value) {
1092 return value->type == CX_JSON_LITERAL; 987 return value->type == CX_JSON_LITERAL;
1093 } 988 }
1094 989
1095 /** 990 /**
1096 * Checks if the specified value is a Boolean literal. 991 * Checks if the specified value is a Boolean literal.
1100 * @retval false otherwise 995 * @retval false otherwise
1101 * @see cxJsonIsTrue() 996 * @see cxJsonIsTrue()
1102 * @see cxJsonIsFalse() 997 * @see cxJsonIsFalse()
1103 */ 998 */
1104 cx_attr_nonnull 999 cx_attr_nonnull
1105 static inline bool cxJsonIsBool(const CxJsonValue *value) { 1000 CX_INLINE bool cxJsonIsBool(const CxJsonValue *value) {
1106 return cxJsonIsLiteral(value) && value->value.literal != CX_JSON_NULL; 1001 return cxJsonIsLiteral(value) && value->value.literal != CX_JSON_NULL;
1107 } 1002 }
1108 1003
1109 /** 1004 /**
1110 * Checks if the specified value is @c true. 1005 * Checks if the specified value is @c true.
1111 * 1006 *
1112 * @remark Be advised, that this is not the same as 1007 * @remark Be advised that this is different from
1113 * testing @c !cxJsonIsFalse(v). 1008 * testing @c !cxJsonIsFalse(v).
1114 * 1009 *
1115 * @param value a pointer to the value 1010 * @param value a pointer to the value
1116 * @retval true the value is @c true 1011 * @retval true the value is @c true
1117 * @retval false otherwise 1012 * @retval false otherwise
1118 * @see cxJsonIsBool() 1013 * @see cxJsonIsBool()
1119 * @see cxJsonIsFalse() 1014 * @see cxJsonIsFalse()
1120 */ 1015 */
1121 cx_attr_nonnull 1016 cx_attr_nonnull
1122 static inline bool cxJsonIsTrue(const CxJsonValue *value) { 1017 CX_INLINE bool cxJsonIsTrue(const CxJsonValue *value) {
1123 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_TRUE; 1018 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_TRUE;
1124 } 1019 }
1125 1020
1126 /** 1021 /**
1127 * Checks if the specified value is @c false. 1022 * Checks if the specified value is @c false.
1128 * 1023 *
1129 * @remark Be advised, that this is not the same as 1024 * @remark Be advised that this is different from
1130 * testing @c !cxJsonIsTrue(v). 1025 * testing @c !cxJsonIsTrue(v).
1131 * 1026 *
1132 * @param value a pointer to the value 1027 * @param value a pointer to the value
1133 * @retval true the value is @c false 1028 * @retval true the value is @c false
1134 * @retval false otherwise 1029 * @retval false otherwise
1135 * @see cxJsonIsBool() 1030 * @see cxJsonIsBool()
1136 * @see cxJsonIsTrue() 1031 * @see cxJsonIsTrue()
1137 */ 1032 */
1138 cx_attr_nonnull 1033 cx_attr_nonnull
1139 static inline bool cxJsonIsFalse(const CxJsonValue *value) { 1034 CX_INLINE bool cxJsonIsFalse(const CxJsonValue *value) {
1140 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_FALSE; 1035 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_FALSE;
1141 } 1036 }
1142 1037
1143 /** 1038 /**
1144 * Checks if the specified value is @c null. 1039 * Checks if the specified value is @c null.
1147 * @retval true the value is @c null 1042 * @retval true the value is @c null
1148 * @retval false otherwise 1043 * @retval false otherwise
1149 * @see cxJsonIsLiteral() 1044 * @see cxJsonIsLiteral()
1150 */ 1045 */
1151 cx_attr_nonnull 1046 cx_attr_nonnull
1152 static inline bool cxJsonIsNull(const CxJsonValue *value) { 1047 CX_INLINE bool cxJsonIsNull(const CxJsonValue *value) {
1153 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_NULL; 1048 return cxJsonIsLiteral(value) && value->value.literal == CX_JSON_NULL;
1154 } 1049 }
1155 1050
1156 /** 1051 /**
1157 * Obtains a C string from the given JSON value. 1052 * Obtains a C string from the given JSON value.
1160 * 1055 *
1161 * @param value the JSON value 1056 * @param value the JSON value
1162 * @return the value represented as C string 1057 * @return the value represented as C string
1163 * @see cxJsonIsString() 1058 * @see cxJsonIsString()
1164 */ 1059 */
1165 cx_attr_nonnull 1060 cx_attr_nonnull cx_attr_returns_nonnull
1166 cx_attr_returns_nonnull 1061 CX_EXPORT char *cxJsonAsString(const CxJsonValue *value);
1167 static inline char *cxJsonAsString(const CxJsonValue *value) {
1168 return value->value.string.ptr;
1169 }
1170 1062
1171 /** 1063 /**
1172 * Obtains a UCX string from the given JSON value. 1064 * Obtains a UCX string from the given JSON value.
1173 * 1065 *
1174 * If the @p value is not a string, the behavior is undefined. 1066 * If the @p value is not a string, the behavior is undefined.
1176 * @param value the JSON value 1068 * @param value the JSON value
1177 * @return the value represented as UCX string 1069 * @return the value represented as UCX string
1178 * @see cxJsonIsString() 1070 * @see cxJsonIsString()
1179 */ 1071 */
1180 cx_attr_nonnull 1072 cx_attr_nonnull
1181 static inline cxstring cxJsonAsCxString(const CxJsonValue *value) { 1073 CX_EXPORT cxstring cxJsonAsCxString(const CxJsonValue *value);
1182 return cx_strcast(value->value.string);
1183 }
1184 1074
1185 /** 1075 /**
1186 * Obtains a mutable UCX string from the given JSON value. 1076 * Obtains a mutable UCX string from the given JSON value.
1187 * 1077 *
1188 * If the @p value is not a string, the behavior is undefined. 1078 * If the @p value is not a string, the behavior is undefined.
1190 * @param value the JSON value 1080 * @param value the JSON value
1191 * @return the value represented as mutable UCX string 1081 * @return the value represented as mutable UCX string
1192 * @see cxJsonIsString() 1082 * @see cxJsonIsString()
1193 */ 1083 */
1194 cx_attr_nonnull 1084 cx_attr_nonnull
1195 static inline cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value) { 1085 CX_EXPORT cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value);
1196 return value->value.string; 1086
1197 } 1087 /**
1198 1088 * Obtains a double-precision floating-point value from the given JSON value.
1199 /**
1200 * Obtains a double-precision floating point value from the given JSON value.
1201 * 1089 *
1202 * If the @p value is not a JSON number, the behavior is undefined. 1090 * If the @p value is not a JSON number, the behavior is undefined.
1203 * 1091 *
1204 * @param value the JSON value 1092 * @param value the JSON value
1205 * @return the value represented as double 1093 * @return the value represented as double
1206 * @see cxJsonIsNumber() 1094 * @see cxJsonIsNumber()
1207 */ 1095 */
1208 cx_attr_nonnull 1096 cx_attr_nonnull
1209 static inline double cxJsonAsDouble(const CxJsonValue *value) { 1097 CX_EXPORT double cxJsonAsDouble(const CxJsonValue *value);
1210 if (value->type == CX_JSON_INTEGER) {
1211 return (double) value->value.integer;
1212 } else {
1213 return value->value.number;
1214 }
1215 }
1216 1098
1217 /** 1099 /**
1218 * Obtains a 64-bit signed integer from the given JSON value. 1100 * Obtains a 64-bit signed integer from the given JSON value.
1219 * 1101 *
1220 * If the @p value is not a JSON number, the behavior is undefined. 1102 * If the @p value is not a JSON number, the behavior is undefined.
1225 * @return the value represented as double 1107 * @return the value represented as double
1226 * @see cxJsonIsNumber() 1108 * @see cxJsonIsNumber()
1227 * @see cxJsonIsInteger() 1109 * @see cxJsonIsInteger()
1228 */ 1110 */
1229 cx_attr_nonnull 1111 cx_attr_nonnull
1230 static inline int64_t cxJsonAsInteger(const CxJsonValue *value) { 1112 CX_EXPORT int64_t cxJsonAsInteger(const CxJsonValue *value);
1231 if (value->type == CX_JSON_INTEGER) {
1232 return value->value.integer;
1233 } else {
1234 return (int64_t) value->value.number;
1235 }
1236 }
1237 1113
1238 /** 1114 /**
1239 * Obtains a Boolean value from the given JSON value. 1115 * Obtains a Boolean value from the given JSON value.
1240 * 1116 *
1241 * If the @p value is not a JSON literal, the behavior is undefined. 1117 * If the @p value is not a JSON literal, the behavior is undefined.
1244 * @param value the JSON value 1120 * @param value the JSON value
1245 * @return the value represented as double 1121 * @return the value represented as double
1246 * @see cxJsonIsLiteral() 1122 * @see cxJsonIsLiteral()
1247 */ 1123 */
1248 cx_attr_nonnull 1124 cx_attr_nonnull
1249 static inline bool cxJsonAsBool(const CxJsonValue *value) { 1125 CX_INLINE bool cxJsonAsBool(const CxJsonValue *value) {
1250 return value->value.literal == CX_JSON_TRUE; 1126 return value->value.literal == CX_JSON_TRUE;
1251 } 1127 }
1252 1128
1253 /** 1129 /**
1254 * Returns the size of a JSON array. 1130 * Returns the size of a JSON array.
1258 * @param value the JSON value 1134 * @param value the JSON value
1259 * @return the size of the array 1135 * @return the size of the array
1260 * @see cxJsonIsArray() 1136 * @see cxJsonIsArray()
1261 */ 1137 */
1262 cx_attr_nonnull 1138 cx_attr_nonnull
1263 static inline size_t cxJsonArrSize(const CxJsonValue *value) { 1139 CX_INLINE size_t cxJsonArrSize(const CxJsonValue *value) {
1264 return value->value.array.array_size; 1140 return value->value.array.array_size;
1265 } 1141 }
1266 1142
1267 /** 1143 /**
1268 * Returns an element from a JSON array. 1144 * Returns an element from a JSON array.
1276 * @param value the JSON value 1152 * @param value the JSON value
1277 * @param index the index in the array 1153 * @param index the index in the array
1278 * @return the value at the specified index 1154 * @return the value at the specified index
1279 * @see cxJsonIsArray() 1155 * @see cxJsonIsArray()
1280 */ 1156 */
1281 cx_attr_nonnull 1157 cx_attr_nonnull cx_attr_returns_nonnull
1282 cx_attr_returns_nonnull 1158 CX_EXPORT CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index);
1283 cx_attr_export 1159
1284 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index); 1160 /**
1161 * Removes an element from a JSON array.
1162 *
1163 * If the @p value is not a JSON array, the behavior is undefined.
1164 *
1165 * This function, in contrast to cxJsonArrayGet(), returns @c NULL
1166 * when the index is out of bounds.
1167 *
1168 * @param value the JSON value
1169 * @param index the index in the array
1170 * @return the removed value from the specified index or @c NULL when the index was out of bounds
1171 * @see cxJsonIsArray()
1172 */
1173 cx_attr_nonnull
1174 CX_EXPORT CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index);
1285 1175
1286 /** 1176 /**
1287 * Returns an iterator over the JSON array elements. 1177 * Returns an iterator over the JSON array elements.
1288 * 1178 *
1289 * The iterator yields values of type @c CxJsonValue* . 1179 * The iterator yields values of type @c CxJsonValue* .
1292 * 1182 *
1293 * @param value the JSON value 1183 * @param value the JSON value
1294 * @return an iterator over the array elements 1184 * @return an iterator over the array elements
1295 * @see cxJsonIsArray() 1185 * @see cxJsonIsArray()
1296 */ 1186 */
1297 cx_attr_nonnull 1187 cx_attr_nonnull cx_attr_nodiscard
1298 cx_attr_nodiscard 1188 CX_EXPORT CxIterator cxJsonArrIter(const CxJsonValue *value);
1299 cx_attr_export
1300 CxIterator cxJsonArrIter(const CxJsonValue *value);
1301 1189
1302 /** 1190 /**
1303 * Returns an iterator over the JSON object members. 1191 * Returns an iterator over the JSON object members.
1304 * 1192 *
1305 * The iterator yields values of type @c CxJsonObjValue* which 1193 * The iterator yields values of type @c CxJsonObjValue* which
1309 * 1197 *
1310 * @param value the JSON value 1198 * @param value the JSON value
1311 * @return an iterator over the object members 1199 * @return an iterator over the object members
1312 * @see cxJsonIsObject() 1200 * @see cxJsonIsObject()
1313 */ 1201 */
1314 cx_attr_nonnull 1202 cx_attr_nonnull cx_attr_nodiscard
1315 cx_attr_nodiscard 1203 CX_EXPORT CxIterator cxJsonObjIter(const CxJsonValue *value);
1316 cx_attr_export 1204
1317 CxIterator cxJsonObjIter(const CxJsonValue *value); 1205 /**
1318 1206 * Internal function, do not use.
1319 /** 1207 * @param value the JSON object
1320 * @copydoc cxJsonObjGet() 1208 * @param name the key to look up
1321 */ 1209 * @return the value corresponding to the key
1322 cx_attr_nonnull 1210 */
1323 cx_attr_returns_nonnull 1211 cx_attr_nonnull cx_attr_returns_nonnull
1324 cx_attr_export 1212 CX_EXPORT CxJsonValue *cx_json_obj_get(const CxJsonValue *value, cxstring name);
1325 CxJsonValue *cx_json_obj_get_cxstr(const CxJsonValue *value, cxstring name); 1213
1326
1327 #ifdef __cplusplus
1328 } // extern "C"
1329
1330 static inline CxJsonValue *cxJsonObjGet(const CxJsonValue *value, cxstring name) {
1331 return cx_json_obj_get_cxstr(value, name);
1332 }
1333
1334 static inline CxJsonValue *cxJsonObjGet(const CxJsonValue *value, cxmutstr name) {
1335 return cx_json_obj_get_cxstr(value, cx_strcast(name));
1336 }
1337
1338 static inline CxJsonValue *cxJsonObjGet(const CxJsonValue *value, const char *name) {
1339 return cx_json_obj_get_cxstr(value, cx_str(name));
1340 }
1341
1342 extern "C" {
1343 #else
1344 /** 1214 /**
1345 * Returns a value corresponding to a key in a JSON object. 1215 * Returns a value corresponding to a key in a JSON object.
1346 * 1216 *
1347 * If the @p value is not a JSON object, the behavior is undefined. 1217 * If the @p value is not a JSON object, the behavior is undefined.
1348 * 1218 *
1353 * @param value the JSON object 1223 * @param value the JSON object
1354 * @param name the key to look up 1224 * @param name the key to look up
1355 * @return the value corresponding to the key 1225 * @return the value corresponding to the key
1356 * @see cxJsonIsObject() 1226 * @see cxJsonIsObject()
1357 */ 1227 */
1358 #define cxJsonObjGet(value, name) _Generic((name), \ 1228 #define cxJsonObjGet(value, name) cx_json_obj_get(value, cx_strcast(name))
1359 cxstring: cx_json_obj_get_cxstr, \ 1229
1360 cxmutstr: cx_json_obj_get_mutstr, \ 1230 /**
1361 char*: cx_json_obj_get_str, \ 1231 * Internal function, do not use.
1362 const char*: cx_json_obj_get_str) \ 1232 * @param value the JSON object
1363 (value, name) 1233 * @param name the key to look up
1364 1234 * @return the value corresponding to the key or @c NULL when the key is not part of the object
1365 /** 1235 */
1366 * @copydoc cxJsonObjGet() 1236 cx_attr_nonnull
1367 */ 1237 CX_EXPORT CxJsonValue *cx_json_obj_remove(CxJsonValue *value, cxstring name);
1368 cx_attr_nonnull 1238
1369 cx_attr_returns_nonnull 1239 /**
1370 static inline CxJsonValue *cx_json_obj_get_mutstr(const CxJsonValue *value, cxmutstr name) { 1240 * Removes and returns a value corresponding to a key in a JSON object.
1371 return cx_json_obj_get_cxstr(value, cx_strcast(name)); 1241 *
1372 } 1242 * If the @p value is not a JSON object, the behavior is undefined.
1373 1243 *
1374 /** 1244 * This function, in contrast to cxJsonObjGet() returns @c NULL when the
1375 * @copydoc cxJsonObjGet() 1245 * object does not contain @p name.
1376 */ 1246 *
1377 cx_attr_nonnull 1247 * @param value the JSON object
1378 cx_attr_returns_nonnull 1248 * @param name the key to look up
1379 cx_attr_cstr_arg(2) 1249 * @return the value corresponding to the key or @c NULL when the key is not part of the object
1380 static inline CxJsonValue *cx_json_obj_get_str(const CxJsonValue *value, const char *name) { 1250 * @see cxJsonIsObject()
1381 return cx_json_obj_get_cxstr(value, cx_str(name)); 1251 */
1252 #define cxJsonObjRemove(value, name) cx_json_obj_remove(value, cx_strcast(name))
1253
1254 #ifdef __cplusplus
1382 } 1255 }
1383 #endif 1256 #endif
1384 1257
1385 #ifdef __cplusplus
1386 }
1387 #endif
1388
1389 #endif /* UCX_JSON_H */ 1258 #endif /* UCX_JSON_H */
1390 1259

mercurial