diff options
-rw-r--r-- | include/plist/plist.h | 47 | ||||
-rw-r--r-- | src/plist.c | 81 |
2 files changed, 94 insertions, 34 deletions
diff --git a/include/plist/plist.h b/include/plist/plist.h index e12d6fa..699a0d6 100644 --- a/include/plist/plist.h +++ b/include/plist/plist.h @@ -48,6 +48,7 @@ extern "C" { #endif #include <sys/types.h> +#include <stdarg.h> /** * \mainpage libplist : A library to handle Apple Property Lists @@ -544,22 +545,25 @@ extern "C" { ********************************************/ /** - * Find the first encountered #PLIST_KEY node mathing that key. + * Get a node from its path. Each path element depends on the associated father node type. + * For Dictionaries, var args are casted to const char*, for arrays, var args are caster to uint32_t * Search is breath first order. * - * @param plist the root node of the plist structure. - * @param value the ASCII Key to match. + * @param plist the node to access result from. + * @param length length of the path to access + * @return the value to access. */ - PLIST_API plist_t plist_find_node_by_key(plist_t plist, const char *value); + PLIST_API plist_t plist_access_path(plist_t plist, uint32_t length, ...); /** - * Find the first encountered #PLIST_STRING node mathing that string. - * Search is breath first order. + * Variadic version of #plist_access_path. * - * @param plist the root node of the plist structure. - * @param value the ASCII String to match. + * @param plist the node to access result from. + * @param length length of the path to access + * @param v list of array's index and dic'st key + * @return the value to access. */ - PLIST_API plist_t plist_find_node_by_string(plist_t plist, const char *value); + PLIST_API plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v); /** * Compare two node values @@ -706,6 +710,31 @@ extern "C" { */ PLIST_API void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec); + +/******************************************** + * * + * Utils * + * * + ********************************************/ + +/** + * Find the first encountered #PLIST_KEY node mathing that key. + * Search is breath first order. + * + * @param plist the root node of the plist structure. + * @param value the ASCII Key to match. + */ + PLIST_API plist_t plist_find_node_by_key(plist_t plist, const char *value); + +/** + * Find the first encountered #PLIST_STRING node mathing that string. + * Search is breath first order. + * + * @param plist the root node of the plist structure. + * @param value the ASCII String to match. + */ + PLIST_API plist_t plist_find_node_by_string(plist_t plist, const char *value); + /*@}*/ diff --git a/src/plist.c b/src/plist.c index 78ac07c..ed73d53 100644 --- a/src/plist.c +++ b/src/plist.c @@ -408,37 +408,36 @@ static char compare_node_value(plist_type type, plist_data_t data, const void *v return res; } -static plist_t plist_find_node(plist_t plist, plist_type type, const void *value, uint64_t length) -{ - plist_t current = NULL; - - if (!plist) - return NULL; - - for (current = (plist_t)g_node_first_child(plist); current; current = (plist_t)g_node_next_sibling(current)) { - - plist_data_t data = plist_get_data(current); - - if (data->type == type && data->length == length && compare_node_value(type, data, value, length)) { - return current; +plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v) +{ + plist_t current = plist; + plist_type type = PLIST_NONE; + uint32_t i = 0; + + for (i = 0; i < length && current; i++) { + type = plist_get_node_type(current); + + if (type == PLIST_ARRAY) { + uint32_t index = va_arg(v, uint32_t); + current = plist_array_get_item(current, index); } - if (data->type == PLIST_DICT || data->type == PLIST_ARRAY) { - plist_t sub = plist_find_node(current, type, value, length); - if (sub) - return sub; + else if (type == PLIST_DICT) { + const char* key = va_arg(v, const char*); + current = plist_dict_get_item(current, key); } } - return NULL; + return current; } -plist_t plist_find_node_by_key(plist_t plist, const char *value) +plist_t plist_access_path(plist_t plist, uint32_t length, ...) { - return plist_find_node(plist, PLIST_KEY, value, strlen(value)); -} - -plist_t plist_find_node_by_string(plist_t plist, const char *value) -{ - return plist_find_node(plist, PLIST_STRING, value, strlen(value)); + plist_t ret = NULL; + va_list v; + + va_start(v, length); + ret = plist_access_pathv(plist, length, v); + va_end(v); + return ret; } static void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length) @@ -886,4 +885,36 @@ void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec) plist_add_sub_element(node, PLIST_DATE, &val, sizeof(GTimeVal)); } +static plist_t plist_find_node(plist_t plist, plist_type type, const void *value, uint64_t length) +{ + plist_t current = NULL; + + if (!plist) + return NULL; + + for (current = (plist_t)g_node_first_child(plist); current; current = (plist_t)g_node_next_sibling(current)) { + + plist_data_t data = plist_get_data(current); + + if (data->type == type && data->length == length && compare_node_value(type, data, value, length)) { + return current; + } + if (data->type == PLIST_DICT || data->type == PLIST_ARRAY) { + plist_t sub = plist_find_node(current, type, value, length); + if (sub) + return sub; + } + } + return NULL; +} + +plist_t plist_find_node_by_key(plist_t plist, const char *value) +{ + return plist_find_node(plist, PLIST_KEY, value, strlen(value)); +} + +plist_t plist_find_node_by_string(plist_t plist, const char *value) +{ + return plist_find_node(plist, PLIST_STRING, value, strlen(value)); +} |