summaryrefslogtreecommitdiffstats
path: root/src/plist.c
blob: cbd6302949ad805616509748171edd12b6e87aee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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);
}