From 77b02c9404dbfef325b7a19228045a817cafe064 Mon Sep 17 00:00:00 2001 From: Jonathan Beck Date: Sat, 10 Oct 2009 18:20:01 +0200 Subject: Rework public API to make it more consistent. --- include/plist/plist.h | 345 ++++++++++++++++++++++++++++++----------- src/plist.c | 419 ++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 565 insertions(+), 199 deletions(-) diff --git a/include/plist/plist.h b/include/plist/plist.h index 6388603..f8c5c53 100644 --- a/include/plist/plist.h +++ b/include/plist/plist.h @@ -65,13 +65,11 @@ extern "C" { * The enumeration of plist node types. */ typedef enum { - PLIST_BOOLEAN, - /**< Boolean, scalar type */ + PLIST_BOOLEAN, /**< Boolean, scalar type */ PLIST_UINT, /**< Unsigned integer, scalar type */ PLIST_REAL, /**< Real, scalar type */ - PLIST_STRING, - /**< ASCII string, scalar type */ - PLIST_ARRAY,/**< Ordered array, structured type */ + PLIST_STRING, /**< ASCII string, scalar type */ + PLIST_ARRAY, /**< Ordered array, structured type */ PLIST_DICT, /**< Unordered dictionary (key/value pair), structured type */ PLIST_DATE, /**< Date, scalar type */ PLIST_DATA, /**< Binary data, scalar type */ @@ -102,6 +100,62 @@ extern "C" { */ PLIST_API plist_t plist_new_array(void); +/** + * Create a new plist_t type #PLIST_STRING + * + * @param val the sting value, encoded in UTF8. + * @return the created item + * @sa #plist_type + */ + PLIST_API plist_t plist_new_string(const char *val); + +/** + * Create a new plist_t type #PLIST_BOOLEAN + * + * @param val the boolean value, 0 is false, other values are true. + * @return the created item + * @sa #plist_type + */ + PLIST_API plist_t plist_new_bool(uint8_t val); + +/** + * Create a new plist_t type #PLIST_UINT + * + * @param val the unsigned integer value + * @return the created item + * @sa #plist_type + */ + PLIST_API plist_t plist_new_uint(uint64_t val); + +/** + * Create a new plist_t type #PLIST_REAL + * + * @param val the real value + * @return the created item + * @sa #plist_type + */ + PLIST_API plist_t plist_new_real(double val); + +/** + * Create a new plist_t type #PLIST_DATA + * + * @param val the binary buffer + * @param length the length of the buffer + * @return the created item + * @sa #plist_type + */ + PLIST_API plist_t plist_new_data(const char *val, uint64_t length); + +/** + * Create a new plist_t type #PLIST_DATE + * + * @param sec the number of seconds since 01/01/2001 + * @param usec the number of microseconds + * @return the created item + * @sa #plist_type + */ + PLIST_API plist_t plist_new_date(int32_t sec, int32_t usec); + /** * Destruct a plist_t node and all its children recursively * @@ -120,139 +174,113 @@ extern "C" { /******************************************** * * - * Tree navigation * + * Array functions * * * ********************************************/ /** - * Get the first child of a node + * Get size of a #PLIST_ARRAY node. * - * @param node the first child + * @param node the node of type #PLIST_ARRAY + * @return size of the #PLIST_ARRAY node */ - PLIST_API plist_t plist_get_first_child(plist_t node); - + PLIST_API uint32_t plist_array_get_size(plist_t node); /** - * Get the next sibling of a node + * Get the nth item in a #PLIST_ARRAY node. * - * @param node the next sibling + * @param node the node of type #PLIST_ARRAY + * @param n the index of the item to get. Range is [0, array_size[ + * @return the nth item or NULL if node is not of type #PLIST_ARRAY */ - PLIST_API plist_t plist_get_next_sibling(plist_t node); - + PLIST_API plist_t plist_array_get_item(plist_t node, uint32_t n); /** - * Get the previous sibling of a node + * Set the nth item in a #PLIST_ARRAY node. + * The previous item at index n will be freed using #plist_free * - * @param node the previous sibling + * @param node the node of type #PLIST_ARRAY + * @param item the new item at index n + * @param n the index of the item to get. Range is [0, array_size[. Assert if n is not in range. */ - PLIST_API plist_t plist_get_prev_sibling(plist_t node); + PLIST_API void plist_array_set_item(plist_t node, plist_t item, uint32_t n); /** - * Get the parent of a node + * Append a new item at the end of a #PLIST_ARRAY node. * - * @param node the parent (NULL if node is root) + * @param node the node of type #PLIST_ARRAY + * @param item the new item */ - PLIST_API plist_t plist_get_parent(plist_t node); + PLIST_API void plist_array_append_item(plist_t node, plist_t item); /** - * Get the nth child of a #PLIST_ARRAY node. + * Insert a new item at position n in a #PLIST_ARRAY node. * * @param node the node of type #PLIST_ARRAY - * @param n the index of the child to get. Range is [0, array_size[ - * @return the nth children or NULL if node is not of type #PLIST_ARRAY + * @param item the new item to insert + * @param n The position at which the node will be stored. Range is [0, array_size[. Assert if n is not in range. */ - PLIST_API plist_t plist_get_array_nth_el(plist_t node, uint32_t n); + PLIST_API void plist_array_insert_item(plist_t node, plist_t item, uint32_t n); /** - * Get the child of a #PLIST_DICT node from the associated key value. + * Remove an existing position in a #PLIST_ARRAY node. + * Removed position will be freed using #plist_free * - * @param node the node of type #PLIST_DICT - * @param key the key associated to the requested value - * @return the key associated value or NULL if node is not of type #PLIST_DICT + * @param node the node of type #PLIST_ARRAY + * @param n The position to remove. Range is [0, array_size[. Assert if n is not in range. */ - PLIST_API plist_t plist_get_dict_el_from_key(plist_t node, const char *key); - + PLIST_API void plist_array_remove_item(plist_t node, uint32_t n); /******************************************** * * - * Setters * + * Dictionary functions * * * ********************************************/ /** - * Add a subnode to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). This function fails silently - * if subnode already has a father. - * - * @param node the node to add a children to - * @param subnode the children node - */ - PLIST_API void plist_add_sub_node(plist_t node, plist_t subnode); - -/** - * Add a subnode of type #PLIST_KEY to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). - * - * @param node the node to add a children to - * @param val the key value encoded as an ASCII string (must be null terminated) - */ - PLIST_API void plist_add_sub_key_el(plist_t node, const char *val); - -/** - * Add a subnode of type #PLIST_STRING to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). + * Get size of a #PLIST_DICT node. * - * @param node the node to add a children to - * @param val the string value encoded as an ASCII or UTF-8 string (must be null terminated) + * @param node the node of type #PLIST_DICT + * @return size of the #PLIST_DICT node */ - PLIST_API void plist_add_sub_string_el(plist_t node, const char *val); + PLIST_API uint32_t plist_dict_get_size(plist_t node); /** - * Add a subnode of type #PLIST_BOOLEAN to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). + * Get the nth item in a #PLIST_DICT node. * - * @param node the node to add a children to - * @param val the boolean value (TRUE or FALSE) - */ - PLIST_API void plist_add_sub_bool_el(plist_t node, uint8_t val); - -/** - * Add a subnode of type #PLIST_UINT to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). - * - * @param node the node to add a children to - * @param val the unsigned integer value + * @param node the node of type #PLIST_DICT + * @param key the identifier of the item to get. + * @return the item or NULL if node is not of type #PLIST_DICT */ - PLIST_API void plist_add_sub_uint_el(plist_t node, uint64_t val); + PLIST_API plist_t plist_dict_get_item(plist_t node, const char* key); /** - * Add a subnode of type #PLIST_REAL to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). + * Set item identified by key in a #PLIST_DICT node. + * The previous item at index n will be freed using #plist_free * - * @param node the node to add a children to - * @param val the real value + * @param node the node of type #PLIST_DICT + * @param item the new item associated to key + * @param key the identifier of the item to get. Assert if identifier is not present. */ - PLIST_API void plist_add_sub_real_el(plist_t node, double val); + PLIST_API void plist_dict_set_item(plist_t node, plist_t item, const char* key); /** - * Add a subnode of type #PLIST_DATA to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). + * Insert a new item at position n in a #PLIST_DICT node. * - * @param node the node to add a children to - * @param val the binary buffer - * @param length the length of the buffer + * @param node the node of type #PLIST_DICT + * @param item the new item to insert + * @param key The identifier of the item to insert. Assert if identifier already present. */ - PLIST_API void plist_add_sub_data_el(plist_t node, const char *val, uint64_t length); + PLIST_API void plist_dict_insert_item(plist_t node, plist_t item, const char* key); /** - * Add a subnode of type #PLIST_DATE to a node. The node must be of a structured type - * (ie #PLIST_DICT or #PLIST_ARRAY). + * Remove an existing position in a #PLIST_DICT node. + * Removed position will be freed using #plist_free * - * @param node the node to add a children to - * @param sec the number of seconds since 01/01/2001 - * @param usec the number of microseconds + * @param node the node of type #PLIST_DICT + * @param key The identifier of the item to remove. Assert if identifier is not present. */ - PLIST_API void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec); + PLIST_API void plist_dict_remove_item(plist_t node, const char* key); /******************************************** @@ -261,6 +289,13 @@ extern "C" { * * ********************************************/ +/** + * Get the parent of a node + * + * @param node the parent (NULL if node is root) + */ + PLIST_API plist_t plist_get_parent(plist_t node); + /** * Get the #plist_type of a node. * @@ -454,7 +489,6 @@ extern "C" { PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist); - /******************************************** * * * Utils * @@ -488,6 +522,143 @@ extern "C" { */ PLIST_API char plist_compare_node_value(plist_t node_l, plist_t node_r); + +//DEPRECATED API BELOW + +/*@}*/ +/** + * \defgroup DeprecatedAPI Deprecated libplist API + */ +/*@{*/ + +/******************************************** + * * + * Tree navigation * + * * + ********************************************/ + +/** + * Get the first child of a node + * + * @param node the first child + */ + PLIST_API plist_t plist_get_first_child(plist_t node); + +/** + * Get the next sibling of a node + * + * @param node the next sibling + */ + PLIST_API plist_t plist_get_next_sibling(plist_t node); + +/** + * Get the previous sibling of a node + * + * @param node the previous sibling + */ + PLIST_API plist_t plist_get_prev_sibling(plist_t node); + +/** + * Get the nth child of a #PLIST_ARRAY node. + * + * @param node the node of type #PLIST_ARRAY + * @param n the index of the child to get. Range is [0, array_size[ + * @return the nth children or NULL if node is not of type #PLIST_ARRAY + */ + PLIST_API plist_t plist_get_array_nth_el(plist_t node, uint32_t n); + +/** + * Get the child of a #PLIST_DICT node from the associated key value. + * + * @param node the node of type #PLIST_DICT + * @param key the key associated to the requested value + * @return the key associated value or NULL if node is not of type #PLIST_DICT + */ + PLIST_API plist_t plist_get_dict_el_from_key(plist_t node, const char *key); + + +/******************************************** + * * + * Setters * + * * + ********************************************/ + +/** + * Add a subnode to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). This function fails silently + * if subnode already has a father. + * + * @param node the node to add a children to + * @param subnode the children node + */ + PLIST_API void plist_add_sub_node(plist_t node, plist_t subnode); + +/** + * Add a subnode of type #PLIST_KEY to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param val the key value encoded as an ASCII string (must be null terminated) + */ + PLIST_API void plist_add_sub_key_el(plist_t node, const char *val); + +/** + * Add a subnode of type #PLIST_STRING to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param val the string value encoded as an ASCII or UTF-8 string (must be null terminated) + */ + PLIST_API void plist_add_sub_string_el(plist_t node, const char *val); + +/** + * Add a subnode of type #PLIST_BOOLEAN to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param val the boolean value (TRUE or FALSE) + */ + PLIST_API void plist_add_sub_bool_el(plist_t node, uint8_t val); + +/** + * Add a subnode of type #PLIST_UINT to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param val the unsigned integer value + */ + PLIST_API void plist_add_sub_uint_el(plist_t node, uint64_t val); + +/** + * Add a subnode of type #PLIST_REAL to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param val the real value + */ + PLIST_API void plist_add_sub_real_el(plist_t node, double val); + +/** + * Add a subnode of type #PLIST_DATA to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param val the binary buffer + * @param length the length of the buffer + */ + PLIST_API void plist_add_sub_data_el(plist_t node, const char *val, uint64_t length); + +/** + * Add a subnode of type #PLIST_DATE to a node. The node must be of a structured type + * (ie #PLIST_DICT or #PLIST_ARRAY). + * + * @param node the node to add a children to + * @param sec the number of seconds since 01/01/2001 + * @param usec the number of microseconds + */ + PLIST_API void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec); + + /*@}*/ diff --git a/src/plist.c b/src/plist.c index 4d98fd2..8368d6e 100644 --- a/src/plist.c +++ b/src/plist.c @@ -80,57 +80,70 @@ plist_t plist_new_array(void) return plist_new_node(data); } -static plist_t plist_add_sub_element(plist_t node, plist_type type, const void *value, uint64_t length) +//These nodes should not be handled by users +static plist_t plist_new_key(const char *val) { - //only structured types can have children - plist_type node_type = plist_get_node_type(node); - if (node_type == PLIST_DICT || node_type == PLIST_ARRAY) { - //only structured types are allowed to have nulll value - if (value || (!value && (type == PLIST_DICT || type == PLIST_ARRAY))) { + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_KEY; + data->strval = strdup(val); + data->length = strlen(val); + return plist_new_node(data); +} - plist_t subnode = NULL; +plist_t plist_new_string(const char *val) +{ + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_STRING; + data->strval = strdup(val); + data->length = strlen(val); + return plist_new_node(data); +} - //now handle value - plist_data_t data = plist_new_plist_data(); - data->type = type; - data->length = length; +plist_t plist_new_bool(uint8_t val) +{ + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_BOOLEAN; + data->boolval = val; + data->length = sizeof(uint8_t); + return plist_new_node(data); +} - switch (type) { - case PLIST_BOOLEAN: - data->boolval = *((char *) value); - break; - case PLIST_UINT: - data->intval = *((uint64_t *) value); - break; - case PLIST_REAL: - data->realval = *((double *) value); - break; - case PLIST_KEY: - case PLIST_STRING: - data->strval = strdup((char *) value); - break; - case PLIST_DATA: - data->buff = (uint8_t *) malloc(length); - memcpy(data->buff, value, length); - break; - case PLIST_DATE: - data->timeval.tv_sec = ((GTimeVal *) value)->tv_sec; - data->timeval.tv_usec = ((GTimeVal *) value)->tv_usec; - break; - case PLIST_ARRAY: - case PLIST_DICT: - default: - break; - } +plist_t plist_new_uint(uint64_t val) +{ + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_UINT; + data->intval = val; + data->length = sizeof(uint64_t); + return plist_new_node(data); +} - subnode = plist_new_node(data); - if (node) - g_node_append(node, subnode); - return subnode; - } else - return NULL; - } - return NULL; +plist_t plist_new_real(double val) +{ + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_REAL; + data->realval = val; + data->length = sizeof(double); + return plist_new_node(data); +} + +plist_t plist_new_data(const char *val, uint64_t length) +{ + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_DATA; + data->buff = (uint8_t *) malloc(length); + memcpy(data->buff, val, length); + data->length = length; + return plist_new_node(data); +} + +plist_t plist_new_date(int32_t sec, int32_t usec) +{ + plist_data_t data = plist_new_plist_data(); + data->type = PLIST_DATE; + data->timeval.tv_sec = sec; + data->timeval.tv_usec = usec; + data->length = sizeof(GTimeVal); + return plist_new_node(data); } void plist_free(plist_t plist) @@ -181,54 +194,131 @@ plist_t plist_copy(plist_t node) return copied; } -plist_t plist_get_first_child(plist_t node) +uint32_t plist_array_get_size(plist_t node) { - return (plist_t) g_node_first_child((GNode *) node); + uint32_t ret = 0; + if (node && PLIST_ARRAY == plist_get_node_type(node)) { + ret = g_node_n_children(node); + } + return ret; } -plist_t plist_get_next_sibling(plist_t node) +plist_t plist_array_get_item(plist_t node, uint32_t n) { - return (plist_t) g_node_next_sibling((GNode *) node); + plist_t ret = NULL; + if (node && PLIST_ARRAY == plist_get_node_type(node)) { + ret = (plist_t)g_node_nth_child(node, n); + } + return ret; } -plist_t plist_get_prev_sibling(plist_t node) +void plist_array_set_item(plist_t node, plist_t item, uint32_t n) { - return (plist_t) g_node_prev_sibling((GNode *) node); + if (node && PLIST_ARRAY == plist_get_node_type(node)) { + plist_t old_item = plist_array_get_item(node, n); + if (old_item) { + plist_free_node(old_item, NULL); + old_item = NULL; + plist_copy_node(item, &old_item); + } + } + return; } -plist_t plist_get_parent(plist_t node) +void plist_array_append_item(plist_t node, plist_t item) { - return node ? (plist_t) ((GNode *) node)->parent : NULL; + if (node && PLIST_ARRAY == plist_get_node_type(node)) { + g_node_append(node, item); + } + return; } -plist_t plist_get_array_nth_el(plist_t node, uint32_t n) +void plist_array_insert_item(plist_t node, plist_t item, uint32_t n) { - plist_t ret = NULL; if (node && PLIST_ARRAY == plist_get_node_type(node)) { - uint32_t i = 0; - plist_t temp = plist_get_first_child(node); + g_node_insert(node, n, item); + } + return; +} - while (i <= n && temp) { - if (i == n) - ret = temp; - temp = plist_get_next_sibling(temp); - i++; +void plist_array_remove_item(plist_t node, uint32_t n) +{ + if (node && PLIST_ARRAY == plist_get_node_type(node)) { + plist_t old_item = plist_array_get_item(node, n); + if (old_item) { + plist_free(old_item); } } + return; +} + +uint32_t plist_dict_get_size(plist_t node) +{ + uint32_t ret = 0; + if (node && PLIST_DICT == plist_get_node_type(node)) { + ret = g_node_n_children(node) / 2; + } return ret; } -plist_t plist_get_dict_el_from_key(plist_t node, const char *key) +plist_t plist_dict_get_item(plist_t node, const char* key) { plist_t ret = NULL; + if (node && PLIST_DICT == plist_get_node_type(node)) { - plist_t key_node = plist_find_node_by_key(node, key); - ret = plist_get_next_sibling(key_node); + plist_t current = NULL; + for (current = plist_get_first_child(node); + current; + current = plist_get_next_sibling(plist_get_next_sibling(current))) { + + assert( PLIST_KEY == plist_get_node_type(current) ); + plist_data_t data = plist_get_data(current); + + if (data && !strcmp(key, data->strval)) { + ret = plist_get_next_sibling(current); + break; + } + } } return ret; } +void plist_dict_set_item(plist_t node, plist_t item, const char* key) +{ + if (node && PLIST_DICT == plist_get_node_type(node)) { + plist_t old_item = plist_dict_get_item(node, key); + if (old_item) { + plist_free_node(old_item, NULL); + old_item = NULL; + plist_copy_node(item, &old_item); + } + } + return; +} + +void plist_dict_insert_item(plist_t node, plist_t item, const char* key) +{ + if (node && PLIST_DICT == plist_get_node_type(node)) { + g_node_append(node, plist_new_key(key)); + g_node_append(node, item); + } + return; +} + +void plist_dict_remove_item(plist_t node, const char* key) +{ + if (node && PLIST_DICT == plist_get_node_type(node)) { + plist_t old_item = plist_dict_get_item(node, key); + if (old_item) { + plist_t key_node = g_node_prev_sibling(old_item); + plist_free(key_node); + plist_free(old_item); + } + } + return; +} + static char compare_node_value(plist_type type, plist_data_t data, const void *value, uint64_t length) { char res = FALSE; @@ -335,6 +425,11 @@ static void plist_get_type_and_value(plist_t node, plist_type * type, void *valu } } +plist_t plist_get_parent(plist_t node) +{ + return node ? (plist_t) ((GNode *) node)->parent : NULL; +} + plist_type plist_get_node_type(plist_t node) { if (node) { @@ -345,51 +440,6 @@ plist_type plist_get_node_type(plist_t node) return PLIST_NONE; } -void plist_add_sub_node(plist_t node, plist_t subnode) -{ - if (node && subnode) { - plist_type type = plist_get_node_type(node); - if (type == PLIST_DICT || type == PLIST_ARRAY) - g_node_append(node, subnode); - } -} - -void plist_add_sub_key_el(plist_t node, const char *val) -{ - plist_add_sub_element(node, PLIST_KEY, val, strlen(val)); -} - -void plist_add_sub_string_el(plist_t node, const char *val) -{ - plist_add_sub_element(node, PLIST_STRING, val, strlen(val)); -} - -void plist_add_sub_bool_el(plist_t node, uint8_t val) -{ - plist_add_sub_element(node, PLIST_BOOLEAN, &val, sizeof(uint8_t)); -} - -void plist_add_sub_uint_el(plist_t node, uint64_t val) -{ - plist_add_sub_element(node, PLIST_UINT, &val, sizeof(uint64_t)); -} - -void plist_add_sub_real_el(plist_t node, double val) -{ - plist_add_sub_element(node, PLIST_REAL, &val, sizeof(double)); -} - -void plist_add_sub_data_el(plist_t node, const char *val, uint64_t length) -{ - plist_add_sub_element(node, PLIST_DATA, val, length); -} - -void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec) -{ - GTimeVal val = { sec, usec }; - plist_add_sub_element(node, PLIST_DATE, &val, sizeof(GTimeVal)); -} - void plist_get_key_val(plist_t node, char **val) { plist_type type = plist_get_node_type(node); @@ -570,7 +620,6 @@ static plist_t plist_set_element_val(plist_t node, plist_type type, const void * } } - void plist_set_key_val(plist_t node, const char *val) { plist_set_element_val(node, PLIST_KEY, val, strlen(val)); @@ -606,3 +655,149 @@ void plist_set_date_val(plist_t node, int32_t sec, int32_t usec) GTimeVal val = { sec, usec }; plist_set_element_val(node, PLIST_DATE, &val, sizeof(GTimeVal)); } + +//DEPRECATED API BELOW + +static plist_t plist_add_sub_element(plist_t node, plist_type type, const void *value, uint64_t length) +{ + //only structured types can have children + plist_type node_type = plist_get_node_type(node); + if (node_type == PLIST_DICT || node_type == PLIST_ARRAY) { + //only structured types are allowed to have nulll value + if (value || (!value && (type == PLIST_DICT || type == PLIST_ARRAY))) { + + plist_t subnode = NULL; + + //now handle value + plist_data_t data = plist_new_plist_data(); + data->type = type; + data->length = length; + + switch (type) { + case PLIST_BOOLEAN: + data->boolval = *((char *) value); + break; + case PLIST_UINT: + data->intval = *((uint64_t *) value); + break; + case PLIST_REAL: + data->realval = *((double *) value); + break; + case PLIST_KEY: + case PLIST_STRING: + data->strval = strdup((char *) value); + break; + case PLIST_DATA: + data->buff = (uint8_t *) malloc(length); + memcpy(data->buff, value, length); + break; + case PLIST_DATE: + data->timeval.tv_sec = ((GTimeVal *) value)->tv_sec; + data->timeval.tv_usec = ((GTimeVal *) value)->tv_usec; + break; + case PLIST_ARRAY: + case PLIST_DICT: + default: + break; + } + + subnode = plist_new_node(data); + if (node) + g_node_append(node, subnode); + return subnode; + } else + return NULL; + } + return NULL; +} + + +plist_t plist_get_first_child(plist_t node) +{ + return (plist_t) g_node_first_child((GNode *) node); +} + +plist_t plist_get_next_sibling(plist_t node) +{ + return (plist_t) g_node_next_sibling((GNode *) node); +} + +plist_t plist_get_prev_sibling(plist_t node) +{ + return (plist_t) g_node_prev_sibling((GNode *) node); +} + +plist_t plist_get_array_nth_el(plist_t node, uint32_t n) +{ + plist_t ret = NULL; + if (node && PLIST_ARRAY == plist_get_node_type(node)) { + uint32_t i = 0; + plist_t temp = plist_get_first_child(node); + + while (i <= n && temp) { + if (i == n) + ret = temp; + temp = plist_get_next_sibling(temp); + i++; + } + } + return ret; +} + +plist_t plist_get_dict_el_from_key(plist_t node, const char *key) +{ + plist_t ret = NULL; + if (node && PLIST_DICT == plist_get_node_type(node)) { + + plist_t key_node = plist_find_node_by_key(node, key); + ret = plist_get_next_sibling(key_node); + } + return ret; +} + +void plist_add_sub_node(plist_t node, plist_t subnode) +{ + if (node && subnode) { + plist_type type = plist_get_node_type(node); + if (type == PLIST_DICT || type == PLIST_ARRAY) + g_node_append(node, subnode); + } +} + +void plist_add_sub_key_el(plist_t node, const char *val) +{ + plist_add_sub_element(node, PLIST_KEY, val, strlen(val)); +} + +void plist_add_sub_string_el(plist_t node, const char *val) +{ + plist_add_sub_element(node, PLIST_STRING, val, strlen(val)); +} + +void plist_add_sub_bool_el(plist_t node, uint8_t val) +{ + plist_add_sub_element(node, PLIST_BOOLEAN, &val, sizeof(uint8_t)); +} + +void plist_add_sub_uint_el(plist_t node, uint64_t val) +{ + plist_add_sub_element(node, PLIST_UINT, &val, sizeof(uint64_t)); +} + +void plist_add_sub_real_el(plist_t node, double val) +{ + plist_add_sub_element(node, PLIST_REAL, &val, sizeof(double)); +} + +void plist_add_sub_data_el(plist_t node, const char *val, uint64_t length) +{ + plist_add_sub_element(node, PLIST_DATA, val, length); +} + +void plist_add_sub_date_el(plist_t node, int32_t sec, int32_t usec) +{ + GTimeVal val = { sec, usec }; + plist_add_sub_element(node, PLIST_DATE, &val, sizeof(GTimeVal)); +} + + -- cgit v1.1-32-gdbae