diff options
-rw-r--r-- | include/plist/plist.h | 10 | ||||
-rw-r--r-- | src/plist.c | 27 |
2 files changed, 37 insertions, 0 deletions
diff --git a/include/plist/plist.h b/include/plist/plist.h index 546e108..41588a8 100644 --- a/include/plist/plist.h +++ b/include/plist/plist.h @@ -336,6 +336,16 @@ extern "C" */ PLIST_API void plist_dict_remove_item(plist_t node, const char* key); + /** + * Merge a dictionary into another. This will add all key/value pairs + * from the source dictionary to the target dictionary, overwriting + * any existing key/value pairs that are already present in target. + * + * @param target pointer to an existing node of type #PLIST_DICT + * @param source node of type #PLIST_DICT that should be merged into target + */ + PLIST_API void plist_dict_merge(plist_t *target, plist_t source); + /******************************************** * * diff --git a/src/plist.c b/src/plist.c index dcaf601..e077ad9 100644 --- a/src/plist.c +++ b/src/plist.c @@ -446,6 +446,33 @@ void plist_dict_remove_item(plist_t node, const char* key) return; } +void plist_dict_merge(plist_t *target, plist_t source) +{ + if (!target || !*target || (plist_get_node_type(*target) != PLIST_DICT) || !source || (plist_get_node_type(source) != PLIST_DICT)) + return; + + char* key = NULL; + plist_dict_iter it = NULL; + plist_t subnode = NULL; + plist_dict_new_iter(source, &it); + if (!it) + return; + + do { + plist_dict_next_item(source, it, &key, &subnode); + if (!key) + break; + + if (plist_dict_get_item(*target, key) != NULL) + plist_dict_remove_item(*target, key); + + plist_dict_insert_item(*target, key, plist_copy(subnode)); + free(key); + key = NULL; + } while (1); + free(it); +} + plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v) { plist_t current = plist; |