summaryrefslogtreecommitdiffstats
path: root/src/bplist.c
diff options
context:
space:
mode:
authorGravatar Jonathan Beck2009-02-09 20:39:14 +0100
committerGravatar Jonathan Beck2009-02-09 21:02:56 +0100
commitfa4a22dde897c0e2a8cc89b7479f0513c9455d37 (patch)
tree877b0140a133fb34c821ff70bde1a4a8c6ef5ab1 /src/bplist.c
parentff1fa73f33e9223e69cbb71e70b084e3482dce3f (diff)
downloadlibplist-fa4a22dde897c0e2a8cc89b7479f0513c9455d37.tar.gz
libplist-fa4a22dde897c0e2a8cc89b7479f0513c9455d37.tar.bz2
Make it compile on MSVC 2005.
Diffstat (limited to 'src/bplist.c')
-rw-r--r--src/bplist.c127
1 files changed, 83 insertions, 44 deletions
diff --git a/src/bplist.c b/src/bplist.c
index 6e00f39..fb24a1e 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -75,6 +75,7 @@ static void byte_convert(uint8_t * address, size_t size)
75#endif 75#endif
76} 76}
77 77
78
78#define UINT_TO_HOST(x, n) \ 79#define UINT_TO_HOST(x, n) \
79 (n == 8 ? GUINT64_FROM_BE( *(uint64_t *)(x) ) : \ 80 (n == 8 ? GUINT64_FROM_BE( *(uint64_t *)(x) ) : \
80 (n == 4 ? GUINT32_FROM_BE( *(uint32_t *)(x) ) : \ 81 (n == 4 ? GUINT32_FROM_BE( *(uint32_t *)(x) ) : \
@@ -220,11 +221,14 @@ static plist_t parse_array_node(char *bnode, uint64_t size, uint32_t ref_size)
220 221
221static plist_t parse_bin_node(char *object, uint8_t dict_size, char **next_object) 222static plist_t parse_bin_node(char *object, uint8_t dict_size, char **next_object)
222{ 223{
224 uint16_t type = 0;
225 uint64_t size = 0;
226
223 if (!object) 227 if (!object)
224 return NULL; 228 return NULL;
225 229
226 uint16_t type = *object & 0xF0; 230 type = (*object) & 0xF0;
227 uint64_t size = *object & 0x0F; 231 size = (*object) & 0x0F;
228 object++; 232 object++;
229 233
230 switch (type) { 234 switch (type) {
@@ -364,6 +368,22 @@ static gpointer copy_plist_data(gconstpointer src, gpointer data)
364 368
365void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist) 369void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist)
366{ 370{
371 char *trailer = NULL;
372
373 uint8_t offset_size = 0;
374 uint8_t dict_param_size = 0;
375 uint64_t num_objects = 0;
376 uint64_t root_object = 0;
377 uint64_t offset_table_index = 0;
378
379 plist_t *nodeslist = NULL;
380 uint64_t i = 0;
381 uint64_t current_offset = 0;
382 char *offset_table = NULL;
383 uint32_t j = 0, str_i = 0, str_j = 0;
384 uint32_t index1 = 0, index2 = 0;
385
386
367 //first check we have enough data 387 //first check we have enough data
368 if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + BPLIST_TRL_SIZE)) 388 if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + BPLIST_TRL_SIZE))
369 return; 389 return;
@@ -375,39 +395,34 @@ void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist)
375 return; 395 return;
376 396
377 //now parse trailer 397 //now parse trailer
378 const char *trailer = plist_bin + (length - BPLIST_TRL_SIZE); 398 trailer = plist_bin + (length - BPLIST_TRL_SIZE);
379 399
380 uint8_t offset_size = trailer[BPLIST_TRL_OFFSIZE_IDX]; 400 offset_size = trailer[BPLIST_TRL_OFFSIZE_IDX];
381 uint8_t dict_param_size = trailer[BPLIST_TRL_PARMSIZE_IDX]; 401 dict_param_size = trailer[BPLIST_TRL_PARMSIZE_IDX];
382 uint64_t num_objects = be64dec(trailer + BPLIST_TRL_NUMOBJ_IDX); 402 num_objects = be64dec(trailer + BPLIST_TRL_NUMOBJ_IDX);
383 uint64_t root_object = be64dec(trailer + BPLIST_TRL_ROOTOBJ_IDX); 403 root_object = be64dec(trailer + BPLIST_TRL_ROOTOBJ_IDX);
384 uint64_t offset_table_index = be64dec(trailer + BPLIST_TRL_OFFTAB_IDX); 404 offset_table_index = be64dec(trailer + BPLIST_TRL_OFFTAB_IDX);
385 405
386 if (num_objects == 0) 406 if (num_objects == 0)
387 return; 407 return;
388 408
389 //allocate serialized array of nodes 409 //allocate serialized array of nodes
390 plist_t *nodeslist = NULL;
391 nodeslist = (plist_t *) malloc(sizeof(plist_t) * num_objects); 410 nodeslist = (plist_t *) malloc(sizeof(plist_t) * num_objects);
392 411
393 if (!nodeslist) 412 if (!nodeslist)
394 return; 413 return;
395 414
396 //parse serialized nodes 415 //parse serialized nodes
397 uint64_t i = 0; 416 offset_table = plist_bin + offset_table_index;
398 uint64_t current_offset = 0;
399 const char *offset_table = plist_bin + offset_table_index;
400 for (i = 0; i < num_objects; i++) { 417 for (i = 0; i < num_objects; i++) {
418 char *obj = NULL;
401 current_offset = UINT_TO_HOST(offset_table + i * offset_size, offset_size); 419 current_offset = UINT_TO_HOST(offset_table + i * offset_size, offset_size);
402 420
403 char *obj = plist_bin + current_offset; 421 obj = plist_bin + current_offset;
404 nodeslist[i] = parse_bin_node(obj, dict_param_size, &obj); 422 nodeslist[i] = parse_bin_node(obj, dict_param_size, &obj);
405 } 423 }
406 424
407 //setup children for structured types 425 //setup children for structured types
408 uint32_t j = 0, str_i = 0, str_j = 0;
409 uint32_t index1 = 0, index2 = 0;
410
411 for (i = 0; i < num_objects; i++) { 426 for (i = 0; i < num_objects; i++) {
412 427
413 plist_data_t data = plist_get_data(nodeslist[i]); 428 plist_data_t data = plist_get_data(nodeslist[i]);
@@ -514,14 +529,17 @@ static guint plist_data_hash(gconstpointer key)
514 529
515static gboolean plist_data_compare(gconstpointer a, gconstpointer b) 530static gboolean plist_data_compare(gconstpointer a, gconstpointer b)
516{ 531{
532 plist_data_t val_a = NULL;
533 plist_data_t val_b = NULL;
534
517 if (!a || !b) 535 if (!a || !b)
518 return FALSE; 536 return FALSE;
519 537
520 if (!((GNode *) a)->data || !((GNode *) b)->data) 538 if (!((GNode *) a)->data || !((GNode *) b)->data)
521 return FALSE; 539 return FALSE;
522 540
523 plist_data_t val_a = plist_get_data((plist_t) a); 541 val_a = plist_get_data((plist_t) a);
524 plist_data_t val_b = plist_get_data((plist_t) b); 542 val_b = plist_get_data((plist_t) b);
525 543
526 if (val_a->type != val_b->type) 544 if (val_a->type != val_b->type)
527 return FALSE; 545 return FALSE;
@@ -574,6 +592,7 @@ struct serialize_s {
574 592
575static void serialize_plist(GNode * node, gpointer data) 593static void serialize_plist(GNode * node, gpointer data)
576{ 594{
595 uint64_t *index_val = NULL;
577 struct serialize_s *ser = (struct serialize_s *) data; 596 struct serialize_s *ser = (struct serialize_s *) data;
578 uint64_t current_index = ser->objects->len; 597 uint64_t current_index = ser->objects->len;
579 598
@@ -584,7 +603,7 @@ static void serialize_plist(GNode * node, gpointer data)
584 return; 603 return;
585 } 604 }
586 //insert new ref 605 //insert new ref
587 uint64_t *index_val = (uint64_t *) malloc(sizeof(uint64_t)); 606 index_val = (uint64_t *) malloc(sizeof(uint64_t));
588 *index_val = current_index; 607 *index_val = current_index;
589 g_hash_table_insert(ser->ref_table, node, index_val); 608 g_hash_table_insert(ser->ref_table, node, index_val);
590 609
@@ -639,6 +658,7 @@ static void write_date(GByteArray * bplist, double val)
639 658
640static void write_raw_data(GByteArray * bplist, uint8_t mark, uint8_t * val, uint64_t size) 659static void write_raw_data(GByteArray * bplist, uint8_t mark, uint8_t * val, uint64_t size)
641{ 660{
661 uint8_t *buff = NULL;
642 uint8_t marker = mark | (size < 15 ? size : 0xf); 662 uint8_t marker = mark | (size < 15 ? size : 0xf);
643 g_byte_array_append(bplist, &marker, sizeof(uint8_t)); 663 g_byte_array_append(bplist, &marker, sizeof(uint8_t));
644 if (size >= 15) { 664 if (size >= 15) {
@@ -647,7 +667,7 @@ static void write_raw_data(GByteArray * bplist, uint8_t mark, uint8_t * val, uin
647 g_byte_array_append(bplist, int_buff->data, int_buff->len); 667 g_byte_array_append(bplist, int_buff->data, int_buff->len);
648 g_byte_array_free(int_buff, TRUE); 668 g_byte_array_free(int_buff, TRUE);
649 } 669 }
650 uint8_t *buff = (uint8_t *) malloc(size); 670 buff = (uint8_t *) malloc(size);
651 memcpy(buff, val, size); 671 memcpy(buff, val, size);
652 g_byte_array_append(bplist, buff, size); 672 g_byte_array_append(bplist, buff, size);
653 free(buff); 673 free(buff);
@@ -677,6 +697,12 @@ static void write_unicode(GByteArray * bplist, gunichar2 * val, uint64_t size)
677 697
678static void write_array(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size) 698static void write_array(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size)
679{ 699{
700 uint64_t idx = 0;
701 uint8_t *buff = NULL;
702
703 GNode *cur = NULL;
704 uint64_t i = 0;
705
680 uint64_t size = g_node_n_children(node); 706 uint64_t size = g_node_n_children(node);
681 uint8_t marker = BPLIST_ARRAY | (size < 15 ? size : 0xf); 707 uint8_t marker = BPLIST_ARRAY | (size < 15 ? size : 0xf);
682 g_byte_array_append(bplist, &marker, sizeof(uint8_t)); 708 g_byte_array_append(bplist, &marker, sizeof(uint8_t));
@@ -687,11 +713,8 @@ static void write_array(GByteArray * bplist, GNode * node, GHashTable * ref_tabl
687 g_byte_array_free(int_buff, TRUE); 713 g_byte_array_free(int_buff, TRUE);
688 } 714 }
689 715
690 uint64_t idx = 0; 716 buff = (uint8_t *) malloc(size * dict_param_size);
691 uint8_t *buff = (uint8_t *) malloc(size * dict_param_size);
692 717
693 GNode *cur = NULL;
694 uint64_t i = 0;
695 for (i = 0, cur = node->children; cur && i < size; cur = cur->next, i++) { 718 for (i = 0, cur = node->children; cur && i < size; cur = cur->next, i++) {
696 idx = *(uint64_t *) (g_hash_table_lookup(ref_table, cur)); 719 idx = *(uint64_t *) (g_hash_table_lookup(ref_table, cur));
697 memcpy(buff + i * dict_param_size, &idx, dict_param_size); 720 memcpy(buff + i * dict_param_size, &idx, dict_param_size);
@@ -706,6 +729,13 @@ static void write_array(GByteArray * bplist, GNode * node, GHashTable * ref_tabl
706 729
707static void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size) 730static void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size)
708{ 731{
732 uint64_t idx1 = 0;
733 uint64_t idx2 = 0;
734 uint8_t *buff = NULL;
735
736 GNode *cur = NULL;
737 uint64_t i = 0;
738
709 uint64_t size = g_node_n_children(node) / 2; 739 uint64_t size = g_node_n_children(node) / 2;
710 uint8_t marker = BPLIST_DICT | (size < 15 ? size : 0xf); 740 uint8_t marker = BPLIST_DICT | (size < 15 ? size : 0xf);
711 g_byte_array_append(bplist, &marker, sizeof(uint8_t)); 741 g_byte_array_append(bplist, &marker, sizeof(uint8_t));
@@ -716,12 +746,8 @@ static void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table
716 g_byte_array_free(int_buff, TRUE); 746 g_byte_array_free(int_buff, TRUE);
717 } 747 }
718 748
719 uint64_t idx1 = 0; 749 buff = (uint8_t *) malloc(size * 2 * dict_param_size);
720 uint64_t idx2 = 0;
721 uint8_t *buff = (uint8_t *) malloc(size * 2 * dict_param_size);
722 750
723 GNode *cur = NULL;
724 uint64_t i = 0;
725 for (i = 0, cur = node->children; cur && i < size; cur = cur->next->next, i++) { 751 for (i = 0, cur = node->children; cur && i < size; cur = cur->next->next, i++) {
726 idx1 = GPOINTER_TO_UINT(g_hash_table_lookup(ref_table, cur)); 752 idx1 = GPOINTER_TO_UINT(g_hash_table_lookup(ref_table, cur));
727 memcpy(buff + i * dict_param_size, &idx1, dict_param_size); 753 memcpy(buff + i * dict_param_size, &idx1, dict_param_size);
@@ -740,41 +766,55 @@ static void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table
740 766
741void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) 767void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
742{ 768{
769 GPtrArray *objects = NULL;
770 GHashTable *ref_table = NULL;
771 struct serialize_s ser_s;
772 uint8_t offset_size = 0;
773 uint8_t dict_param_size = 0;
774 uint64_t num_objects = 0;
775 uint64_t root_object = 0;
776 uint64_t offset_table_index = 0;
777 GByteArray *bplist_buff = NULL;
778 uint64_t i = 0;
779 uint8_t *buff = NULL;
780 uint64_t *offsets = NULL;
781 uint8_t pad[6] = { 0, 0, 0, 0, 0, 0 };
782 uint8_t trailer[BPLIST_TRL_SIZE];
783
743 //check for valid input 784 //check for valid input
744 if (!plist || !plist_bin || *plist_bin || !length) 785 if (!plist || !plist_bin || *plist_bin || !length)
745 return; 786 return;
746 787
747 //list of objects 788 //list of objects
748 GPtrArray *objects = g_ptr_array_new(); 789 objects = g_ptr_array_new();
749 //hashtable to write only once same nodes 790 //hashtable to write only once same nodes
750 GHashTable *ref_table = g_hash_table_new(plist_data_hash, plist_data_compare); 791 ref_table = g_hash_table_new(plist_data_hash, plist_data_compare);
751 792
752 //serialize plist 793 //serialize plist
753 struct serialize_s ser_s = { objects, ref_table }; 794 ser_s.objects = objects;
795 ser_s.ref_table = ref_table;
754 serialize_plist(plist, &ser_s); 796 serialize_plist(plist, &ser_s);
755 797
756 //now stream to output buffer 798 //now stream to output buffer
757 uint8_t offset_size = 0; //unknown yet 799 offset_size = 0; //unknown yet
758 uint8_t dict_param_size = get_needed_bytes(objects->len); 800 dict_param_size = get_needed_bytes(objects->len);
759 uint64_t num_objects = objects->len; 801 num_objects = objects->len;
760 uint64_t root_object = 0; //root is first in list 802 root_object = 0; //root is first in list
761 uint64_t offset_table_index = 0; //unknown yet 803 offset_table_index = 0; //unknown yet
762 804
763 //setup a dynamic bytes array to store bplist in 805 //setup a dynamic bytes array to store bplist in
764 GByteArray *bplist_buff = g_byte_array_new(); 806 bplist_buff = g_byte_array_new();
765 807
766 //set magic number and version 808 //set magic number and version
767 g_byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE); 809 g_byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE);
768 g_byte_array_append(bplist_buff, BPLIST_VERSION, BPLIST_VERSION_SIZE); 810 g_byte_array_append(bplist_buff, BPLIST_VERSION, BPLIST_VERSION_SIZE);
769 811
770 //write objects and table 812 //write objects and table
771 uint64_t i = 0; 813 offsets = (uint64_t *) malloc(num_objects * sizeof(uint64_t));
772 uint8_t *buff = NULL;
773 uint64_t offsets[num_objects];
774 for (i = 0; i < num_objects; i++) { 814 for (i = 0; i < num_objects; i++) {
775 815
776 offsets[i] = bplist_buff->len;
777 plist_data_t data = plist_get_data(g_ptr_array_index(objects, i)); 816 plist_data_t data = plist_get_data(g_ptr_array_index(objects, i));
817 offsets[i] = bplist_buff->len;
778 818
779 switch (data->type) { 819 switch (data->type) {
780 case PLIST_BOOLEAN: 820 case PLIST_BOOLEAN:
@@ -830,7 +870,6 @@ void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
830 } 870 }
831 871
832 //experimental pad to reflect apple's files 872 //experimental pad to reflect apple's files
833 uint8_t pad[6] = { 0, 0, 0, 0, 0, 0 };
834 g_byte_array_append(bplist_buff, pad, 6); 873 g_byte_array_append(bplist_buff, pad, 6);
835 874
836 //setup trailer 875 //setup trailer
@@ -838,7 +877,6 @@ void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
838 root_object = GUINT64_FROM_BE(root_object); 877 root_object = GUINT64_FROM_BE(root_object);
839 offset_table_index = GUINT64_FROM_BE(offset_table_index); 878 offset_table_index = GUINT64_FROM_BE(offset_table_index);
840 879
841 uint8_t trailer[BPLIST_TRL_SIZE];
842 memcpy(trailer + BPLIST_TRL_OFFSIZE_IDX, &offset_size, sizeof(uint8_t)); 880 memcpy(trailer + BPLIST_TRL_OFFSIZE_IDX, &offset_size, sizeof(uint8_t));
843 memcpy(trailer + BPLIST_TRL_PARMSIZE_IDX, &dict_param_size, sizeof(uint8_t)); 881 memcpy(trailer + BPLIST_TRL_PARMSIZE_IDX, &dict_param_size, sizeof(uint8_t));
844 memcpy(trailer + BPLIST_TRL_NUMOBJ_IDX, &num_objects, sizeof(uint64_t)); 882 memcpy(trailer + BPLIST_TRL_NUMOBJ_IDX, &num_objects, sizeof(uint64_t));
@@ -853,4 +891,5 @@ void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
853 *length = bplist_buff->len; 891 *length = bplist_buff->len;
854 892
855 g_byte_array_free(bplist_buff, TRUE); 893 g_byte_array_free(bplist_buff, TRUE);
894 free(offsets);
856} 895}