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)
downloadlibplist-9fbadfad2af22767cce6a620a1f5b91f16479e05.tar.gz
libplist-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 @@
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <string.h>
+#include <assert.h>
#include "plist.h"
const 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\
<plist version=\"1.0\">\n\
</plist>\0";
+/** Formats a block of text to be a given indentation and width.
+ *
+ * The total width of the return string will be depth + cols.
+ *
+ * @param buf The string to format.
+ * @param cols The number of text columns for returned block of text.
+ * @param depth The number of tabs to indent the returned block of text.
+ *
+ * @return The formatted string.
+ */
char* format_string(const char* buf, int cols, int depth)
{
- int colw = depth + cols + 1; //new buf cols width
+ int colw = depth + cols + 1;
int len = strlen(buf);
- //int nlines = ceil((float)len / (float)cols);
int nlines = len / cols + 1;
char* new_buf = (char*)malloc(nlines * colw + depth + 1);
int i = 0;
int j = 0;
+
+ assert(cols > 0);
+ assert(depth > 0);
+
+ // Inserts new lines and tabs at appropriate locations
for (i = 0; i < nlines; i++){
new_buf[i * colw] = '\n';
for (j = 0; j < depth; j++)
@@ -45,62 +60,137 @@ char* format_string(const char* buf, int cols, int depth)
memcpy(new_buf + i * colw + 1 + depth, buf + i * cols, cols);
}
new_buf[len+(1+depth)*nlines] = '\n';
+
+ // Inserts final row of indentation and termination character
for (j = 0; j < depth; j++)
new_buf[len+(1+depth)*nlines + 1 + j] = '\t';
new_buf[len+(1+depth)*nlines+depth+1] = '\0';
+
return new_buf;
}
+/** Creates a new plist XML document.
+ *
+ * @return The plist XML document.
+ */
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;
}
+/** Destroys a previously created XML document.
+ *
+ * @param plist The XML document to destroy.
+ */
void free_plist(xmlDocPtr plist) {
if (!plist) return;
+
xmlFreeDoc(plist);
}
+/** Adds a new node as a child to a given node.
+ *
+ * This is a lower level function so you probably want to use
+ * add_key_str_dict_element, add_key_dict_node or add_key_data_dict_element
+ * instead.
+ *
+ * @param plist The plist XML document to which the to_node belongs.
+ * @param name The name of the new node.
+ * @param content The string containing the text node of the new node.
+ * @param to_node The node to attach the child node to. If none is given, the
+ * root node of the given document is used.
+ * @param depth The number of tabs to indent the new node.
+ *
+ * @return The newly created node.
+ */
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 (!plist) return NULL;
+ assert(depth > 0);
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;
}
+/** Adds a string key-pair to a plist XML document.
+ *
+ * @param plist The plist XML document to add the new node to.
+ * @param dict The dictionary node within the plist XML document to add the new node to.
+ * @param key The string containing the key value.
+ * @param value The string containing the value.
+ * @param depth The number of tabs to indent the new node.
+ *
+ * @return The newly created key node.
+ */
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;
}
+/** Adds a new dictionary key-pair to a plist XML document.
+ *
+ * @param plist The plist XML document to add the new node to.
+ * @param dict The dictionary node within the plist XML document to add the new node to.
+ * @param key The string containing the key value.
+ * @param value The string containing the value.
+ * @param depth The number of tabs to indent the new node.
+ *
+ * @return The newly created dict node.
+ */
xmlNode *add_key_dict_node(xmlDocPtr plist, xmlNode *dict, const char *key, const char *value, int depth) {
xmlNode *child;
+
add_child_to_plist(plist, "key", key, dict, depth);
child = add_child_to_plist(plist, "dict", value, dict, depth);
+
return child;
}
+/** Adds a new data dictionary key-pair to a plist XML document.
+ *
+ * @param plist The plist XML document to add the new node to.
+ * @param dict The dictionary node within the plist XML document to add the new node to.
+ * @param key The string containing the key value.
+ * @param value The string containing the value.
+ * @param depth The number of tabs to indent the new node.
+ *
+ * @return The newly created key node.
+ */
xmlNode *add_key_data_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, "data", format_string(value, 60, depth), dict, depth);
+
return keyPtr;
}
+/** Reads a set of keys and strings into an array from a plist XML document.
+ *
+ * @param dict The root XMLNode of a plist XML document to be read.
+ *
+ * @return An array where each even number is a key and the odd numbers are
+ * values. If the odd number is \0, that's the end of the list.
+ */
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;
@@ -120,7 +210,6 @@ char **read_dict_element_strings(xmlNode *dict) {
}
}
- // one last thing...
old = return_me;
return_me = realloc(return_me, sizeof(char*) * (current_length+1));
return_me[current_pos] = strdup("");
@@ -128,10 +217,13 @@ char **read_dict_element_strings(xmlNode *dict) {
return return_me;
}
+/** Destroys a dictionary as returned by read_dict_element_strings
+ */
void free_dictionary(char **dictionary) {
- if (!dictionary) return;
int i = 0;
+ if (!dictionary) return;
+
for (i = 0; strcmp(dictionary[i], ""); i++) {
free(dictionary[i]);
}