diff options
| author | 2008-11-28 23:19:17 +0100 | |
|---|---|---|
| committer | 2008-11-28 23:19:17 +0100 | |
| commit | 5811f92943fa81b6266e0b57d95824d1efa17120 (patch) | |
| tree | a330212fc6dab12918d304727657b863bebc0a5c | |
| parent | aed2c025f6e47dc769675e564cc574adc496a88a (diff) | |
| download | libimobiledevice-5811f92943fa81b6266e0b57d95824d1efa17120.tar.gz libimobiledevice-5811f92943fa81b6266e0b57d95824d1efa17120.tar.bz2 | |
Start an abstraction of xml and binary plist
| -rw-r--r-- | src/plist.c | 279 | ||||
| -rw-r--r-- | src/plist.h | 35 |
2 files changed, 314 insertions, 0 deletions
diff --git a/src/plist.c b/src/plist.c index 7a09b4d..1553c1c 100644 --- a/src/plist.c +++ b/src/plist.c | |||
| @@ -536,3 +536,282 @@ bplist_node *parse_nodes(const char *bpbuffer, uint32_t bplength, uint32_t * pos | |||
| 536 | root_node = nodeslist[root_object]; | 536 | root_node = nodeslist[root_object]; |
| 537 | return root_node; | 537 | return root_node; |
| 538 | } | 538 | } |
| 539 | |||
| 540 | struct plist_data { | ||
| 541 | union { | ||
| 542 | char boolval; | ||
| 543 | uint8_t intval8; | ||
| 544 | uint16_t intval16; | ||
| 545 | uint32_t intval32; | ||
| 546 | uint64_t intval64; | ||
| 547 | float realval32; | ||
| 548 | double realval64; | ||
| 549 | char *strval; | ||
| 550 | wchar_t *unicodeval; | ||
| 551 | char *buff; | ||
| 552 | }; | ||
| 553 | int index; | ||
| 554 | plist_type type; | ||
| 555 | }; | ||
| 556 | |||
| 557 | void plist_new_plist(plist_t* plist) | ||
| 558 | { | ||
| 559 | if (*plist != NULL) return; | ||
| 560 | struct plist_data* data = (struct plist_data*)calloc(sizeof(struct plist_data), 1); | ||
| 561 | data->type = PLIST_PLIST; | ||
| 562 | *plist = g_node_new (data); | ||
| 563 | } | ||
| 564 | |||
| 565 | void plist_new_dict_in_plist(plist_t plist, dict_t* dict) | ||
| 566 | { | ||
| 567 | if (!plist || *dict) return; | ||
| 568 | |||
| 569 | struct plist_data* data = (struct plist_data*)calloc(sizeof(struct plist_data), 1); | ||
| 570 | data->type = PLIST_DICT; | ||
| 571 | *dict = g_node_new (data); | ||
| 572 | g_node_append(plist, *dict); | ||
| 573 | } | ||
| 574 | |||
| 575 | void plist_new_array_in_plist(plist_t plist, int length, plist_type type, void** values, array_t* array) | ||
| 576 | { | ||
| 577 | } | ||
| 578 | |||
| 579 | void plist_add_dict_element(dict_t dict, char* key, plist_type type, void* value) | ||
| 580 | { | ||
| 581 | if (!dict || !key || !value) return; | ||
| 582 | |||
| 583 | struct plist_data* data = (struct plist_data*)calloc(sizeof(struct plist_data), 1); | ||
| 584 | data->type = PLIST_KEY; | ||
| 585 | data->strval = strdup(key); | ||
| 586 | GNode* keynode = g_node_new (data); | ||
| 587 | g_node_append(dict, keynode); | ||
| 588 | |||
| 589 | //now handle value | ||
| 590 | struct plist_data* val = (struct plist_data*)calloc(sizeof(struct plist_data), 1); | ||
| 591 | val->type = type; | ||
| 592 | |||
| 593 | switch (type) { | ||
| 594 | case PLIST_BOOLEAN : val->boolval = *((char*)value); break; | ||
| 595 | case PLIST_UINT8 : val->intval8 = *((uint8_t*)value); break; | ||
| 596 | case PLIST_UINT16 : val->intval16 = *((uint16_t*)value); break; | ||
| 597 | case PLIST_UINT32 : val->intval32 = *((uint32_t*)value); break; | ||
| 598 | case PLIST_UINT64 : val->intval64 = *((uint64_t*)value); break; | ||
| 599 | case PLIST_FLOAT32 : val->realval32 = *((float*)value); break; | ||
| 600 | case PLIST_FLOAT64 : val->realval64 = *((double*)value); break; | ||
| 601 | case PLIST_STRING : val->strval = strdup((char*) value); break; | ||
| 602 | case PLIST_UNICODE : val->unicodeval = wcsdup((wchar_t*) value); break; | ||
| 603 | case PLIST_DATA : val->buff = strdup((char*) value); break; | ||
| 604 | case PLIST_ARRAY : | ||
| 605 | case PLIST_DICT : | ||
| 606 | case PLIST_DATE : | ||
| 607 | case PLIST_PLIST : | ||
| 608 | default: | ||
| 609 | break; | ||
| 610 | } | ||
| 611 | GNode* valnode = g_node_new (val); | ||
| 612 | g_node_append(dict, valnode); | ||
| 613 | } | ||
| 614 | |||
| 615 | void plist_free(plist_t plist) | ||
| 616 | { | ||
| 617 | g_node_destroy(plist); | ||
| 618 | } | ||
| 619 | |||
| 620 | void node_to_xml (GNode *node, gpointer data) | ||
| 621 | { | ||
| 622 | if (!node) return; | ||
| 623 | |||
| 624 | struct plist_data* node_data = (struct plist_data*)node->data; | ||
| 625 | |||
| 626 | xmlNodePtr child_node = NULL; | ||
| 627 | char isStruct = FALSE; | ||
| 628 | |||
| 629 | gchar* tag = NULL; | ||
| 630 | gchar* val = NULL; | ||
| 631 | |||
| 632 | switch (node_data->type) { | ||
| 633 | case PLIST_BOOLEAN : | ||
| 634 | { | ||
| 635 | if (node_data->boolval) | ||
| 636 | tag = "true"; | ||
| 637 | else | ||
| 638 | tag = "false"; | ||
| 639 | } | ||
| 640 | break; | ||
| 641 | |||
| 642 | case PLIST_UINT8 : | ||
| 643 | tag = "integer"; | ||
| 644 | val = g_strdup_printf("%u", node_data->intval8); | ||
| 645 | break; | ||
| 646 | |||
| 647 | case PLIST_UINT16 : | ||
| 648 | tag = "integer"; | ||
| 649 | val = g_strdup_printf("%u", node_data->intval16); | ||
| 650 | break; | ||
| 651 | |||
| 652 | case PLIST_UINT32 : | ||
| 653 | tag = "integer"; | ||
| 654 | val = g_strdup_printf("%u", node_data->intval32); | ||
| 655 | break; | ||
| 656 | |||
| 657 | case PLIST_UINT64 : | ||
| 658 | tag = "integer"; | ||
| 659 | val = g_strdup_printf("%lu", (long unsigned int)node_data->intval64); | ||
| 660 | break; | ||
| 661 | |||
| 662 | case PLIST_FLOAT32 : | ||
| 663 | tag = "real"; | ||
| 664 | val = g_strdup_printf("%f", node_data->realval32); | ||
| 665 | break; | ||
| 666 | |||
| 667 | case PLIST_FLOAT64 : | ||
| 668 | tag = "real"; | ||
| 669 | val = g_strdup_printf("%Lf", (long double)node_data->intval64); | ||
| 670 | break; | ||
| 671 | |||
| 672 | case PLIST_STRING : | ||
| 673 | tag = "string"; | ||
| 674 | val = g_strdup(node_data->strval); | ||
| 675 | break; | ||
| 676 | |||
| 677 | case PLIST_UNICODE : | ||
| 678 | tag = "string"; | ||
| 679 | val = g_strdup((gchar*)node_data->unicodeval); | ||
| 680 | break; | ||
| 681 | |||
| 682 | case PLIST_KEY : | ||
| 683 | tag = "key"; | ||
| 684 | val = g_strdup((gchar*)node_data->strval); | ||
| 685 | break; | ||
| 686 | |||
| 687 | case PLIST_DATA : | ||
| 688 | tag = "data"; | ||
| 689 | val = format_string(node_data->buff, 60, 0); | ||
| 690 | break; | ||
| 691 | case PLIST_ARRAY : | ||
| 692 | tag = "array"; | ||
| 693 | isStruct = TRUE; | ||
| 694 | break; | ||
| 695 | case PLIST_DICT : | ||
| 696 | tag = "dict"; | ||
| 697 | isStruct = TRUE; | ||
| 698 | break; | ||
| 699 | case PLIST_PLIST : | ||
| 700 | tag = "plist"; | ||
| 701 | isStruct = TRUE; | ||
| 702 | break; | ||
| 703 | case PLIST_DATE : //TODO : handle date tag | ||
| 704 | default: | ||
| 705 | break; | ||
| 706 | } | ||
| 707 | return; | ||
| 708 | |||
| 709 | child_node = xmlNewChild(data, NULL, tag, val); | ||
| 710 | gfree(val); | ||
| 711 | |||
| 712 | if (isStruct) | ||
| 713 | g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, child_node); | ||
| 714 | |||
| 715 | return; | ||
| 716 | } | ||
| 717 | |||
| 718 | void xml_to_node (xmlNodePtr xml_node, GNode *plist_node) | ||
| 719 | { | ||
| 720 | xmlNodePtr node = NULL; | ||
| 721 | struct plist_data* data = (struct plist_data*)calloc(sizeof(struct plist_data), 1); | ||
| 722 | GNode* subnode = g_node_new (data); | ||
| 723 | g_node_append(plist_node, subnode); | ||
| 724 | |||
| 725 | for (node = xml_node->children; node; node = node->next) { | ||
| 726 | |||
| 727 | if (!xmlStrcmp(node->name, "true")) { | ||
| 728 | data->boolval = 1; | ||
| 729 | data->type = PLIST_BOOLEAN; | ||
| 730 | continue; | ||
| 731 | } | ||
| 732 | |||
| 733 | if (!xmlStrcmp(node->name, "false")) { | ||
| 734 | data->boolval = 0; | ||
| 735 | data->type = PLIST_BOOLEAN; | ||
| 736 | continue; | ||
| 737 | } | ||
| 738 | |||
| 739 | if (!xmlStrcmp(node->name, "integer")) { | ||
| 740 | char* strval = xmlNodeGetContent(node); | ||
| 741 | data->intval64 = atoi(strval); | ||
| 742 | data->type = PLIST_UINT64; | ||
| 743 | continue; | ||
| 744 | } | ||
| 745 | |||
| 746 | if (!xmlStrcmp(node->name, "real")){ | ||
| 747 | char* strval = xmlNodeGetContent(node); | ||
| 748 | data->realval64 = atof(strval); | ||
| 749 | data->type = PLIST_FLOAT64; | ||
| 750 | continue; | ||
| 751 | } | ||
| 752 | |||
| 753 | if (!xmlStrcmp(node->name, "date")) | ||
| 754 | continue;//TODO : handle date tag | ||
| 755 | |||
| 756 | if (!xmlStrcmp(node->name, "string")) { | ||
| 757 | data->strval = strdup(xmlNodeGetContent(node)); | ||
| 758 | data->type = PLIST_STRING; | ||
| 759 | continue; | ||
| 760 | } | ||
| 761 | |||
| 762 | if (!xmlStrcmp(node->name, "key")) { | ||
| 763 | data->strval = strdup(xmlNodeGetContent(node)); | ||
| 764 | data->type = PLIST_KEY; | ||
| 765 | continue; | ||
| 766 | } | ||
| 767 | |||
| 768 | if (!xmlStrcmp(node->name, "data")) { | ||
| 769 | data->buff = strdup(xmlNodeGetContent(node)); | ||
| 770 | data->type = PLIST_DATA; | ||
| 771 | continue; | ||
| 772 | } | ||
| 773 | |||
| 774 | if (!xmlStrcmp(node->name, "array")) { | ||
| 775 | data->type = PLIST_ARRAY; | ||
| 776 | xml_to_node (node, subnode); | ||
| 777 | continue; | ||
| 778 | } | ||
| 779 | |||
| 780 | if (!xmlStrcmp(node->name, "dict")) { | ||
| 781 | data->type = PLIST_DICT; | ||
| 782 | xml_to_node (node, subnode); | ||
| 783 | continue; | ||
| 784 | } | ||
| 785 | } | ||
| 786 | } | ||
| 787 | |||
| 788 | void plist_to_xml(plist_t plist, char** plist_xml) | ||
| 789 | { | ||
| 790 | if (!plist || !plist_xml || *plist_xml) return; | ||
| 791 | xmlDocPtr plist_doc = new_plist(); | ||
| 792 | xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); | ||
| 793 | g_node_children_foreach(plist, G_TRAVERSE_ALL, node_to_xml, root_node); | ||
| 794 | int size = 0; | ||
| 795 | xmlDocDumpMemory (plist_doc, (xmlChar**)plist_xml, &size); | ||
| 796 | } | ||
| 797 | |||
| 798 | |||
| 799 | void plist_to_bin(plist_t plist, char** plist_bin) | ||
| 800 | { | ||
| 801 | } | ||
| 802 | |||
| 803 | void xml_to_plist(const char* plist_xml, plist_t* plist) | ||
| 804 | { | ||
| 805 | xmlDocPtr plist_doc = xmlReadMemory(plist_xml, strlen(plist_xml), NULL, NULL, 0); | ||
| 806 | xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); | ||
| 807 | |||
| 808 | struct plist_data* data = (struct plist_data*)calloc(sizeof(struct plist_data), 1); | ||
| 809 | *plist = g_node_new (data); | ||
| 810 | data->type = PLIST_PLIST; | ||
| 811 | xml_to_node (root_node, *plist); | ||
| 812 | |||
| 813 | } | ||
| 814 | |||
| 815 | void bin_to_plist(const char* plist_bin, plist_t* plist) | ||
| 816 | { | ||
| 817 | } | ||
diff --git a/src/plist.h b/src/plist.h index 5f31281..4586d6f 100644 --- a/src/plist.h +++ b/src/plist.h | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <sys/types.h> | 30 | #include <sys/types.h> |
| 31 | #include <sys/stat.h> | 31 | #include <sys/stat.h> |
| 32 | #include <unistd.h> | 32 | #include <unistd.h> |
| 33 | #include <glib.h> | ||
| 33 | 34 | ||
| 34 | char *format_string(const char *buf, int cols, int depth); | 35 | char *format_string(const char *buf, int cols, int depth); |
| 35 | xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth); | 36 | xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode * dict, const char *key, const char *value, int depth); |
| @@ -76,4 +77,38 @@ typedef struct _bplist_node { | |||
| 76 | 77 | ||
| 77 | bplist_node *parse_nodes(const char *bpbuffer, uint32_t bplength, uint32_t * position); | 78 | bplist_node *parse_nodes(const char *bpbuffer, uint32_t bplength, uint32_t * position); |
| 78 | 79 | ||
| 80 | typedef enum { | ||
| 81 | PLIST_BOOLEAN, | ||
| 82 | PLIST_UINT8, | ||
| 83 | PLIST_UINT16, | ||
| 84 | PLIST_UINT32, | ||
| 85 | PLIST_UINT64, | ||
| 86 | PLIST_FLOAT32, | ||
| 87 | PLIST_FLOAT64, | ||
| 88 | PLIST_STRING, | ||
| 89 | PLIST_UNICODE, | ||
| 90 | PLIST_ARRAY, | ||
| 91 | PLIST_DICT, | ||
| 92 | PLIST_DATE, | ||
| 93 | PLIST_DATA, | ||
| 94 | PLIST_PLIST, | ||
| 95 | PLIST_KEY, | ||
| 96 | } plist_type; | ||
| 97 | |||
| 98 | |||
| 99 | typedef GNode *plist_t; | ||
| 100 | typedef GNode *dict_t; | ||
| 101 | typedef GNode *array_t; | ||
| 102 | |||
| 103 | void plist_new_plist(plist_t* plist); | ||
| 104 | void plist_new_dict_in_plist(plist_t plist, dict_t* dict); | ||
| 105 | void plist_new_array_in_plist(plist_t plist, int length, plist_type type, void** values, array_t* array); | ||
| 106 | void plist_add_dict_element(dict_t dict, char* key, plist_type type, void* value); | ||
| 107 | void plist_free(plist_t plist); | ||
| 108 | |||
| 109 | void plist_to_xml(plist_t plist, char** plist_xml); | ||
| 110 | void plist_to_bin(plist_t plist, char** plist_bin); | ||
| 111 | |||
| 112 | void xml_to_plist(const char* plist_xml, plist_t* plist); | ||
| 113 | void bin_to_plist(const char* plist_bin, plist_t* plist); | ||
| 79 | #endif | 114 | #endif |
