summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Jonathan Beck2009-07-08 19:30:53 +0200
committerGravatar Jonathan Beck2009-07-08 19:30:53 +0200
commitc8a140dce1d160c1766d3e0ac1346900efc193f3 (patch)
tree120f29a6fb0fb86b10df3f95a028b2ff12bc8126
parente925e6f61752fbdf9304c4f62bad3d21dc881a32 (diff)
downloadlibplist-c8a140dce1d160c1766d3e0ac1346900efc193f3.tar.gz
libplist-c8a140dce1d160c1766d3e0ac1346900efc193f3.tar.bz2
Add a deep copy function and value setters for nodes.
-rw-r--r--include/plist/plist.h80
-rw-r--r--src/bplist.c23
-rw-r--r--src/plist.c119
-rw-r--r--src/xplist.c10
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;