Commit e492ef67 authored by Jonathan Beck's avatar Jonathan Beck

Add path accessor util function.

parent 3cff5a16
...@@ -48,6 +48,7 @@ extern "C" { ...@@ -48,6 +48,7 @@ extern "C" {
#endif #endif
#include <sys/types.h> #include <sys/types.h>
#include <stdarg.h>
/** /**
* \mainpage libplist : A library to handle Apple Property Lists * \mainpage libplist : A library to handle Apple Property Lists
...@@ -544,22 +545,25 @@ extern "C" { ...@@ -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. * Search is breath first order.
* *
* @param plist the root node of the plist structure. * @param plist the node to access result from.
* @param value the ASCII Key to match. * @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. * Variadic version of #plist_access_path.
* Search is breath first order.
* *
* @param plist the root node of the plist structure. * @param plist the node to access result from.
* @param value the ASCII String to match. * @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 * Compare two node values
...@@ -706,6 +710,31 @@ extern "C" { ...@@ -706,6 +710,31 @@ extern "C" {
*/ */
PLIST_API void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec); 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);
/*@}*/ /*@}*/
......
...@@ -408,37 +408,36 @@ static char compare_node_value(plist_type type, plist_data_t data, const void *v ...@@ -408,37 +408,36 @@ static char compare_node_value(plist_type type, plist_data_t data, const void *v
return res; return res;
} }
static plist_t plist_find_node(plist_t plist, plist_type type, const void *value, uint64_t length) plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v)
{ {
plist_t current = NULL; plist_t current = plist;
plist_type type = PLIST_NONE;
if (!plist) uint32_t i = 0;
return NULL;
for (current = (plist_t)g_node_first_child(plist); current; current = (plist_t)g_node_next_sibling(current)) { for (i = 0; i < length && current; i++) {
type = plist_get_node_type(current);
plist_data_t data = plist_get_data(current); if (type == PLIST_ARRAY) {
uint32_t index = va_arg(v, uint32_t);
if (data->type == type && data->length == length && compare_node_value(type, data, value, length)) { current = plist_array_get_item(current, index);
return current;
} }
if (data->type == PLIST_DICT || data->type == PLIST_ARRAY) { else if (type == PLIST_DICT) {
plist_t sub = plist_find_node(current, type, value, length); const char* key = va_arg(v, const char*);
if (sub) current = plist_dict_get_item(current, key);
return sub;
} }
} }
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 ret = NULL;
} va_list v;
plist_t plist_find_node_by_string(plist_t plist, const char *value) va_start(v, length);
{ ret = plist_access_pathv(plist, length, v);
return plist_find_node(plist, PLIST_STRING, value, strlen(value)); va_end(v);
return ret;
} }
static void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length) 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) ...@@ -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)); 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));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment