diff options
author | Jonathan Beck | 2009-07-08 19:30:53 +0200 |
---|---|---|
committer | Jonathan Beck | 2009-07-08 19:30:53 +0200 |
commit | c8a140dce1d160c1766d3e0ac1346900efc193f3 (patch) | |
tree | 120f29a6fb0fb86b10df3f95a028b2ff12bc8126 | |
parent | e925e6f61752fbdf9304c4f62bad3d21dc881a32 (diff) | |
download | libplist-c8a140dce1d160c1766d3e0ac1346900efc193f3.tar.gz libplist-c8a140dce1d160c1766d3e0ac1346900efc193f3.tar.bz2 |
Add a deep copy function and value setters for nodes.
-rw-r--r-- | include/plist/plist.h | 80 | ||||
-rw-r--r-- | src/bplist.c | 23 | ||||
-rw-r--r-- | src/plist.c | 119 | ||||
-rw-r--r-- | src/xplist.c | 10 |
4 files changed, 211 insertions, 21 deletions
diff --git a/include/plist/plist.h b/include/plist/plist.h index c289158..a075fc6 100644 --- a/include/plist/plist.h +++ b/include/plist/plist.h @@ -109,6 +109,15 @@ extern "C" { */ PLIST_API void plist_free(plist_t plist); +/** + * Return a copy of passed node and it's children + * + * @param plist the plist to copy + * @return copied plist + */ + PLIST_API plist_t plist_copy(plist_t node); + + /******************************************** * * * Tree navigation * @@ -321,6 +330,77 @@ extern "C" { PLIST_API void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec); +/******************************************** + * * + * Setters * + * * + ********************************************/ + +/** + * Set the value of a node. + * Forces type of node to #PLIST_KEY + * + * @param node the node + * @param val the key value + */ + PLIST_API void plist_set_key_val(plist_t node, const char *val); + +/** + * Set the value of a node. + * Forces type of node to #PLIST_STRING + * + * @param node the node + * @param val the string value + */ + PLIST_API void plist_set_string_val(plist_t node, const char *val); + +/** + * Set the value of a node. + * Forces type of node to #PLIST_BOOLEAN + * + * @param node the node + * @param val the boolean value + */ + PLIST_API void plist_set_bool_val(plist_t node, uint8_t val); + +/** + * Set the value of a node. + * Forces type of node to #PLIST_UINT + * + * @param node the node + * @param val the unsigned integer value + */ + PLIST_API void plist_set_uint_val(plist_t node, uint64_t val); + +/** + * Set the value of a node. + * Forces type of node to #PLIST_REAL + * + * @param node the node + * @param val the real value + */ + PLIST_API void plist_set_real_val(plist_t node, double val); + +/** + * Set the value of a node. + * Forces type of node to #PLIST_DATA + * + * @param node the node + * @param val the binary buffer + * @param length the length of the buffer + */ + PLIST_API void plist_set_data_val(plist_t node, const char *val, uint64_t length); + +/** + * Set the value of a node. + * Forces type of node to #PLIST_DATE + * + * @param node the node + * @param sec the number of seconds since 01/01/2001 + * @param usec the number of microseconds + */ + PLIST_API void plist_set_date_val(plist_t node, int32_t sec, int32_t usec); + /******************************************** * * diff --git a/src/bplist.c b/src/bplist.c index 6b2d2f3..f993d9e 100644 --- a/src/bplist.c +++ b/src/bplist.c @@ -80,7 +80,7 @@ static void byte_convert(uint8_t * address, size_t size) static uint32_t uint24_from_be(char *buff) { uint32_t ret = 0; - char *tmp = (char*) &ret; + char *tmp = (char *) &ret; memcpy(tmp + 1, buff, 3 * sizeof(char)); byte_convert(tmp, sizeof(uint32_t)); return ret; @@ -137,13 +137,13 @@ static plist_t parse_real_node(char *bnode, uint8_t size) size = 1 << size; // make length less misleading switch (size) { case sizeof(float): - floatval = *(float*)bnode; - byte_convert((uint8_t*)&floatval, sizeof(float)); + floatval = *(float *) bnode; + byte_convert((uint8_t *) & floatval, sizeof(float)); data->realval = floatval; break; case sizeof(double): - data->realval = *(double*)bnode; - byte_convert((uint8_t*)&(data->realval), sizeof(double)); + data->realval = *(double *) bnode; + byte_convert((uint8_t *) & (data->realval), sizeof(double)); break; default: free(data); @@ -197,7 +197,7 @@ static plist_t parse_unicode_node(char *bnode, uint64_t size) unicodestr = (gunichar2 *) malloc(sizeof(gunichar2) * size); memcpy(unicodestr, bnode, sizeof(gunichar2) * size); for (i = 0; i < size; i++) - byte_convert((uint8_t*)(unicodestr + i), sizeof(gunichar2)); + byte_convert((uint8_t *) (unicodestr + i), sizeof(gunichar2)); tmpstr = g_utf16_to_utf8(unicodestr, size, &items_read, &items_written, &error); free(unicodestr); @@ -426,7 +426,7 @@ void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist) return; //now parse trailer - trailer = (char*)(plist_bin + (length - BPLIST_TRL_SIZE)); + trailer = (char *) (plist_bin + (length - BPLIST_TRL_SIZE)); offset_size = trailer[BPLIST_TRL_OFFSIZE_IDX]; dict_param_size = trailer[BPLIST_TRL_PARMSIZE_IDX]; @@ -444,12 +444,12 @@ void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist) return; //parse serialized nodes - offset_table = (char*)(plist_bin + offset_table_index); + offset_table = (char *) (plist_bin + offset_table_index); for (i = 0; i < num_objects; i++) { char *obj = NULL; current_offset = UINT_TO_HOST(offset_table + i * offset_size, offset_size); - obj = (char*)(plist_bin + current_offset); + obj = (char *) (plist_bin + current_offset); nodeslist[i] = parse_bin_node(obj, dict_param_size, &obj); } @@ -734,7 +734,7 @@ static void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table memcpy(buff + i * dict_param_size, &idx1, dict_param_size); byte_convert(buff + i * dict_param_size, dict_param_size); - idx2 = *(uint64_t *)(g_hash_table_lookup(ref_table, cur->next)); + idx2 = *(uint64_t *) (g_hash_table_lookup(ref_table, cur->next)); memcpy(buff + (i + size) * dict_param_size, &idx2, dict_param_size); byte_convert(buff + (i + size) * dict_param_size, dict_param_size); } @@ -828,8 +828,7 @@ void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) unicodestr = g_utf8_to_utf16(data->strval, len, &items_read, &items_written, &error); write_unicode(bplist_buff, unicodestr, items_written); g_free(unicodestr); - } - else if (XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type) { + } else if (XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type) { write_string(bplist_buff, data->strval); } break; diff --git a/src/plist.c b/src/plist.c index 7949bce..e43d50d 100644 --- a/src/plist.c +++ b/src/plist.c @@ -109,7 +109,7 @@ static plist_t plist_add_sub_element(plist_t node, plist_type type, const void * data->strval = strdup((char *) value); break; case PLIST_DATA: - data->buff = (uint8_t*)malloc(length); + data->buff = (uint8_t *) malloc(length); memcpy(data->buff, value, length); break; case PLIST_DATE: @@ -138,6 +138,28 @@ void plist_free(plist_t plist) g_node_destroy(plist); } +static void plist_copy_node(GNode * node, gpointer parent_node) +{ + plist_t newnode = NULL; + plist_data_t data = plist_get_data(node); + plist_data_t newdata = plist_new_plist_data(); + + assert(data); // plist should always have data + + memcpy(newdata, data, sizeof(struct plist_data_s)); + newnode = plist_new_node(newdata); + + if (parent_node) { + g_node_append(parent_node, newnode); + } + g_node_children_foreach(node, G_TRAVERSE_ALL, plist_copy_node, newnode); +} + +plist_t plist_copy(plist_t node) +{ + plist_copy_node(node, NULL); +} + plist_t plist_get_first_child(plist_t node) { return (plist_t) g_node_first_child((GNode *) node); @@ -160,7 +182,7 @@ plist_t plist_get_array_nth_el(plist_t node, uint32_t n) uint32_t i = 0; plist_t temp = plist_get_first_child(node); - while ( i <= n && temp) { + while (i <= n && temp) { if (i == n) ret = temp; temp = plist_get_next_sibling(temp); @@ -465,5 +487,96 @@ gboolean plist_data_compare(gconstpointer a, gconstpointer b) char plist_compare_node_value(plist_t node_l, plist_t node_r) { - return plist_data_compare( node_l , node_r ); + return plist_data_compare(node_l, node_r); +} + +static plist_t plist_set_element_val(plist_t node, plist_type type, const void *value, uint64_t length) +{ + //free previous allocated buffer + plist_data_t data = plist_get_data(node); + assert(data); // a node should always have data attached + + switch (data->type) { + case PLIST_KEY: + case PLIST_STRING: + free(data->strval); + data->strval = NULL; + break; + case PLIST_DATA: + free(data->buff); + data->buff = NULL; + break; + default: + break; + } + + //now handle value + + 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; + } +} + + +void plist_set_key_val(plist_t node, const char *val) +{ + plist_set_element_val(node, PLIST_KEY, val, strlen(val)); +} + +void plist_set_string_val(plist_t node, const char *val) +{ + plist_set_element_val(node, PLIST_STRING, val, strlen(val)); +} + +void plist_set_bool_val(plist_t node, uint8_t val) +{ + plist_set_element_val(node, PLIST_BOOLEAN, &val, sizeof(uint8_t)); +} + +void plist_set_uint_val(plist_t node, uint64_t val) +{ + plist_set_element_val(node, PLIST_UINT, &val, sizeof(uint64_t)); +} + +void plist_set_real_val(plist_t node, double val) +{ + plist_set_element_val(node, PLIST_REAL, &val, sizeof(double)); +} + +void plist_set_data_val(plist_t node, const char *val, uint64_t length) +{ + plist_set_element_val(node, PLIST_DATA, val, length); +} + +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)); } diff --git a/src/xplist.c b/src/xplist.c index 38cc4fe..490367e 100644 --- a/src/xplist.c +++ b/src/xplist.c @@ -257,7 +257,7 @@ static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node) if (!xmlStrcmp(node->name, XPLIST_INT)) { xmlChar *strval = xmlNodeGetContent(node); - data->intval = g_ascii_strtoull((char *)strval, NULL, 0); + data->intval = g_ascii_strtoull((char *) strval, NULL, 0); data->type = PLIST_UINT; data->length = 8; xmlFree(strval); @@ -266,7 +266,7 @@ static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node) if (!xmlStrcmp(node->name, XPLIST_REAL)) { xmlChar *strval = xmlNodeGetContent(node); - data->realval = atof((char *)strval); + data->realval = atof((char *) strval); data->type = PLIST_REAL; data->length = 8; xmlFree(strval); @@ -287,9 +287,7 @@ static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node) len = strlen((char *) strval); type = xmlDetectCharEncoding(strval, len); - if (XML_CHAR_ENCODING_UTF8 == type || - XML_CHAR_ENCODING_ASCII == type || - XML_CHAR_ENCODING_NONE == type) { + if (XML_CHAR_ENCODING_UTF8 == type || XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type) { data->strval = strdup((char *) strval); data->type = PLIST_STRING; data->length = strlen(data->strval); @@ -311,7 +309,7 @@ static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node) xmlChar *strval = xmlNodeGetContent(node); gsize size = 0; guchar *dec = g_base64_decode((char *) strval, &size); - data->buff = (uint8_t*) malloc( size * sizeof(uint8_t)); + data->buff = (uint8_t *) malloc(size * sizeof(uint8_t)); memcpy(data->buff, dec, size * sizeof(uint8_t)); g_free(dec); data->length = size; |