Fossil SCM
pulled in latest cson for cson_object_merge().
Commit
d3ad893c5b8134ee503611dbdd7e35a9d845d22d
Parent
3db8bfc5bfa8cf9…
2 files changed
+61
-1
+67
-1
+61
-1
| --- src/cson_amalgamation.c | ||
| +++ src/cson_amalgamation.c | ||
| @@ -2409,11 +2409,11 @@ | ||
| 2409 | 2409 | kvp->value = NULL; |
| 2410 | 2410 | } |
| 2411 | 2411 | } |
| 2412 | 2412 | } |
| 2413 | 2413 | |
| 2414 | -cson_string const * cson_kvp_key( cson_kvp const * kvp ) | |
| 2414 | +cson_string * cson_kvp_key( cson_kvp const * kvp ) | |
| 2415 | 2415 | { |
| 2416 | 2416 | return kvp ? cson_value_get_string(kvp->key) : NULL; |
| 2417 | 2417 | } |
| 2418 | 2418 | cson_value * cson_kvp_value( cson_kvp const * kvp ) |
| 2419 | 2419 | { |
| @@ -3057,10 +3057,17 @@ | ||
| 3057 | 3057 | cson_value * cson_object_get( cson_object const * obj, char const * key ) |
| 3058 | 3058 | { |
| 3059 | 3059 | cson_kvp * kvp = cson_object_search_impl( obj, key, NULL ); |
| 3060 | 3060 | return kvp ? kvp->value : NULL; |
| 3061 | 3061 | } |
| 3062 | + | |
| 3063 | +cson_value * cson_object_get_s( cson_object const * obj, cson_string const *key ) | |
| 3064 | +{ | |
| 3065 | + cson_kvp * kvp = cson_object_search_impl( obj, cson_string_cstr(key), NULL ); | |
| 3066 | + return kvp ? kvp->value : NULL; | |
| 3067 | +} | |
| 3068 | + | |
| 3062 | 3069 | |
| 3063 | 3070 | #if CSON_OBJECT_PROPS_SORT |
| 3064 | 3071 | static void cson_object_sort_props( cson_object * obj ) |
| 3065 | 3072 | { |
| 3066 | 3073 | assert( NULL != obj ); |
| @@ -4482,10 +4489,17 @@ | ||
| 4482 | 4489 | *inp = pos; |
| 4483 | 4490 | for( ; *pos && (*pos != separator); ++pos) { /* find next splitter */ } |
| 4484 | 4491 | *end = pos; |
| 4485 | 4492 | return (pos > *inp) ? 1 : 0; |
| 4486 | 4493 | } |
| 4494 | + | |
| 4495 | +int cson_object_fetch_sub2( cson_object const * obj, cson_value ** tgt, char const * path ) | |
| 4496 | +{ | |
| 4497 | + if( ! obj || !path ) return cson_rc.ArgError; | |
| 4498 | + else if( !*path || !*(1+path) ) return cson_rc.RangeError; | |
| 4499 | + else return cson_object_fetch_sub(obj, tgt, path+1, *path); | |
| 4500 | +} | |
| 4487 | 4501 | |
| 4488 | 4502 | int cson_object_fetch_sub( cson_object const * obj, cson_value ** tgt, char const * path, char sep ) |
| 4489 | 4503 | { |
| 4490 | 4504 | if( ! obj || !path ) return cson_rc.ArgError; |
| 4491 | 4505 | else if( !*path || !sep ) return cson_rc.RangeError; |
| @@ -4554,10 +4568,17 @@ | ||
| 4554 | 4568 | { |
| 4555 | 4569 | cson_value * v = NULL; |
| 4556 | 4570 | cson_object_fetch_sub( obj, &v, path, sep ); |
| 4557 | 4571 | return v; |
| 4558 | 4572 | } |
| 4573 | + | |
| 4574 | +cson_value * cson_object_get_sub2( cson_object const * obj, char const * path ) | |
| 4575 | +{ | |
| 4576 | + cson_value * v = NULL; | |
| 4577 | + cson_object_fetch_sub2( obj, &v, path ); | |
| 4578 | + return v; | |
| 4579 | +} | |
| 4559 | 4580 | |
| 4560 | 4581 | static cson_value * cson_value_clone_array( cson_value const * orig ) |
| 4561 | 4582 | { |
| 4562 | 4583 | unsigned int i = 0; |
| 4563 | 4584 | cson_array const * asrc = cson_value_get_array( orig ); |
| @@ -4889,10 +4910,49 @@ | ||
| 4889 | 4910 | |
| 4890 | 4911 | } |
| 4891 | 4912 | return rc; |
| 4892 | 4913 | } |
| 4893 | 4914 | } |
| 4915 | + | |
| 4916 | +int cson_object_merge( cson_object * dest, cson_object const * src, int flags ){ | |
| 4917 | + cson_object_iterator iter = cson_object_iterator_empty; | |
| 4918 | + int rc; | |
| 4919 | + char const replace = (flags & CSON_MERGE_REPLACE); | |
| 4920 | + char const recurse = !(flags & CSON_MERGE_NO_RECURSE); | |
| 4921 | + cson_kvp const * kvp; | |
| 4922 | + if((!dest || !src) || (dest==src)) return cson_rc.ArgError; | |
| 4923 | + rc = cson_object_iter_init( src, &iter ); | |
| 4924 | + if(rc) return rc; | |
| 4925 | + while( (kvp = cson_object_iter_next(&iter) ) ) | |
| 4926 | + { | |
| 4927 | + cson_string * key = cson_kvp_key(kvp); | |
| 4928 | + cson_value * val = cson_kvp_value(kvp); | |
| 4929 | + cson_value * check = cson_object_get_s( dest, key ); | |
| 4930 | + if(!check){ | |
| 4931 | + cson_object_set_s( dest, key, val ); | |
| 4932 | + continue; | |
| 4933 | + } | |
| 4934 | + else if(!replace && !recurse) continue; | |
| 4935 | + else if(replace && !recurse){ | |
| 4936 | + cson_object_set_s( dest, key, val ); | |
| 4937 | + continue; | |
| 4938 | + } | |
| 4939 | + else if( recurse ){ | |
| 4940 | + if( cson_value_is_object(check) && | |
| 4941 | + cson_value_is_object(val) ){ | |
| 4942 | + rc = cson_object_merge( cson_value_get_object(check), | |
| 4943 | + cson_value_get_object(val), | |
| 4944 | + flags ); | |
| 4945 | + if(rc) return rc; | |
| 4946 | + else continue; | |
| 4947 | + } | |
| 4948 | + else continue; | |
| 4949 | + } | |
| 4950 | + else continue; | |
| 4951 | + } | |
| 4952 | + return 0; | |
| 4953 | +} | |
| 4894 | 4954 | |
| 4895 | 4955 | #if defined(__cplusplus) |
| 4896 | 4956 | } /*extern "C"*/ |
| 4897 | 4957 | #endif |
| 4898 | 4958 | |
| 4899 | 4959 |
| --- src/cson_amalgamation.c | |
| +++ src/cson_amalgamation.c | |
| @@ -2409,11 +2409,11 @@ | |
| 2409 | kvp->value = NULL; |
| 2410 | } |
| 2411 | } |
| 2412 | } |
| 2413 | |
| 2414 | cson_string const * cson_kvp_key( cson_kvp const * kvp ) |
| 2415 | { |
| 2416 | return kvp ? cson_value_get_string(kvp->key) : NULL; |
| 2417 | } |
| 2418 | cson_value * cson_kvp_value( cson_kvp const * kvp ) |
| 2419 | { |
| @@ -3057,10 +3057,17 @@ | |
| 3057 | cson_value * cson_object_get( cson_object const * obj, char const * key ) |
| 3058 | { |
| 3059 | cson_kvp * kvp = cson_object_search_impl( obj, key, NULL ); |
| 3060 | return kvp ? kvp->value : NULL; |
| 3061 | } |
| 3062 | |
| 3063 | #if CSON_OBJECT_PROPS_SORT |
| 3064 | static void cson_object_sort_props( cson_object * obj ) |
| 3065 | { |
| 3066 | assert( NULL != obj ); |
| @@ -4482,10 +4489,17 @@ | |
| 4482 | *inp = pos; |
| 4483 | for( ; *pos && (*pos != separator); ++pos) { /* find next splitter */ } |
| 4484 | *end = pos; |
| 4485 | return (pos > *inp) ? 1 : 0; |
| 4486 | } |
| 4487 | |
| 4488 | int cson_object_fetch_sub( cson_object const * obj, cson_value ** tgt, char const * path, char sep ) |
| 4489 | { |
| 4490 | if( ! obj || !path ) return cson_rc.ArgError; |
| 4491 | else if( !*path || !sep ) return cson_rc.RangeError; |
| @@ -4554,10 +4568,17 @@ | |
| 4554 | { |
| 4555 | cson_value * v = NULL; |
| 4556 | cson_object_fetch_sub( obj, &v, path, sep ); |
| 4557 | return v; |
| 4558 | } |
| 4559 | |
| 4560 | static cson_value * cson_value_clone_array( cson_value const * orig ) |
| 4561 | { |
| 4562 | unsigned int i = 0; |
| 4563 | cson_array const * asrc = cson_value_get_array( orig ); |
| @@ -4889,10 +4910,49 @@ | |
| 4889 | |
| 4890 | } |
| 4891 | return rc; |
| 4892 | } |
| 4893 | } |
| 4894 | |
| 4895 | #if defined(__cplusplus) |
| 4896 | } /*extern "C"*/ |
| 4897 | #endif |
| 4898 | |
| 4899 |
| --- src/cson_amalgamation.c | |
| +++ src/cson_amalgamation.c | |
| @@ -2409,11 +2409,11 @@ | |
| 2409 | kvp->value = NULL; |
| 2410 | } |
| 2411 | } |
| 2412 | } |
| 2413 | |
| 2414 | cson_string * cson_kvp_key( cson_kvp const * kvp ) |
| 2415 | { |
| 2416 | return kvp ? cson_value_get_string(kvp->key) : NULL; |
| 2417 | } |
| 2418 | cson_value * cson_kvp_value( cson_kvp const * kvp ) |
| 2419 | { |
| @@ -3057,10 +3057,17 @@ | |
| 3057 | cson_value * cson_object_get( cson_object const * obj, char const * key ) |
| 3058 | { |
| 3059 | cson_kvp * kvp = cson_object_search_impl( obj, key, NULL ); |
| 3060 | return kvp ? kvp->value : NULL; |
| 3061 | } |
| 3062 | |
| 3063 | cson_value * cson_object_get_s( cson_object const * obj, cson_string const *key ) |
| 3064 | { |
| 3065 | cson_kvp * kvp = cson_object_search_impl( obj, cson_string_cstr(key), NULL ); |
| 3066 | return kvp ? kvp->value : NULL; |
| 3067 | } |
| 3068 | |
| 3069 | |
| 3070 | #if CSON_OBJECT_PROPS_SORT |
| 3071 | static void cson_object_sort_props( cson_object * obj ) |
| 3072 | { |
| 3073 | assert( NULL != obj ); |
| @@ -4482,10 +4489,17 @@ | |
| 4489 | *inp = pos; |
| 4490 | for( ; *pos && (*pos != separator); ++pos) { /* find next splitter */ } |
| 4491 | *end = pos; |
| 4492 | return (pos > *inp) ? 1 : 0; |
| 4493 | } |
| 4494 | |
| 4495 | int cson_object_fetch_sub2( cson_object const * obj, cson_value ** tgt, char const * path ) |
| 4496 | { |
| 4497 | if( ! obj || !path ) return cson_rc.ArgError; |
| 4498 | else if( !*path || !*(1+path) ) return cson_rc.RangeError; |
| 4499 | else return cson_object_fetch_sub(obj, tgt, path+1, *path); |
| 4500 | } |
| 4501 | |
| 4502 | int cson_object_fetch_sub( cson_object const * obj, cson_value ** tgt, char const * path, char sep ) |
| 4503 | { |
| 4504 | if( ! obj || !path ) return cson_rc.ArgError; |
| 4505 | else if( !*path || !sep ) return cson_rc.RangeError; |
| @@ -4554,10 +4568,17 @@ | |
| 4568 | { |
| 4569 | cson_value * v = NULL; |
| 4570 | cson_object_fetch_sub( obj, &v, path, sep ); |
| 4571 | return v; |
| 4572 | } |
| 4573 | |
| 4574 | cson_value * cson_object_get_sub2( cson_object const * obj, char const * path ) |
| 4575 | { |
| 4576 | cson_value * v = NULL; |
| 4577 | cson_object_fetch_sub2( obj, &v, path ); |
| 4578 | return v; |
| 4579 | } |
| 4580 | |
| 4581 | static cson_value * cson_value_clone_array( cson_value const * orig ) |
| 4582 | { |
| 4583 | unsigned int i = 0; |
| 4584 | cson_array const * asrc = cson_value_get_array( orig ); |
| @@ -4889,10 +4910,49 @@ | |
| 4910 | |
| 4911 | } |
| 4912 | return rc; |
| 4913 | } |
| 4914 | } |
| 4915 | |
| 4916 | int cson_object_merge( cson_object * dest, cson_object const * src, int flags ){ |
| 4917 | cson_object_iterator iter = cson_object_iterator_empty; |
| 4918 | int rc; |
| 4919 | char const replace = (flags & CSON_MERGE_REPLACE); |
| 4920 | char const recurse = !(flags & CSON_MERGE_NO_RECURSE); |
| 4921 | cson_kvp const * kvp; |
| 4922 | if((!dest || !src) || (dest==src)) return cson_rc.ArgError; |
| 4923 | rc = cson_object_iter_init( src, &iter ); |
| 4924 | if(rc) return rc; |
| 4925 | while( (kvp = cson_object_iter_next(&iter) ) ) |
| 4926 | { |
| 4927 | cson_string * key = cson_kvp_key(kvp); |
| 4928 | cson_value * val = cson_kvp_value(kvp); |
| 4929 | cson_value * check = cson_object_get_s( dest, key ); |
| 4930 | if(!check){ |
| 4931 | cson_object_set_s( dest, key, val ); |
| 4932 | continue; |
| 4933 | } |
| 4934 | else if(!replace && !recurse) continue; |
| 4935 | else if(replace && !recurse){ |
| 4936 | cson_object_set_s( dest, key, val ); |
| 4937 | continue; |
| 4938 | } |
| 4939 | else if( recurse ){ |
| 4940 | if( cson_value_is_object(check) && |
| 4941 | cson_value_is_object(val) ){ |
| 4942 | rc = cson_object_merge( cson_value_get_object(check), |
| 4943 | cson_value_get_object(val), |
| 4944 | flags ); |
| 4945 | if(rc) return rc; |
| 4946 | else continue; |
| 4947 | } |
| 4948 | else continue; |
| 4949 | } |
| 4950 | else continue; |
| 4951 | } |
| 4952 | return 0; |
| 4953 | } |
| 4954 | |
| 4955 | #if defined(__cplusplus) |
| 4956 | } /*extern "C"*/ |
| 4957 | #endif |
| 4958 | |
| 4959 |
+67
-1
| --- src/cson_amalgamation.h | ||
| +++ src/cson_amalgamation.h | ||
| @@ -1400,10 +1400,16 @@ | ||
| 1400 | 1400 | @see cson_object_fetch_sub() |
| 1401 | 1401 | @see cson_object_get_sub() |
| 1402 | 1402 | */ |
| 1403 | 1403 | cson_value * cson_object_get( cson_object const * obj, char const * key ); |
| 1404 | 1404 | |
| 1405 | +/** | |
| 1406 | + Equivalent to cson_object_get() but takes a cson_string argument | |
| 1407 | + instead of a C-style string. | |
| 1408 | +*/ | |
| 1409 | +cson_value * cson_object_get_s( cson_object const * obj, cson_string const *key ); | |
| 1410 | + | |
| 1405 | 1411 | /** |
| 1406 | 1412 | Similar to cson_object_get(), but removes the value from the parent |
| 1407 | 1413 | object's ownership. If no item is found then NULL is returned, else |
| 1408 | 1414 | the object (now owned by the caller or possibly shared with other |
| 1409 | 1415 | containers) is returned. |
| @@ -1485,19 +1491,79 @@ | ||
| 1485 | 1491 | Multiple successive separators in the list are collapsed into a |
| 1486 | 1492 | single separator for parsing purposes. e.g. the path "a...b...c" |
| 1487 | 1493 | (separator='.') is equivalent to "a.b.c". |
| 1488 | 1494 | |
| 1489 | 1495 | @see cson_object_get_sub() |
| 1496 | + @see cson_object_get_sub2() | |
| 1490 | 1497 | */ |
| 1491 | 1498 | int cson_object_fetch_sub( cson_object const * obj, cson_value ** tgt, char const * path, char separator ); |
| 1492 | 1499 | |
| 1500 | +/** | |
| 1501 | + Similar to cson_object_fetch_sub(), but derives the path separator | |
| 1502 | + character from the first byte of the path argument. e.g. the | |
| 1503 | + following arg equivalent: | |
| 1504 | + | |
| 1505 | + @code | |
| 1506 | + cson_object_fetch_sub( obj, &tgt, "foo.bar.baz", '.' ); | |
| 1507 | + cson_object_fetch_sub2( obj, &tgt, ".foo.bar.baz" ); | |
| 1508 | + @endcode | |
| 1509 | +*/ | |
| 1510 | +int cson_object_fetch_sub2( cson_object const * obj, cson_value ** tgt, char const * path ); | |
| 1511 | + | |
| 1493 | 1512 | /** |
| 1494 | 1513 | Convenience form of cson_object_fetch_sub() which returns NULL if the given |
| 1495 | 1514 | item is not found. |
| 1496 | 1515 | */ |
| 1497 | 1516 | cson_value * cson_object_get_sub( cson_object const * obj, char const * path, char sep ); |
| 1498 | 1517 | |
| 1518 | +/** | |
| 1519 | + Convenience form of cson_object_fetch_sub2() which returns NULL if the given | |
| 1520 | + item is not found. | |
| 1521 | +*/ | |
| 1522 | +cson_value * cson_object_get_sub2( cson_object const * obj, char const * path ); | |
| 1523 | + | |
| 1524 | +/** @enum CSON_MERGE_FLAGS | |
| 1525 | + | |
| 1526 | + Flags for cson_object_merge(). | |
| 1527 | +*/ | |
| 1528 | +enum CSON_MERGE_FLAGS { | |
| 1529 | + CSON_MERGE_DEFAULT = 0, | |
| 1530 | + CSON_MERGE_REPLACE = 0x01, | |
| 1531 | + CSON_MERGE_NO_RECURSE = 0x02 | |
| 1532 | +}; | |
| 1533 | + | |
| 1534 | +/** | |
| 1535 | + "Merges" the src object's properties into dest. Each property in | |
| 1536 | + src is copied (using reference counting, not cloning) into dest. If | |
| 1537 | + dest already has the given property then behaviour depends on the | |
| 1538 | + flags argument: | |
| 1539 | + | |
| 1540 | + If flag has the CSON_MERGE_REPLACE bit set then this function will | |
| 1541 | + by default replace non-object properties with the src property. If | |
| 1542 | + src and dest both have the property AND it is an Object then this | |
| 1543 | + function operates recursively on those objects. If | |
| 1544 | + CSON_MERGE_NO_RECURSE is set then objects are not recursed in this | |
| 1545 | + manner, and will be completely replaced if CSON_MERGE_REPLACE is | |
| 1546 | + set. | |
| 1547 | + | |
| 1548 | + Array properties in dest are NOT recursed for merging - they are | |
| 1549 | + either replaced or left as-is, depending on whether flags contains | |
| 1550 | + he CSON_MERGE_REPLACE bit. | |
| 1551 | + | |
| 1552 | + Returns 0 on success. The error conditions are: | |
| 1553 | + | |
| 1554 | + - dest or src are NULL or (dest==src) returns cson_rc.ArgError. | |
| 1555 | + | |
| 1556 | + - dest or src contain cyclic references - this will likely cause a | |
| 1557 | + crash due to endless recursion. | |
| 1558 | + | |
| 1559 | + Potential TODOs: | |
| 1560 | + | |
| 1561 | + - Add a flag to copy clones, not the original values. | |
| 1562 | +*/ | |
| 1563 | +int cson_object_merge( cson_object * dest, cson_object const * src, int flags ); | |
| 1564 | + | |
| 1499 | 1565 | |
| 1500 | 1566 | /** |
| 1501 | 1567 | An iterator type for traversing object properties. |
| 1502 | 1568 | |
| 1503 | 1569 | Its values must be considered private, not to be touched by client |
| @@ -1590,11 +1656,11 @@ | ||
| 1590 | 1656 | Returns the key associated with the given key/value pair, |
| 1591 | 1657 | or NULL if !kvp. The memory is owned by the object which contains |
| 1592 | 1658 | the key/value pair, and may be invalidated by any modifications |
| 1593 | 1659 | to that object. |
| 1594 | 1660 | */ |
| 1595 | -cson_string const * cson_kvp_key( cson_kvp const * kvp ); | |
| 1661 | +cson_string * cson_kvp_key( cson_kvp const * kvp ); | |
| 1596 | 1662 | |
| 1597 | 1663 | /** |
| 1598 | 1664 | Returns the value associated with the given key/value pair, |
| 1599 | 1665 | or NULL if !kvp. The memory is owned by the object which contains |
| 1600 | 1666 | the key/value pair, and may be invalidated by any modifications |
| 1601 | 1667 |
| --- src/cson_amalgamation.h | |
| +++ src/cson_amalgamation.h | |
| @@ -1400,10 +1400,16 @@ | |
| 1400 | @see cson_object_fetch_sub() |
| 1401 | @see cson_object_get_sub() |
| 1402 | */ |
| 1403 | cson_value * cson_object_get( cson_object const * obj, char const * key ); |
| 1404 | |
| 1405 | /** |
| 1406 | Similar to cson_object_get(), but removes the value from the parent |
| 1407 | object's ownership. If no item is found then NULL is returned, else |
| 1408 | the object (now owned by the caller or possibly shared with other |
| 1409 | containers) is returned. |
| @@ -1485,19 +1491,79 @@ | |
| 1485 | Multiple successive separators in the list are collapsed into a |
| 1486 | single separator for parsing purposes. e.g. the path "a...b...c" |
| 1487 | (separator='.') is equivalent to "a.b.c". |
| 1488 | |
| 1489 | @see cson_object_get_sub() |
| 1490 | */ |
| 1491 | int cson_object_fetch_sub( cson_object const * obj, cson_value ** tgt, char const * path, char separator ); |
| 1492 | |
| 1493 | /** |
| 1494 | Convenience form of cson_object_fetch_sub() which returns NULL if the given |
| 1495 | item is not found. |
| 1496 | */ |
| 1497 | cson_value * cson_object_get_sub( cson_object const * obj, char const * path, char sep ); |
| 1498 | |
| 1499 | |
| 1500 | /** |
| 1501 | An iterator type for traversing object properties. |
| 1502 | |
| 1503 | Its values must be considered private, not to be touched by client |
| @@ -1590,11 +1656,11 @@ | |
| 1590 | Returns the key associated with the given key/value pair, |
| 1591 | or NULL if !kvp. The memory is owned by the object which contains |
| 1592 | the key/value pair, and may be invalidated by any modifications |
| 1593 | to that object. |
| 1594 | */ |
| 1595 | cson_string const * cson_kvp_key( cson_kvp const * kvp ); |
| 1596 | |
| 1597 | /** |
| 1598 | Returns the value associated with the given key/value pair, |
| 1599 | or NULL if !kvp. The memory is owned by the object which contains |
| 1600 | the key/value pair, and may be invalidated by any modifications |
| 1601 |
| --- src/cson_amalgamation.h | |
| +++ src/cson_amalgamation.h | |
| @@ -1400,10 +1400,16 @@ | |
| 1400 | @see cson_object_fetch_sub() |
| 1401 | @see cson_object_get_sub() |
| 1402 | */ |
| 1403 | cson_value * cson_object_get( cson_object const * obj, char const * key ); |
| 1404 | |
| 1405 | /** |
| 1406 | Equivalent to cson_object_get() but takes a cson_string argument |
| 1407 | instead of a C-style string. |
| 1408 | */ |
| 1409 | cson_value * cson_object_get_s( cson_object const * obj, cson_string const *key ); |
| 1410 | |
| 1411 | /** |
| 1412 | Similar to cson_object_get(), but removes the value from the parent |
| 1413 | object's ownership. If no item is found then NULL is returned, else |
| 1414 | the object (now owned by the caller or possibly shared with other |
| 1415 | containers) is returned. |
| @@ -1485,19 +1491,79 @@ | |
| 1491 | Multiple successive separators in the list are collapsed into a |
| 1492 | single separator for parsing purposes. e.g. the path "a...b...c" |
| 1493 | (separator='.') is equivalent to "a.b.c". |
| 1494 | |
| 1495 | @see cson_object_get_sub() |
| 1496 | @see cson_object_get_sub2() |
| 1497 | */ |
| 1498 | int cson_object_fetch_sub( cson_object const * obj, cson_value ** tgt, char const * path, char separator ); |
| 1499 | |
| 1500 | /** |
| 1501 | Similar to cson_object_fetch_sub(), but derives the path separator |
| 1502 | character from the first byte of the path argument. e.g. the |
| 1503 | following arg equivalent: |
| 1504 | |
| 1505 | @code |
| 1506 | cson_object_fetch_sub( obj, &tgt, "foo.bar.baz", '.' ); |
| 1507 | cson_object_fetch_sub2( obj, &tgt, ".foo.bar.baz" ); |
| 1508 | @endcode |
| 1509 | */ |
| 1510 | int cson_object_fetch_sub2( cson_object const * obj, cson_value ** tgt, char const * path ); |
| 1511 | |
| 1512 | /** |
| 1513 | Convenience form of cson_object_fetch_sub() which returns NULL if the given |
| 1514 | item is not found. |
| 1515 | */ |
| 1516 | cson_value * cson_object_get_sub( cson_object const * obj, char const * path, char sep ); |
| 1517 | |
| 1518 | /** |
| 1519 | Convenience form of cson_object_fetch_sub2() which returns NULL if the given |
| 1520 | item is not found. |
| 1521 | */ |
| 1522 | cson_value * cson_object_get_sub2( cson_object const * obj, char const * path ); |
| 1523 | |
| 1524 | /** @enum CSON_MERGE_FLAGS |
| 1525 | |
| 1526 | Flags for cson_object_merge(). |
| 1527 | */ |
| 1528 | enum CSON_MERGE_FLAGS { |
| 1529 | CSON_MERGE_DEFAULT = 0, |
| 1530 | CSON_MERGE_REPLACE = 0x01, |
| 1531 | CSON_MERGE_NO_RECURSE = 0x02 |
| 1532 | }; |
| 1533 | |
| 1534 | /** |
| 1535 | "Merges" the src object's properties into dest. Each property in |
| 1536 | src is copied (using reference counting, not cloning) into dest. If |
| 1537 | dest already has the given property then behaviour depends on the |
| 1538 | flags argument: |
| 1539 | |
| 1540 | If flag has the CSON_MERGE_REPLACE bit set then this function will |
| 1541 | by default replace non-object properties with the src property. If |
| 1542 | src and dest both have the property AND it is an Object then this |
| 1543 | function operates recursively on those objects. If |
| 1544 | CSON_MERGE_NO_RECURSE is set then objects are not recursed in this |
| 1545 | manner, and will be completely replaced if CSON_MERGE_REPLACE is |
| 1546 | set. |
| 1547 | |
| 1548 | Array properties in dest are NOT recursed for merging - they are |
| 1549 | either replaced or left as-is, depending on whether flags contains |
| 1550 | he CSON_MERGE_REPLACE bit. |
| 1551 | |
| 1552 | Returns 0 on success. The error conditions are: |
| 1553 | |
| 1554 | - dest or src are NULL or (dest==src) returns cson_rc.ArgError. |
| 1555 | |
| 1556 | - dest or src contain cyclic references - this will likely cause a |
| 1557 | crash due to endless recursion. |
| 1558 | |
| 1559 | Potential TODOs: |
| 1560 | |
| 1561 | - Add a flag to copy clones, not the original values. |
| 1562 | */ |
| 1563 | int cson_object_merge( cson_object * dest, cson_object const * src, int flags ); |
| 1564 | |
| 1565 | |
| 1566 | /** |
| 1567 | An iterator type for traversing object properties. |
| 1568 | |
| 1569 | Its values must be considered private, not to be touched by client |
| @@ -1590,11 +1656,11 @@ | |
| 1656 | Returns the key associated with the given key/value pair, |
| 1657 | or NULL if !kvp. The memory is owned by the object which contains |
| 1658 | the key/value pair, and may be invalidated by any modifications |
| 1659 | to that object. |
| 1660 | */ |
| 1661 | cson_string * cson_kvp_key( cson_kvp const * kvp ); |
| 1662 | |
| 1663 | /** |
| 1664 | Returns the value associated with the given key/value pair, |
| 1665 | or NULL if !kvp. The memory is owned by the object which contains |
| 1666 | the key/value pair, and may be invalidated by any modifications |
| 1667 |