summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Jonathan Beck2009-01-04 20:56:05 +0100
committerGravatar Jonathan Beck2009-01-04 20:56:05 +0100
commita835ed062afea72a2c50fc002b0467925f8d9c1b (patch)
tree23a2bc7cfd487a568013c9cee7e78e46afa9ad02
parenta3c6acf863f1a4deef76b0075c36f20de8d31197 (diff)
downloadlibplist-a835ed062afea72a2c50fc002b0467925f8d9c1b.tar.gz
libplist-a835ed062afea72a2c50fc002b0467925f8d9c1b.tar.bz2
handle date tag.
-rw-r--r--src/bplist.c43
-rw-r--r--src/plist.h1
-rw-r--r--src/xplist.c11
3 files changed, 43 insertions, 12 deletions
diff --git a/src/bplist.c b/src/bplist.c
index 7a7225d..cbe53cd 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -74,7 +74,7 @@ static void byte_convert(uint8_t *address, size_t size)
#endif
}
-#define swap_n_bytes(x, n) \
+#define UINT_TO_HOST(x, n) \
(n == 8 ? GUINT64_FROM_BE( *(uint64_t *)(x) ) : \
(n == 4 ? GUINT32_FROM_BE( *(uint32_t *)(x) ) : \
(n == 2 ? GUINT16_FROM_BE( *(uint16_t *)(x) ) : \
@@ -104,7 +104,7 @@ static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object)
case sizeof(uint32_t):
case sizeof(uint64_t):
memcpy(&data->intval, bnode, size);
- data->intval = swap_n_bytes(&data->intval, size);
+ data->intval = UINT_TO_HOST(&data->intval, size);
break;
default:
free(data);
@@ -124,7 +124,7 @@ static plist_t parse_real_node(char *bnode, uint8_t size)
switch (size) {
case sizeof(float):
case sizeof(double):
- data->realval = swap_n_bytes(bnode, size);
+ data->intval = UINT_TO_HOST(bnode, size); //use the fact that we have an union to cheat byte swapping
break;
default:
free(data);
@@ -134,6 +134,18 @@ static plist_t parse_real_node(char *bnode, uint8_t size)
return g_node_new(data);
}
+static plist_t parse_date_node(char *bnode, uint8_t size)
+{
+ plist_t node = parse_real_node(bnode, size);
+ plist_data_t data = plist_get_data(node);
+
+ double time_real = data->realval;
+ data->timeval.tv_sec = (glong)time_real;
+ data->timeval.tv_usec = (time_real - (glong)time_real) * G_USEC_PER_SEC;
+ data->type = PLIST_DATE;
+ return node;
+}
+
static plist_t parse_string_node(char *bnode, uint8_t size)
{
plist_data_t data = plist_new_plist_data();
@@ -241,7 +253,7 @@ static plist_t parse_bin_node(char *object, uint8_t dict_size, char **next_objec
if (3 != size)
return NULL;
else
- return parse_real_node(object, size);
+ return parse_date_node(object, size);
case BPLIST_DATA:
if (0x0F == size) {
@@ -378,7 +390,7 @@ void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist)
uint64_t current_offset = 0;
const char *offset_table = plist_bin + offset_table_index;
for (i = 0; i < num_objects; i++) {
- current_offset = swap_n_bytes(offset_table + i * offset_size, offset_size);
+ current_offset = UINT_TO_HOST(offset_table + i * offset_size, offset_size);
log_debug_msg("parse_nodes: current_offset = %i\n", current_offset);
char *obj = plist_bin + current_offset;
@@ -402,8 +414,8 @@ void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist)
str_i = j * dict_param_size;
str_j = (j + data->length) * dict_param_size;
- index1 = swap_n_bytes(data->buff + str_i, dict_param_size);
- index2 = swap_n_bytes(data->buff + str_j, dict_param_size);
+ index1 = UINT_TO_HOST(data->buff + str_i, dict_param_size);
+ index2 = UINT_TO_HOST(data->buff + str_j, dict_param_size);
//first one is actually a key
plist_get_data(nodeslist[index1])->type = PLIST_KEY;
@@ -430,7 +442,7 @@ void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist)
log_debug_msg("parse_nodes: array found\n");
for (j = 0; j < data->length; j++) {
str_j = j * dict_param_size;
- index1 = swap_n_bytes(data->buff + str_j, dict_param_size);
+ index1 = UINT_TO_HOST(data->buff + str_j, dict_param_size);
if (index1 < num_objects) {
if (G_NODE_IS_ROOT(nodeslist[index1]))
@@ -463,7 +475,7 @@ static guint plist_data_hash(gconstpointer key)
case PLIST_BOOLEAN:
case PLIST_UINT:
case PLIST_REAL:
- buff = (char *) &data->intval;
+ buff = (char *) &data->intval; //works also for real as we use an union
size = 8;
break;
case PLIST_KEY:
@@ -604,6 +616,17 @@ static void write_real(GByteArray * bplist, double val)
free(buff);
}
+static void write_date(GByteArray * bplist, double val)
+{
+ uint64_t size = 8; //dates always use 8 bytes
+ uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size);
+ buff[0] = BPLIST_DATE | Log2(size);
+ memcpy(buff + 1, &val, size);
+ byte_convert(buff + 1, size);
+ g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);
+ free(buff);
+}
+
static void write_raw_data(GByteArray * bplist, uint8_t mark, uint8_t * val, uint64_t size)
{
uint8_t marker = mark | (size < 15 ? size : 0xf);
@@ -764,7 +787,7 @@ void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
write_dict(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size);
break;
case PLIST_DATE:
- //TODO
+ write_date(bplist_buff, data->timeval.tv_sec + (double)data->timeval.tv_usec / G_USEC_PER_SEC );
break;
default:
break;
diff --git a/src/plist.h b/src/plist.h
index 8428597..bd12e3a 100644
--- a/src/plist.h
+++ b/src/plist.h
@@ -44,6 +44,7 @@ struct plist_data_s {
char *strval;
wchar_t *unicodeval;
uint8_t *buff;
+ GTimeVal timeval;
};
uint64_t length;
plist_type type;
diff --git a/src/xplist.c b/src/xplist.c
index 3487f96..29d4e46 100644
--- a/src/xplist.c
+++ b/src/xplist.c
@@ -188,7 +188,10 @@ static void node_to_xml(GNode * node, gpointer xml_struct)
tag = XPLIST_DICT;
isStruct = TRUE;
break;
- case PLIST_DATE: //TODO : handle date tag
+ case PLIST_DATE:
+ tag = XPLIST_DATE;
+ val = g_time_val_to_iso8601(&node_data->timeval);
+ break;
default:
break;
}
@@ -268,8 +271,12 @@ static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node)
continue;
}
- if (!xmlStrcmp(node->name, XPLIST_DATE))
+ if (!xmlStrcmp(node->name, XPLIST_DATE)) {
+ g_time_val_from_iso8601((char*)xmlNodeGetContent(node), &data->timeval);
+ data->type = PLIST_DATE;
+ data->length = sizeof(GTimeVal);
continue; //TODO : handle date tag
+ }
if (!xmlStrcmp(node->name, XPLIST_STRING)) {
data->strval = strdup( (char*) xmlNodeGetContent(node));