summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Jonathan Beck2009-10-13 20:03:38 +0200
committerGravatar Jonathan Beck2009-10-13 20:03:38 +0200
commite492ef675c404cc6c0d1cfa26e47a1c16c850d5f (patch)
tree57cdc453f9d29e465ff83622c8b43d89e46dca00
parent3cff5a16030168cdc45102a770b54b973170cd7f (diff)
downloadlibplist-e492ef675c404cc6c0d1cfa26e47a1c16c850d5f.tar.gz
libplist-e492ef675c404cc6c0d1cfa26e47a1c16c850d5f.tar.bz2
Add path accessor util function.
-rw-r--r--include/plist/plist.h47
-rw-r--r--src/plist.c81
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));
+}