ucx/cx/json.h

changeset 112
c3f2f16fa4b8
parent 102
64ded9f6a6c6
child 113
dde28a806552
equal deleted inserted replaced
111:81c4f73236a4 112:c3f2f16fa4b8
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.
494 * This function blocks until either all data is written, or an error occurs. 494 * 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 495 * 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 496 * that the data is only partially written when an error occurs with no
497 * way to indicate how much data was written. 497 * way to indicate how much data was written.
498 * To avoid this problem, you can use a CxBuffer as @p target which is 498 * 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 499 * 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 500 * feature to relay the data.
501 * write it to the actual target.
502 * 501 *
503 * @param target the buffer or stream where to write to 502 * @param target the buffer or stream where to write to
504 * @param value the value that shall be written 503 * @param value the value that shall be written
505 * @param wfunc the write function to use 504 * @param wfunc the write function to use
506 * @param settings formatting settings (or @c NULL to use a compact default) 505 * @param settings formatting settings (or @c NULL to use a compact default)
515 cx_write_func wfunc, 514 cx_write_func wfunc,
516 const CxJsonWriter* settings 515 const CxJsonWriter* settings
517 ); 516 );
518 517
519 /** 518 /**
520 * Initializes the json interface. 519 * Initializes the JSON interface.
521 * 520 *
522 * @param json the json interface 521 * @param json the JSON interface
523 * @param allocator the allocator that shall be used for the produced values 522 * @param allocator the allocator that shall be used for the produced values
524 * @see cxJsonDestroy() 523 * @see cxJsonDestroy()
525 */ 524 */
526 cx_attr_nonnull_arg(1) 525 cx_attr_nonnull_arg(1)
527 cx_attr_export 526 cx_attr_export
528 void cxJsonInit(CxJson *json, const CxAllocator *allocator); 527 void cxJsonInit(CxJson *json, const CxAllocator *allocator);
529 528
530 /** 529 /**
531 * Destroys the json interface. 530 * Destroys the JSON interface.
532 * 531 *
533 * @param json the json interface 532 * @param json the JSON interface
534 * @see cxJsonInit() 533 * @see cxJsonInit()
535 */ 534 */
536 cx_attr_nonnull 535 cx_attr_nonnull
537 cx_attr_export 536 cx_attr_export
538 void cxJsonDestroy(CxJson *json); 537 void cxJsonDestroy(CxJson *json);
539 538
540 /** 539 /**
541 * Destroys and re-initializes the json interface. 540 * Destroys and re-initializes the JSON interface.
542 * 541 *
543 * You might want to use this, to reset the parser after 542 * You might want to use this to reset the parser after
544 * encountering a syntax error. 543 * encountering a syntax error.
545 * 544 *
546 * @param json the json interface 545 * @param json the JSON interface
547 */ 546 */
548 cx_attr_nonnull 547 cx_attr_nonnull
549 static inline void cxJsonReset(CxJson *json) { 548 static inline void cxJsonReset(CxJson *json) {
550 const CxAllocator *allocator = json->allocator; 549 const CxAllocator *allocator = json->allocator;
551 cxJsonDestroy(json); 550 cxJsonDestroy(json);
561 * pointer to the data in that case. When you invoke the fill 560 * pointer to the data in that case. When you invoke the fill
562 * function more than once before calling cxJsonNext(), 561 * function more than once before calling cxJsonNext(),
563 * the additional data is appended - inevitably leading to 562 * the additional data is appended - inevitably leading to
564 * an allocation of a new buffer and copying the previous contents. 563 * an allocation of a new buffer and copying the previous contents.
565 * 564 *
566 * @param json the json interface 565 * @param json the JSON interface
567 * @param buf the source buffer 566 * @param buf the source buffer
568 * @param len the length of the source buffer 567 * @param len the length of the source buffer
569 * @retval zero success 568 * @retval zero success
570 * @retval non-zero internal allocation error 569 * @retval non-zero internal allocation error
571 * @see cxJsonFill() 570 * @see cxJsonFill()
573 cx_attr_nonnull 572 cx_attr_nonnull
574 cx_attr_access_r(2, 3) 573 cx_attr_access_r(2, 3)
575 cx_attr_export 574 cx_attr_export
576 int cxJsonFilln(CxJson *json, const char *buf, size_t len); 575 int cxJsonFilln(CxJson *json, const char *buf, size_t len);
577 576
578 #ifdef __cplusplus 577
579 } // extern "C" 578 /**
580 579 * Internal function, do not use.
581 cx_attr_nonnull 580 *
582 static inline int cxJsonFill( 581 * @param json the JSON interface
583 CxJson *json, 582 * @param str the string
584 cxstring str 583 * @retval zero success
585 ) { 584 * @retval non-zero internal allocation error
585 */
586 cx_attr_nonnull
587 static inline int cx_json_fill(CxJson *json, cxstring str) {
586 return cxJsonFilln(json, str.ptr, str.length); 588 return cxJsonFilln(json, str.ptr, str.length);
587 } 589 }
588 590
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 /** 591 /**
609 * Fills the input buffer. 592 * Fills the input buffer.
610 * 593 *
611 * The JSON interface tries to avoid copying the input data. 594 * The JSON interface tries to avoid copying the input data.
612 * When you use this function and cxJsonNext() interleaving, 595 * When you use this function and cxJsonNext() interleaving,
614 * pointer to the data in that case. When you invoke the fill 597 * pointer to the data in that case. When you invoke the fill
615 * function more than once before calling cxJsonNext(), 598 * function more than once before calling cxJsonNext(),
616 * the additional data is appended - inevitably leading to 599 * the additional data is appended - inevitably leading to
617 * an allocation of a new buffer and copying the previous contents. 600 * an allocation of a new buffer and copying the previous contents.
618 * 601 *
619 * @param json the json interface 602 * @param json the JSON interface
620 * @param str the source string 603 * @param str the source string
621 * @retval zero success 604 * @retval zero success
622 * @retval non-zero internal allocation error 605 * @retval non-zero internal allocation error
623 * @see cxJsonFilln() 606 * @see cxJsonFilln()
624 */ 607 */
625 #define cxJsonFill(json, str) _Generic((str), \ 608 #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 609
667 /** 610 /**
668 * Creates a new (empty) JSON object. 611 * Creates a new (empty) JSON object.
669 * 612 *
670 * @param allocator the allocator to use 613 * @param allocator the allocator to use
971 914
972 /** 915 /**
973 * Recursively deallocates the memory of a JSON value. 916 * Recursively deallocates the memory of a JSON value.
974 * 917 *
975 * @remark The type of each deallocated value will be changed 918 * @remark The type of each deallocated value will be changed
976 * to #CX_JSON_NOTHING and values of such type will be skipped 919 * to #CX_JSON_NOTHING, and values of such a type will be skipped
977 * by the de-allocation. That means, this function protects 920 * by the deallocation. That means this function protects
978 * you from double-frees when you are accidentally freeing 921 * you from double-frees when you are accidentally freeing
979 * a nested value and then the parent value (or vice versa). 922 * a nested value and then the parent value (or vice versa).
980 * 923 *
981 * @param value the value 924 * @param value the value
982 */ 925 */
991 * 934 *
992 * When this function returns #CX_JSON_INCOMPLETE_DATA, you can 935 * When this function returns #CX_JSON_INCOMPLETE_DATA, you can
993 * add the missing data with another invocation of cxJsonFill() 936 * add the missing data with another invocation of cxJsonFill()
994 * and then repeat the call to cxJsonNext(). 937 * and then repeat the call to cxJsonNext().
995 * 938 *
996 * @param json the json interface 939 * @param json the JSON interface
997 * @param value a pointer where the next value shall be stored 940 * @param value a pointer where the next value shall be stored
998 * @retval CX_JSON_NO_ERROR successfully retrieve the @p value 941 * @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 942 * @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 943 * @retval CX_JSON_INCOMPLETE_DATA an incomplete value was read
1001 * and more data needs to be filled 944 * and more data needs to be filled
1047 } 990 }
1048 991
1049 /** 992 /**
1050 * Checks if the specified value is a JSON number. 993 * Checks if the specified value is a JSON number.
1051 * 994 *
1052 * This function will return true for both floating point and 995 * This function will return true for both floating-point and
1053 * integer numbers. 996 * integer numbers.
1054 * 997 *
1055 * @param value a pointer to the value 998 * @param value a pointer to the value
1056 * @retval true the value is a JSON number 999 * @retval true the value is a JSON number
1057 * @retval false otherwise 1000 * @retval false otherwise
1107 } 1050 }
1108 1051
1109 /** 1052 /**
1110 * Checks if the specified value is @c true. 1053 * Checks if the specified value is @c true.
1111 * 1054 *
1112 * @remark Be advised, that this is not the same as 1055 * @remark Be advised that this is different from
1113 * testing @c !cxJsonIsFalse(v). 1056 * testing @c !cxJsonIsFalse(v).
1114 * 1057 *
1115 * @param value a pointer to the value 1058 * @param value a pointer to the value
1116 * @retval true the value is @c true 1059 * @retval true the value is @c true
1117 * @retval false otherwise 1060 * @retval false otherwise
1124 } 1067 }
1125 1068
1126 /** 1069 /**
1127 * Checks if the specified value is @c false. 1070 * Checks if the specified value is @c false.
1128 * 1071 *
1129 * @remark Be advised, that this is not the same as 1072 * @remark Be advised that this is different from
1130 * testing @c !cxJsonIsTrue(v). 1073 * testing @c !cxJsonIsTrue(v).
1131 * 1074 *
1132 * @param value a pointer to the value 1075 * @param value a pointer to the value
1133 * @retval true the value is @c false 1076 * @retval true the value is @c false
1134 * @retval false otherwise 1077 * @retval false otherwise
1195 static inline cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value) { 1138 static inline cxmutstr cxJsonAsCxMutStr(const CxJsonValue *value) {
1196 return value->value.string; 1139 return value->value.string;
1197 } 1140 }
1198 1141
1199 /** 1142 /**
1200 * Obtains a double-precision floating point value from the given JSON value. 1143 * Obtains a double-precision floating-point value from the given JSON value.
1201 * 1144 *
1202 * If the @p value is not a JSON number, the behavior is undefined. 1145 * If the @p value is not a JSON number, the behavior is undefined.
1203 * 1146 *
1204 * @param value the JSON value 1147 * @param value the JSON value
1205 * @return the value represented as double 1148 * @return the value represented as double
1282 cx_attr_returns_nonnull 1225 cx_attr_returns_nonnull
1283 cx_attr_export 1226 cx_attr_export
1284 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index); 1227 CxJsonValue *cxJsonArrGet(const CxJsonValue *value, size_t index);
1285 1228
1286 /** 1229 /**
1230 * Removes an element from a JSON array.
1231 *
1232 * If the @p value is not a JSON array, the behavior is undefined.
1233 *
1234 * This function, in contrast to cxJsonArrayGet(), returns @c NULL
1235 * when the index is out of bounds.
1236 *
1237 * @param value the JSON value
1238 * @param index the index in the array
1239 * @return the removed value from the specified index or @c NULL when the index was out of bounds
1240 * @see cxJsonIsArray()
1241 */
1242 cx_attr_nonnull
1243 cx_attr_export
1244 CxJsonValue *cxJsonArrRemove(CxJsonValue *value, size_t index);
1245
1246 /**
1287 * Returns an iterator over the JSON array elements. 1247 * Returns an iterator over the JSON array elements.
1288 * 1248 *
1289 * The iterator yields values of type @c CxJsonValue* . 1249 * The iterator yields values of type @c CxJsonValue* .
1290 * 1250 *
1291 * If the @p value is not a JSON array, the behavior is undefined. 1251 * If the @p value is not a JSON array, the behavior is undefined.
1315 cx_attr_nodiscard 1275 cx_attr_nodiscard
1316 cx_attr_export 1276 cx_attr_export
1317 CxIterator cxJsonObjIter(const CxJsonValue *value); 1277 CxIterator cxJsonObjIter(const CxJsonValue *value);
1318 1278
1319 /** 1279 /**
1320 * @copydoc cxJsonObjGet() 1280 * Internal function, do not use.
1281 * @param value the JSON object
1282 * @param name the key to look up
1283 * @return the value corresponding to the key
1321 */ 1284 */
1322 cx_attr_nonnull 1285 cx_attr_nonnull
1323 cx_attr_returns_nonnull 1286 cx_attr_returns_nonnull
1324 cx_attr_export 1287 cx_attr_export
1325 CxJsonValue *cx_json_obj_get_cxstr(const CxJsonValue *value, cxstring name); 1288 CxJsonValue *cx_json_obj_get(const CxJsonValue *value, cxstring name);
1326 1289
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 /** 1290 /**
1345 * Returns a value corresponding to a key in a JSON object. 1291 * Returns a value corresponding to a key in a JSON object.
1346 * 1292 *
1347 * If the @p value is not a JSON object, the behavior is undefined. 1293 * If the @p value is not a JSON object, the behavior is undefined.
1348 * 1294 *
1353 * @param value the JSON object 1299 * @param value the JSON object
1354 * @param name the key to look up 1300 * @param name the key to look up
1355 * @return the value corresponding to the key 1301 * @return the value corresponding to the key
1356 * @see cxJsonIsObject() 1302 * @see cxJsonIsObject()
1357 */ 1303 */
1358 #define cxJsonObjGet(value, name) _Generic((name), \ 1304 #define cxJsonObjGet(value, name) cx_json_obj_get(value, cx_strcast(name))
1359 cxstring: cx_json_obj_get_cxstr, \ 1305
1360 cxmutstr: cx_json_obj_get_mutstr, \ 1306 /**
1361 char*: cx_json_obj_get_str, \ 1307 * Internal function, do not use.
1362 const char*: cx_json_obj_get_str) \ 1308 * @param value the JSON object
1363 (value, name) 1309 * @param name the key to look up
1364 1310 * @return the value corresponding to the key or @c NULL when the key is not part of the object
1365 /** 1311 */
1366 * @copydoc cxJsonObjGet() 1312 cx_attr_nonnull
1367 */ 1313 cx_attr_export
1368 cx_attr_nonnull 1314 CxJsonValue *cx_json_obj_remove(CxJsonValue *value, cxstring name);
1369 cx_attr_returns_nonnull 1315
1370 static inline CxJsonValue *cx_json_obj_get_mutstr(const CxJsonValue *value, cxmutstr name) { 1316 /**
1371 return cx_json_obj_get_cxstr(value, cx_strcast(name)); 1317 * Removes and returns a value corresponding to a key in a JSON object.
1372 } 1318 *
1373 1319 * If the @p value is not a JSON object, the behavior is undefined.
1374 /** 1320 *
1375 * @copydoc cxJsonObjGet() 1321 * This function, in contrast to cxJsonObjGet() returns @c NULL when the
1376 */ 1322 * object does not contain @p name.
1377 cx_attr_nonnull 1323 *
1378 cx_attr_returns_nonnull 1324 * @param value the JSON object
1379 cx_attr_cstr_arg(2) 1325 * @param name the key to look up
1380 static inline CxJsonValue *cx_json_obj_get_str(const CxJsonValue *value, const char *name) { 1326 * @return the value corresponding to the key or @c NULL when the key is not part of the object
1381 return cx_json_obj_get_cxstr(value, cx_str(name)); 1327 * @see cxJsonIsObject()
1328 */
1329 #define cxJsonObjRemove(value, name) cx_json_obj_remove(value, cx_strcast(name))
1330
1331 #ifdef __cplusplus
1382 } 1332 }
1383 #endif 1333 #endif
1384 1334
1385 #ifdef __cplusplus
1386 }
1387 #endif
1388
1389 #endif /* UCX_JSON_H */ 1335 #endif /* UCX_JSON_H */
1390 1336

mercurial