summaryrefslogtreecommitdiffstats
path: root/src/plist.c
diff options
context:
space:
mode:
authorGravatar Matt Colyer2008-08-12 09:32:57 -0700
committerGravatar Matt Colyer2008-08-12 09:32:57 -0700
commit9fbadfad2af22767cce6a620a1f5b91f16479e05 (patch)
tree5cb01c51bc2dd5a232e22f91ffe223a28cbeff1d /src/plist.c
parentbb74e8fd0041132379d525030ed277b49f972494 (diff)
downloadlibimobiledevice-9fbadfad2af22767cce6a620a1f5b91f16479e05.tar.gz
libimobiledevice-9fbadfad2af22767cce6a620a1f5b91f16479e05.tar.bz2
Cleaned up plist.c, added doxygen docs.
Diffstat (limited to 'src/plist.c')
-rw-r--r--src/plist.c106
1 files changed, 99 insertions, 7 deletions
diff --git a/src/plist.c b/src/plist.c
index 4d4fce4..c86e166 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -22,6 +22,7 @@
22#include <libxml/parser.h> 22#include <libxml/parser.h>
23#include <libxml/tree.h> 23#include <libxml/tree.h>
24#include <string.h> 24#include <string.h>
25#include <assert.h>
25#include "plist.h" 26#include "plist.h"
26 27
27const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\ 28const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
@@ -29,15 +30,29 @@ const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
29<plist version=\"1.0\">\n\ 30<plist version=\"1.0\">\n\
30</plist>\0"; 31</plist>\0";
31 32
33/** Formats a block of text to be a given indentation and width.
34 *
35 * The total width of the return string will be depth + cols.
36 *
37 * @param buf The string to format.
38 * @param cols The number of text columns for returned block of text.
39 * @param depth The number of tabs to indent the returned block of text.
40 *
41 * @return The formatted string.
42 */
32char* format_string(const char* buf, int cols, int depth) 43char* format_string(const char* buf, int cols, int depth)
33{ 44{
34 int colw = depth + cols + 1; //new buf cols width 45 int colw = depth + cols + 1;
35 int len = strlen(buf); 46 int len = strlen(buf);
36 //int nlines = ceil((float)len / (float)cols);
37 int nlines = len / cols + 1; 47 int nlines = len / cols + 1;
38 char* new_buf = (char*)malloc(nlines * colw + depth + 1); 48 char* new_buf = (char*)malloc(nlines * colw + depth + 1);
39 int i = 0; 49 int i = 0;
40 int j = 0; 50 int j = 0;
51
52 assert(cols > 0);
53 assert(depth > 0);
54
55 // Inserts new lines and tabs at appropriate locations
41 for (i = 0; i < nlines; i++){ 56 for (i = 0; i < nlines; i++){
42 new_buf[i * colw] = '\n'; 57 new_buf[i * colw] = '\n';
43 for (j = 0; j < depth; j++) 58 for (j = 0; j < depth; j++)
@@ -45,62 +60,137 @@ char* format_string(const char* buf, int cols, int depth)
45 memcpy(new_buf + i * colw + 1 + depth, buf + i * cols, cols); 60 memcpy(new_buf + i * colw + 1 + depth, buf + i * cols, cols);
46 } 61 }
47 new_buf[len+(1+depth)*nlines] = '\n'; 62 new_buf[len+(1+depth)*nlines] = '\n';
63
64 // Inserts final row of indentation and termination character
48 for (j = 0; j < depth; j++) 65 for (j = 0; j < depth; j++)
49 new_buf[len+(1+depth)*nlines + 1 + j] = '\t'; 66 new_buf[len+(1+depth)*nlines + 1 + j] = '\t';
50 new_buf[len+(1+depth)*nlines+depth+1] = '\0'; 67 new_buf[len+(1+depth)*nlines+depth+1] = '\0';
68
51 return new_buf; 69 return new_buf;
52} 70}
53 71
72/** Creates a new plist XML document.
73 *
74 * @return The plist XML document.
75 */
54xmlDocPtr new_plist() { 76xmlDocPtr new_plist() {
55 char *plist = strdup(plist_base); 77 char *plist = strdup(plist_base);
56 xmlDocPtr plist_xml = xmlReadMemory(plist, strlen(plist), NULL, NULL, 0); 78 xmlDocPtr plist_xml = xmlReadMemory(plist, strlen(plist), NULL, NULL, 0);
79
57 if (!plist_xml) return NULL; 80 if (!plist_xml) return NULL;
81
58 free(plist); 82 free(plist);
83
59 return plist_xml; 84 return plist_xml;
60} 85}
61 86
87/** Destroys a previously created XML document.
88 *
89 * @param plist The XML document to destroy.
90 */
62void free_plist(xmlDocPtr plist) { 91void free_plist(xmlDocPtr plist) {
63 if (!plist) return; 92 if (!plist) return;
93
64 xmlFreeDoc(plist); 94 xmlFreeDoc(plist);
65} 95}
66 96
97/** Adds a new node as a child to a given node.
98 *
99 * This is a lower level function so you probably want to use
100 * add_key_str_dict_element, add_key_dict_node or add_key_data_dict_element
101 * instead.
102 *
103 * @param plist The plist XML document to which the to_node belongs.
104 * @param name The name of the new node.
105 * @param content The string containing the text node of the new node.
106 * @param to_node The node to attach the child node to. If none is given, the
107 * root node of the given document is used.
108 * @param depth The number of tabs to indent the new node.
109 *
110 * @return The newly created node.
111 */
67xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode *to_node, int depth) { 112xmlNode *add_child_to_plist(xmlDocPtr plist, const char *name, const char *content, xmlNode *to_node, int depth) {
68 if (!plist) return NULL;
69 int i = 0; 113 int i = 0;
70 xmlNode *child; 114 xmlNode *child;
115
116 if (!plist) return NULL;
117 assert(depth > 0);
71 if (!to_node) to_node = xmlDocGetRootElement(plist); 118 if (!to_node) to_node = xmlDocGetRootElement(plist);
119
72 for (i = 0; i < depth; i++) { 120 for (i = 0; i < depth; i++) {
73 xmlNodeAddContent(to_node, "\t"); 121 xmlNodeAddContent(to_node, "\t");
74 } 122 }
75 child = xmlNewChild(to_node, NULL, name, content); 123 child = xmlNewChild(to_node, NULL, name, content);
76 xmlNodeAddContent(to_node, "\n"); 124 xmlNodeAddContent(to_node, "\n");
125
77 return child; 126 return child;
78} 127}
79 128
129/** Adds a string key-pair to a plist XML document.
130 *
131 * @param plist The plist XML document to add the new node to.
132 * @param dict The dictionary node within the plist XML document to add the new node to.
133 * @param key The string containing the key value.
134 * @param value The string containing the value.
135 * @param depth The number of tabs to indent the new node.
136 *
137 * @return The newly created key node.
138 */
80xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) { 139xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) {
81 xmlNode *keyPtr; 140 xmlNode *keyPtr;
141
82 keyPtr = add_child_to_plist(plist, "key", key, dict, depth); 142 keyPtr = add_child_to_plist(plist, "key", key, dict, depth);
83 add_child_to_plist(plist, "string", value, dict, depth); 143 add_child_to_plist(plist, "string", value, dict, depth);
144
84 return keyPtr; 145 return keyPtr;
85} 146}
86 147
148/** Adds a new dictionary key-pair to a plist XML document.
149 *
150 * @param plist The plist XML document to add the new node to.
151 * @param dict The dictionary node within the plist XML document to add the new node to.
152 * @param key The string containing the key value.
153 * @param value The string containing the value.
154 * @param depth The number of tabs to indent the new node.
155 *
156 * @return The newly created dict node.
157 */
87xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) { 158xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) {
88 xmlNode *child; 159 xmlNode *child;
160
89 add_child_to_plist(plist, "key", key, dict, depth); 161 add_child_to_plist(plist, "key", key, dict, depth);
90 child = add_child_to_plist(plist, "dict", value, dict, depth); 162 child = add_child_to_plist(plist, "dict", value, dict, depth);
163
91 return child; 164 return child;
92} 165}
93 166
167/** Adds a new data dictionary key-pair to a plist XML document.
168 *
169 * @param plist The plist XML document to add the new node to.
170 * @param dict The dictionary node within the plist XML document to add the new node to.
171 * @param key The string containing the key value.
172 * @param value The string containing the value.
173 * @param depth The number of tabs to indent the new node.
174 *
175 * @return The newly created key node.
176 */
94xmlNode *add_key_data_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) { 177xmlNode *add_key_data_dict_element(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) {
95 xmlNode *keyPtr; 178 xmlNode *keyPtr;
179
96 keyPtr = add_child_to_plist(plist, "key", key, dict, depth); 180 keyPtr = add_child_to_plist(plist, "key", key, dict, depth);
97 add_child_to_plist(plist, "data", format_string(value, 60, depth), dict, depth); 181 add_child_to_plist(plist, "data", format_string(value, 60, depth), dict, depth);
182
98 return keyPtr; 183 return keyPtr;
99} 184}
100 185
186/** Reads a set of keys and strings into an array from a plist XML document.
187 *
188 * @param dict The root XMLNode of a plist XML document to be read.
189 *
190 * @return An array where each even number is a key and the odd numbers are
191 * values. If the odd number is \0, that's the end of the list.
192 */
101char **read_dict_element_strings(xmlNode *dict) { 193char **read_dict_element_strings(xmlNode *dict) {
102 // reads a set of keys and strings into an array where each even number is a key and odd numbers are values.
103 // if the odd number is \0, that's the end of the list.
104 char **return_me = NULL, **old = NULL; 194 char **return_me = NULL, **old = NULL;
105 int current_length = 0; 195 int current_length = 0;
106 int current_pos = 0; 196 int current_pos = 0;
@@ -120,7 +210,6 @@ char **read_dict_element_strings(xmlNode *dict) {
120 } 210 }
121 } 211 }
122 212
123 // one last thing...
124 old = return_me; 213 old = return_me;
125 return_me = realloc(return_me, sizeof(char*) * (current_length+1)); 214 return_me = realloc(return_me, sizeof(char*) * (current_length+1));
126 return_me[current_pos] = strdup(""); 215 return_me[current_pos] = strdup("");
@@ -128,10 +217,13 @@ char **read_dict_element_strings(xmlNode *dict) {
128 return return_me; 217 return return_me;
129} 218}
130 219
220/** Destroys a dictionary as returned by read_dict_element_strings
221 */
131void free_dictionary(char **dictionary) { 222void free_dictionary(char **dictionary) {
132 if (!dictionary) return;
133 int i = 0; 223 int i = 0;
134 224
225 if (!dictionary) return;
226
135 for (i = 0; strcmp(dictionary[i], ""); i++) { 227 for (i = 0; strcmp(dictionary[i], ""); i++) {
136 free(dictionary[i]); 228 free(dictionary[i]);
137 } 229 }