diff options
Diffstat (limited to 'plist.c')
| -rw-r--r-- | plist.c | 91 |
1 files changed, 91 insertions, 0 deletions
| @@ -0,0 +1,91 @@ | |||
| 1 | /* | ||
| 2 | * plist.c | ||
| 3 | * Builds plist XML structures. | ||
| 4 | * Written by FxChiP | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <libxml/parser.h> | ||
| 8 | #include <libxml/tree.h> | ||
| 9 | #include <string.h> | ||
| 10 | #include "plist.h" | ||
| 11 | |||
| 12 | const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ | ||
| 13 | <!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n\ | ||
| 14 | <plist version=\"1.0\">\n\ | ||
| 15 | </plist>\0"; | ||
| 16 | |||
| 17 | xmlDocPtr new_plist() { | ||
| 18 | char *plist = strdup(plist_base); | ||
| 19 | xmlDocPtr plist_xml = xmlReadMemory(plist, strlen(plist), NULL, NULL, 0); | ||
| 20 | if (!plist_xml) return NULL; | ||
| 21 | free(plist); | ||
| 22 | return plist_xml; | ||
| 23 | } | ||
| 24 | |||
| 25 | void free_plist(xmlDocPtr plist) { | ||
| 26 | if (!plist) return; | ||
| 27 | xmlFreeDoc(plist); | ||
| 28 | } | ||
| 29 | |||
| 30 | xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode *to_node, int depth) { | ||
| 31 | if (!plist) return NULL; | ||
| 32 | int i = 0; | ||
| 33 | xmlNode *child; | ||
| 34 | if (!to_node) to_node = xmlDocGetRootElement(plist); | ||
| 35 | for (i = 0; i < depth; i++) { | ||
| 36 | xmlNodeAddContent(to_node, "\t"); | ||
| 37 | } | ||
| 38 | child = xmlNewChild(to_node, NULL, name, content); | ||
| 39 | xmlNodeAddContent(to_node, "\n"); | ||
| 40 | return child; | ||
| 41 | } | ||
| 42 | |||
| 43 | xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) { | ||
| 44 | xmlNode *keyPtr; | ||
| 45 | keyPtr = add_child_to_plist(plist, "key", key, dict, depth); | ||
| 46 | add_child_to_plist(plist, "string", value, dict, depth); | ||
| 47 | return keyPtr; | ||
| 48 | } | ||
| 49 | |||
| 50 | char **read_dict_element_strings(xmlNode *dict) { | ||
| 51 | // reads a set of keys and strings into an array where each even number is a key and odd numbers are values. | ||
| 52 | // if the odd number is \0, that's the end of the list. | ||
| 53 | char **return_me = NULL, **old = NULL; | ||
| 54 | int current_length = 0; | ||
| 55 | int current_pos = 0; | ||
| 56 | xmlNode *dict_walker; | ||
| 57 | |||
| 58 | for (dict_walker = dict->children; dict_walker; dict_walker = dict_walker->next) { | ||
| 59 | if (!xmlStrcmp(dict_walker->name, "key")) { | ||
| 60 | current_length += 2; | ||
| 61 | old = return_me; | ||
| 62 | return_me = realloc(return_me, sizeof(char*) * current_length); | ||
| 63 | if (!return_me) { | ||
| 64 | free(old); | ||
| 65 | return NULL; | ||
| 66 | } | ||
| 67 | return_me[current_pos++] = xmlNodeGetContent(dict_walker); | ||
| 68 | return_me[current_pos++] = xmlNodeGetContent(dict_walker->next->next); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | // one last thing... | ||
| 73 | old = return_me; | ||
| 74 | return_me = realloc(return_me, sizeof(char*) * current_length+1); | ||
| 75 | return_me[current_pos] = strdup(""); | ||
| 76 | |||
| 77 | return return_me; | ||
| 78 | } | ||
| 79 | |||
| 80 | void free_dictionary(char **dictionary) { | ||
| 81 | if (!dictionary) return; | ||
| 82 | int i = 0; | ||
| 83 | |||
| 84 | for (i = 0; strcmp(dictionary[i], ""); i++) { | ||
| 85 | free(dictionary[i]); | ||
| 86 | } | ||
| 87 | |||
| 88 | free(dictionary[i]); | ||
| 89 | free(dictionary); | ||
| 90 | } | ||
| 91 | |||
