summaryrefslogtreecommitdiffstats
path: root/src/bplist.c
diff options
context:
space:
mode:
authorGravatar Jonathan Beck2009-02-15 17:15:29 +0100
committerGravatar Jonathan Beck2009-02-15 17:15:29 +0100
commitbb3097cb2266b55719b955c93d09a0e2d6f8eccb (patch)
tree478a6dd7b31b1640d79bc645052fc9843cc74ca1 /src/bplist.c
parent8e9eb83c2a8cd3b6a6d1943043f1d3b674e82de4 (diff)
downloadlibplist-bb3097cb2266b55719b955c93d09a0e2d6f8eccb.tar.gz
libplist-bb3097cb2266b55719b955c93d09a0e2d6f8eccb.tar.bz2
Add more regression test and fix Integer and Real type handling.
Diffstat (limited to 'src/bplist.c')
-rw-r--r--src/bplist.c80
1 files changed, 16 insertions, 64 deletions
diff --git a/src/bplist.c b/src/bplist.c
index 95070d7..cf9b9c6 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -87,7 +87,7 @@ static uint32_t uint24_from_be(char *buff)
87#define UINT_TO_HOST(x, n) \ 87#define UINT_TO_HOST(x, n) \
88 (n == 8 ? GUINT64_FROM_BE( *(uint64_t *)(x) ) : \ 88 (n == 8 ? GUINT64_FROM_BE( *(uint64_t *)(x) ) : \
89 (n == 4 ? GUINT32_FROM_BE( *(uint32_t *)(x) ) : \ 89 (n == 4 ? GUINT32_FROM_BE( *(uint32_t *)(x) ) : \
90 (n == 3 ? uint24_from_be( x ) : \ 90 (n == 3 ? uint24_from_be( (char*)x ) : \
91 (n == 2 ? GUINT16_FROM_BE( *(uint16_t *)(x) ) : \ 91 (n == 2 ? GUINT16_FROM_BE( *(uint16_t *)(x) ) : \
92 *(uint8_t *)(x) )))) 92 *(uint8_t *)(x) ))))
93 93
@@ -99,10 +99,7 @@ static uint32_t uint24_from_be(char *buff)
99 ( ((uint64_t)x) < (1ULL << 24) ? 3 : \ 99 ( ((uint64_t)x) < (1ULL << 24) ? 3 : \
100 ( ((uint64_t)x) < (1ULL << 32) ? 4 : 8)))) 100 ( ((uint64_t)x) < (1ULL << 32) ? 4 : 8))))
101 101
102#define get_real_bytes(x) (x >> 32 ? 4 : 8) 102#define get_real_bytes(x) (x == (float) x ? 4 : 8)
103
104
105
106 103
107 104
108static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object) 105static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object)
@@ -133,12 +130,18 @@ static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object)
133static plist_t parse_real_node(char *bnode, uint8_t size) 130static plist_t parse_real_node(char *bnode, uint8_t size)
134{ 131{
135 plist_data_t data = plist_new_plist_data(); 132 plist_data_t data = plist_new_plist_data();
133 float floatval = 0.0;
136 134
137 size = 1 << size; // make length less misleading 135 size = 1 << size; // make length less misleading
138 switch (size) { 136 switch (size) {
139 case sizeof(float): 137 case sizeof(float):
138 floatval = *(float*)bnode;
139 byte_convert((uint8_t*)&floatval, sizeof(float));
140 data->realval = floatval;
141 break;
140 case sizeof(double): 142 case sizeof(double):
141 data->intval = UINT_TO_HOST(bnode, size); //use the fact that we have an union to cheat byte swapping 143 data->realval = *(double*)bnode;
144 byte_convert((uint8_t*)&(data->realval), sizeof(double));
142 break; 145 break;
143 default: 146 default:
144 free(data); 147 free(data);
@@ -187,7 +190,7 @@ static plist_t parse_unicode_node(char *bnode, uint64_t size)
187 data->unicodeval[sizeof(gunichar2) * size] = '\0'; 190 data->unicodeval[sizeof(gunichar2) * size] = '\0';
188 data->length = size; 191 data->length = size;
189 for (i = 0; i <= size; i++) 192 for (i = 0; i <= size; i++)
190 byte_convert(data->unicodeval + i, sizeof(gunichar2)); 193 byte_convert((uint8_t*)(data->unicodeval + i), sizeof(gunichar2));
191 return g_node_new(data); 194 return g_node_new(data);
192} 195}
193 196
@@ -543,63 +546,7 @@ static guint plist_data_hash(gconstpointer key)
543 return hash; 546 return hash;
544} 547}
545 548
546static gboolean plist_data_compare(gconstpointer a, gconstpointer b)
547{
548 plist_data_t val_a = NULL;
549 plist_data_t val_b = NULL;
550 549
551 if (!a || !b)
552 return FALSE;
553
554 if (!((GNode *) a)->data || !((GNode *) b)->data)
555 return FALSE;
556
557 val_a = plist_get_data((plist_t) a);
558 val_b = plist_get_data((plist_t) b);
559
560 if (val_a->type != val_b->type)
561 return FALSE;
562
563 switch (val_a->type) {
564 case PLIST_BOOLEAN:
565 case PLIST_UINT:
566 case PLIST_REAL:
567 if (val_a->intval == val_b->intval) //it is an union so this is sufficient
568 return TRUE;
569 else
570 return FALSE;
571
572 case PLIST_KEY:
573 case PLIST_STRING:
574 if (!strcmp(val_a->strval, val_b->strval))
575 return TRUE;
576 else
577 return FALSE;
578 case PLIST_UNICODE:
579 if (!memcmp(val_a->unicodeval, val_b->unicodeval, val_a->length))
580 return TRUE;
581 else
582 return FALSE;
583
584 case PLIST_DATA:
585 case PLIST_ARRAY:
586 case PLIST_DICT:
587 //compare pointer
588 if (a == b)
589 return TRUE;
590 else
591 return FALSE;
592 break;
593 case PLIST_DATE:
594 if (!memcmp(&(val_a->timeval), &(val_b->timeval), sizeof(GTimeVal)))
595 return TRUE;
596 else
597 return FALSE;
598 default:
599 break;
600 }
601 return FALSE;
602}
603 550
604struct serialize_s { 551struct serialize_s {
605 GPtrArray *objects; 552 GPtrArray *objects;
@@ -655,7 +602,12 @@ static void write_real(GByteArray * bplist, double val)
655 uint64_t size = get_real_bytes(*((uint64_t *) & val)); //cheat to know used space 602 uint64_t size = get_real_bytes(*((uint64_t *) & val)); //cheat to know used space
656 uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size); 603 uint8_t *buff = (uint8_t *) malloc(sizeof(uint8_t) + size);
657 buff[0] = BPLIST_REAL | Log2(size); 604 buff[0] = BPLIST_REAL | Log2(size);
658 memcpy(buff + 1, &val, size); 605 if (size == sizeof(double)) {
606 memcpy(buff + 1, &val, size);
607 } else if (size == sizeof(float)) {
608 float tmpval = (float) val;
609 memcpy(buff + 1, &tmpval, size);
610 }
659 byte_convert(buff + 1, size); 611 byte_convert(buff + 1, size);
660 g_byte_array_append(bplist, buff, sizeof(uint8_t) + size); 612 g_byte_array_append(bplist, buff, sizeof(uint8_t) + size);
661 free(buff); 613 free(buff);