summaryrefslogtreecommitdiffstats
path: root/src/bplist.c
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/bplist.c
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/bplist.c')
-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
63 BPLIST_MASK = 0xF0 63 BPLIST_MASK = 0xF0
64}; 64};
65 65
66static void float_byte_convert(uint8_t * address, size_t size)
67{
68#if G_BYTE_ORDER == G_LITTLE_ENDIAN && !defined (__VFP_FP__)
69 uint8_t i = 0, j = 0;
70 uint8_t tmp = 0;
71
72 for (i = 0; i < (size / 2); i++)
73 {
74 tmp = address[i];
75 j = ((size - 1) + 0) - i;
76 address[i] = address[j];
77 address[j] = tmp;
78 }
79#endif
80}
81
66static void byte_convert(uint8_t * address, size_t size) 82static void byte_convert(uint8_t * address, size_t size)
67{ 83{
68#if G_BYTE_ORDER == G_LITTLE_ENDIAN 84#if G_BYTE_ORDER == G_LITTLE_ENDIAN
@@ -136,23 +152,27 @@ static plist_t parse_real_node(char *bnode, uint8_t size)
136{ 152{
137 plist_data_t data = plist_new_plist_data(); 153 plist_data_t data = plist_new_plist_data();
138 float floatval = 0.0; 154 float floatval = 0.0;
155 uint8_t* buf;
139 156
140 size = 1 << size; // make length less misleading 157 size = 1 << size; // make length less misleading
158 buf = malloc (size);
159 memcpy (buf, bnode, size);
141 switch (size) 160 switch (size)
142 { 161 {
143 case sizeof(float): 162 case sizeof(float):
144 floatval = *(float *) bnode; 163 float_byte_convert(buf, size);
145 byte_convert((uint8_t *) & floatval, sizeof(float)); 164 floatval = *(float *) buf;
146 data->realval = floatval; 165 data->realval = floatval;
147 break; 166 break;
148 case sizeof(double): 167 case sizeof(double):
149 data->realval = *(double *) bnode; 168 float_byte_convert(buf, size);
150 byte_convert((uint8_t *) & (data->realval), sizeof(double)); 169 data->realval = *(double *) buf;
151 break; 170 break;
152 default: 171 default:
153 free(data); 172 free(data);
154 return NULL; 173 return NULL;
155 } 174 }
175 free (buf);
156 data->type = PLIST_REAL; 176 data->type = PLIST_REAL;
157 data->length = sizeof(double); 177 data->length = sizeof(double);
158 178
@@ -648,7 +668,7 @@ static void write_real(GByteArray * bplist, double val)
648 float tmpval = (float) val; 668 float tmpval = (float) val;
649 memcpy(buff + 1, &tmpval, size); 669 memcpy(buff + 1, &tmpval, size);
650 } 670 }
651 byte_convert(buff + 1, size); 671 float_byte_convert(buff + 1, size);
652 g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); 672 g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);
653 free(buff); 673 free(buff);
654} 674}
@@ -659,7 +679,7 @@ static void write_date(GByteArray * bplist, double val)
659 uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size); 679 uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size);
660 buff[0] = BPLIST_DATE | Log2(size); 680 buff[0] = BPLIST_DATE | Log2(size);
661 memcpy(buff + 1, &val, size); 681 memcpy(buff + 1, &val, size);
662 byte_convert(buff + 1, size); 682 float_byte_convert(buff + 1, size);
663 g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); 683 g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);
664 free(buff); 684 free(buff);
665} 685}