summaryrefslogtreecommitdiffstats
path: root/src/plist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plist.c')
-rw-r--r--src/plist.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/plist.c b/src/plist.c
new file mode 100644
index 0000000..cbd6302
--- /dev/null
+++ b/src/plist.c
@@ -0,0 +1,91 @@
+/*
+ * plist.c
+ * Builds plist XML structures.
+ * Written by FxChiP
+ */
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <string.h>
+#include "plist.h"
+
+const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n\
+<plist version=\"1.0\">\n\
+</plist>\0";
+
+xmlDocPtr new_plist() {
+ char *plist = strdup(plist_base);
+ xmlDocPtr plist_xml = xmlReadMemory(plist, strlen(plist), NULL, NULL, 0);
+ if (!plist_xml) return NULL;
+ free(plist);
+ return plist_xml;
+}
+
+void free_plist(xmlDocPtr plist) {
+ if (!plist) return;
+ xmlFreeDoc(plist);
+}
+
+xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode *to_node, int depth) {
+ if (!plist) return NULL;
+ int i = 0;
+ xmlNode *child;
+ if (!to_node) to_node = xmlDocGetRootElement(plist);
+ for (i = 0; i < depth; i++) {
+ xmlNodeAddContent(to_node, "\t");
+ }
+ child = xmlNewChild(to_node, NULL, name, content);
+ xmlNodeAddContent(to_node, "\n");
+ return child;
+}
+
+xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) {
+ xmlNode *keyPtr;
+ keyPtr = add_child_to_plist(plist, "key", key, dict, depth);
+ add_child_to_plist(plist, "string", value, dict, depth);
+ return keyPtr;
+}
+
+char **read_dict_element_strings(xmlNode *dict) {
+ // reads a set of keys and strings into an array where each even number is a key and odd numbers are values.
+ // if the odd number is \0, that's the end of the list.
+ char **return_me = NULL, **old = NULL;
+ int current_length = 0;
+ int current_pos = 0;
+ xmlNode *dict_walker;
+
+ for (dict_walker = dict->children; dict_walker; dict_walker = dict_walker->next) {
+ if (!xmlStrcmp(dict_walker->name, "key")) {
+ current_length += 2;
+ old = return_me;
+ return_me = realloc(return_me, sizeof(char*) * current_length);
+ if (!return_me) {
+ free(old);
+ return NULL;
+ }
+ return_me[current_pos++] = xmlNodeGetContent(dict_walker);
+ return_me[current_pos++] = xmlNodeGetContent(dict_walker->next->next);
+ }
+ }
+
+ // one last thing...
+ old = return_me;
+ return_me = realloc(return_me, sizeof(char*) * current_length+1);
+ return_me[current_pos] = strdup("");
+
+ return return_me;
+}
+
+void free_dictionary(char **dictionary) {
+ if (!dictionary) return;
+ int i = 0;
+
+ for (i = 0; strcmp(dictionary[i], ""); i++) {
+ free(dictionary[i]);
+ }
+
+ free(dictionary[i]);
+ free(dictionary);
+}
+