summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Alexander Sack2010-03-24 17:47:02 +0100
committerGravatar Jonathan Beck2010-03-24 17:47:02 +0100
commite965b325b5adf4624f74b8d3366dddc2da9f81f3 (patch)
tree0cc7bdd060c4081f5150c8487748a2deeeb1e6f6 /src
parent9bccdb305845e31bcbc8c693e909cc5561f3dd03 (diff)
downloadlibplist-e965b325b5adf4624f74b8d3366dddc2da9f81f3.tar.gz
libplist-e965b325b5adf4624f74b8d3366dddc2da9f81f3.tar.bz2
Fix armel floating point endianess (LP: #541879)
* on armel system floating poing data can have different endianess than rest of types; hence we fix arm endianess for defined(__VFP_FP__) to be big/native; this also applies for data parsing/writing * date parsing didnt flip the endianess back for little endian systems when reading the values causing test failures; we fix this by ensuring float endianess is applied when parsing
Diffstat (limited to 'src')
-rw-r--r--src/bplist.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/src/bplist.c b/src/bplist.c
index a9e2638..5618c38 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -63,6 +63,22 @@ enum
BPLIST_MASK = 0xF0
};
+static void float_byte_convert(uint8_t * address, size_t size)
+{
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN && !defined (__VFP_FP__)
+ uint8_t i = 0, j = 0;
+ uint8_t tmp = 0;
+
+ for (i = 0; i < (size / 2); i++)
+ {
+ tmp = address[i];
+ j = ((size - 1) + 0) - i;
+ address[i] = address[j];
+ address[j] = tmp;
+ }
+#endif
+}
+
static void byte_convert(uint8_t * address, size_t size)
{
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
@@ -136,23 +152,27 @@ static plist_t parse_real_node(char *bnode, uint8_t size)
{
plist_data_t data = plist_new_plist_data();
float floatval = 0.0;
+ uint8_t* buf;
size = 1 << size; // make length less misleading
+ buf = malloc (size);
+ memcpy (buf, bnode, size);
switch (size)
{
case sizeof(float):
- floatval = *(float *) bnode;
- byte_convert((uint8_t *) & floatval, sizeof(float));
+ float_byte_convert(buf, size);
+ floatval = *(float *) buf;
data->realval = floatval;
break;
case sizeof(double):
- data->realval = *(double *) bnode;
- byte_convert((uint8_t *) & (data->realval), sizeof(double));
+ float_byte_convert(buf, size);
+ data->realval = *(double *) buf;
break;
default:
free(data);
return NULL;
}
+ free (buf);
data->type = PLIST_REAL;
data->length = sizeof(double);
@@ -648,7 +668,7 @@ static void write_real(GByteArray * bplist, double val)
float tmpval = (float) val;
memcpy(buff + 1, &tmpval, size);
}
- byte_convert(buff + 1, size);
+ float_byte_convert(buff + 1, size);
g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);
free(buff);
}
@@ -659,7 +679,7 @@ static void write_date(GByteArray * bplist, double val)
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);
+ float_byte_convert(buff + 1, size);
g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);
free(buff);
}