summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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" {
48#endif 48#endif
49 49
50#include <sys/types.h> 50#include <sys/types.h>
51#include <stdarg.h>
51 52
52/** 53/**
53 * \mainpage libplist : A library to handle Apple Property Lists 54 * \mainpage libplist : A library to handle Apple Property Lists
@@ -544,22 +545,25 @@ extern "C" {
544 ********************************************/ 545 ********************************************/
545 546
546/** 547/**
547 * Find the first encountered #PLIST_KEY node mathing that key. 548 * Get a node from its path. Each path element depends on the associated father node type.
549 * For Dictionaries, var args are casted to const char*, for arrays, var args are caster to uint32_t
548 * Search is breath first order. 550 * Search is breath first order.
549 * 551 *
550 * @param plist the root node of the plist structure. 552 * @param plist the node to access result from.
551 * @param value the ASCII Key to match. 553 * @param length length of the path to access
554 * @return the value to access.
552 */ 555 */
553 PLIST_API plist_t plist_find_node_by_key(plist_t plist, const char *value); 556 PLIST_API plist_t plist_access_path(plist_t plist, uint32_t length, ...);
554 557
555/** 558/**
556 * Find the first encountered #PLIST_STRING node mathing that string. 559 * Variadic version of #plist_access_path.
557 * Search is breath first order.
558 * 560 *
559 * @param plist the root node of the plist structure. 561 * @param plist the node to access result from.
560 * @param value the ASCII String to match. 562 * @param length length of the path to access
563 * @param v list of array's index and dic'st key
564 * @return the value to access.
561 */ 565 */
562 PLIST_API plist_t plist_find_node_by_string(plist_t plist, const char *value); 566 PLIST_API plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v);
563 567
564/** 568/**
565 * Compare two node values 569 * Compare two node values
@@ -706,6 +710,31 @@ extern "C" {
706 */ 710 */
707 PLIST_API void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec); 711 PLIST_API void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec);
708 712
713
714/********************************************
715 * *
716 * Utils *
717 * *
718 ********************************************/
719
720/**
721 * Find the first encountered #PLIST_KEY node mathing that key.
722 * Search is breath first order.
723 *
724 * @param plist the root node of the plist structure.
725 * @param value the ASCII Key to match.
726 */
727 PLIST_API plist_t plist_find_node_by_key(plist_t plist, const char *value);
728
729/**
730 * Find the first encountered #PLIST_STRING node mathing that string.
731 * Search is breath first order.
732 *
733 * @param plist the root node of the plist structure.
734 * @param value the ASCII String to match.
735 */
736 PLIST_API plist_t plist_find_node_by_string(plist_t plist, const char *value);
737
709/*@}*/ 738/*@}*/
710 739
711 740
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
408 return res; 408 return res;
409} 409}
410 410
411static plist_t plist_find_node(plist_t plist, plist_type type, const void *value, uint64_t length) 411plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v)
412{ 412{
413 plist_t current = NULL; 413 plist_t current = plist;
414 414 plist_type type = PLIST_NONE;
415 if (!plist) 415 uint32_t i = 0;
416 return NULL; 416
417 417 for (i = 0; i < length && current; i++) {
418 for (current = (plist_t)g_node_first_child(plist); current; current = (plist_t)g_node_next_sibling(current)) { 418 type = plist_get_node_type(current);
419 419
420 plist_data_t data = plist_get_data(current); 420 if (type == PLIST_ARRAY) {
421 421 uint32_t index = va_arg(v, uint32_t);
422 if (data->type == type && data->length == length && compare_node_value(type, data, value, length)) { 422 current = plist_array_get_item(current, index);
423 return current;
424 } 423 }
425 if (data->type == PLIST_DICT || data->type == PLIST_ARRAY) { 424 else if (type == PLIST_DICT) {
426 plist_t sub = plist_find_node(current, type, value, length); 425 const char* key = va_arg(v, const char*);
427 if (sub) 426 current = plist_dict_get_item(current, key);
428 return sub;
429 } 427 }
430 } 428 }
431 return NULL; 429 return current;
432} 430}
433 431
434plist_t plist_find_node_by_key(plist_t plist, const char *value) 432plist_t plist_access_path(plist_t plist, uint32_t length, ...)
435{ 433{
436 return plist_find_node(plist, PLIST_KEY, value, strlen(value)); 434 plist_t ret = NULL;
437} 435 va_list v;
438 436
439plist_t plist_find_node_by_string(plist_t plist, const char *value) 437 va_start(v, length);
440{ 438 ret = plist_access_pathv(plist, length, v);
441 return plist_find_node(plist, PLIST_STRING, value, strlen(value)); 439 va_end(v);
440 return ret;
442} 441}
443 442
444static void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint64_t * length) 443static 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 plist_add_sub_element(node, PLIST_DATE, &val, sizeof(GTimeVal)); 885 plist_add_sub_element(node, PLIST_DATE, &val, sizeof(GTimeVal));
887} 886}
888 887
888static plist_t plist_find_node(plist_t plist, plist_type type, const void *value, uint64_t length)
889{
890 plist_t current = NULL;
891
892 if (!plist)
893 return NULL;
894
895 for (current = (plist_t)g_node_first_child(plist); current; current = (plist_t)g_node_next_sibling(current)) {
896
897 plist_data_t data = plist_get_data(current);
898
899 if (data->type == type && data->length == length && compare_node_value(type, data, value, length)) {
900 return current;
901 }
902 if (data->type == PLIST_DICT || data->type == PLIST_ARRAY) {
903 plist_t sub = plist_find_node(current, type, value, length);
904 if (sub)
905 return sub;
906 }
907 }
908 return NULL;
909}
910
911plist_t plist_find_node_by_key(plist_t plist, const char *value)
912{
913 return plist_find_node(plist, PLIST_KEY, value, strlen(value));
914}
915
916plist_t plist_find_node_by_string(plist_t plist, const char *value)
917{
918 return plist_find_node(plist, PLIST_STRING, value, strlen(value));
919}
889 920