Commit c8a140dc authored by Jonathan Beck's avatar Jonathan Beck

Add a deep copy function and value setters for nodes.

parent e925e6f6
......@@ -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);
/********************************************
* *
......
......@@ -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;
......
......@@ -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));
}
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment