diff options
Diffstat (limited to 'src/xplist.c')
-rw-r--r-- | src/xplist.c | 312 |
1 files changed, 0 insertions, 312 deletions
diff --git a/src/xplist.c b/src/xplist.c deleted file mode 100644 index 2d650b4..0000000 --- a/src/xplist.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * plist.c - * XML plist implementation - * - * Copyright (c) 2008 Jonathan Beck All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include <string.h> -#include <assert.h> -#include "utils.h" -#include "plist.h" -#include <wchar.h> -#include <stdlib.h> -#include <stdio.h> - - -#include <libxml/parser.h> -#include <libxml/tree.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"; - - -/** 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; - int len = strlen(buf); - 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++) - new_buf[i * colw + 1 + j] = '\t'; - 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; -} - - - -struct xml_node { - xmlNodePtr xml; - uint32_t depth; -}; - -/** Creates a new plist XML document. - * - * @return The plist XML document. - */ -xmlDocPtr new_xml_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); -} - -void node_to_xml(GNode * node, gpointer xml_struct) -{ - if (!node) - return; - - struct xml_node *xstruct = (struct xml_node *) xml_struct; - struct plist_data *node_data = (struct plist_data *) node->data; - - xmlNodePtr child_node = NULL; - char isStruct = FALSE; - - gchar *tag = NULL; - gchar *val = NULL; - - switch (node_data->type) { - case PLIST_BOOLEAN: - { - if (node_data->boolval) - tag = "true"; - else - tag = "false"; - } - break; - - case PLIST_UINT: - tag = "integer"; - val = g_strdup_printf("%lu", (long unsigned int) node_data->intval); - break; - - case PLIST_REAL: - tag = "real"; - val = g_strdup_printf("%Lf", (long double) node_data->realval); - break; - - case PLIST_STRING: - tag = "string"; - val = g_strdup(node_data->strval); - break; - - case PLIST_UNICODE: - tag = "string"; - val = g_strdup((gchar *) node_data->unicodeval); - break; - - case PLIST_KEY: - tag = "key"; - val = g_strdup((gchar *) node_data->strval); - break; - - case PLIST_DATA: - tag = "data"; - gchar *valtmp = g_base64_encode(node_data->buff, node_data->length); - val = format_string(valtmp, 60, xstruct->depth); - g_free(valtmp); - break; - case PLIST_ARRAY: - tag = "array"; - isStruct = TRUE; - break; - case PLIST_DICT: - tag = "dict"; - isStruct = TRUE; - break; - case PLIST_DATE: //TODO : handle date tag - default: - break; - } - - int i = 0; - for (i = 0; i < xstruct->depth; i++) { - xmlNodeAddContent(xstruct->xml, "\t"); - } - child_node = xmlNewChild(xstruct->xml, NULL, tag, val); - xmlNodeAddContent(xstruct->xml, "\n"); - g_free(val); - - //add return for structured types - if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT || node_data->type == PLIST_DATA) - xmlNodeAddContent(child_node, "\n"); - - if (isStruct) { - struct xml_node child = { child_node, xstruct->depth + 1 }; - g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, &child); - } - //fix indent for structured types - if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT || node_data->type == PLIST_DATA) { - - for (i = 0; i < xstruct->depth; i++) { - xmlNodeAddContent(child_node, "\t"); - } - } - - return; -} - -void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node) -{ - xmlNodePtr node = NULL; - - for (node = xml_node->children; node; node = node->next) { - - while (node && !xmlStrcmp(node->name, "text")) - node = node->next; - if (!node) - break; - - struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); - GNode *subnode = g_node_new(data); - if (*plist_node) - g_node_append(*plist_node, subnode); - else - *plist_node = subnode; - - if (!xmlStrcmp(node->name, "true")) { - data->boolval = 1; - data->type = PLIST_BOOLEAN; - continue; - } - - if (!xmlStrcmp(node->name, "false")) { - data->boolval = 0; - data->type = PLIST_BOOLEAN; - continue; - } - - if (!xmlStrcmp(node->name, "integer")) { - char *strval = xmlNodeGetContent(node); - data->intval = g_ascii_strtoull(strval, NULL, 0); - data->type = PLIST_UINT; - continue; - } - - if (!xmlStrcmp(node->name, "real")) { - char *strval = xmlNodeGetContent(node); - data->realval = atof(strval); - data->type = PLIST_REAL; - continue; - } - - if (!xmlStrcmp(node->name, "date")) - continue; //TODO : handle date tag - - if (!xmlStrcmp(node->name, "string")) { - data->strval = strdup(xmlNodeGetContent(node)); - data->type = PLIST_STRING; - continue; - } - - if (!xmlStrcmp(node->name, "key")) { - data->strval = strdup(xmlNodeGetContent(node)); - data->type = PLIST_KEY; - continue; - } - - if (!xmlStrcmp(node->name, "data")) { - gsize size = 0; - data->buff = g_base64_decode(xmlNodeGetContent(node), &size); - data->length = size; - data->type = PLIST_DATA; - continue; - } - - if (!xmlStrcmp(node->name, "array")) { - data->type = PLIST_ARRAY; - xml_to_node(node, &subnode); - continue; - } - - if (!xmlStrcmp(node->name, "dict")) { - data->type = PLIST_DICT; - xml_to_node(node, &subnode); - continue; - } - } -} - -void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) -{ - if (!plist || !plist_xml || *plist_xml) - return; - xmlDocPtr plist_doc = new_xml_plist(); - xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); - struct xml_node root = { root_node, 0 }; - - node_to_xml(plist, &root); - - xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, length); -} - -void xml_to_plist(const char *plist_xml, uint32_t length, plist_t * plist) -{ - xmlDocPtr plist_doc = xmlReadMemory(plist_xml, length, NULL, NULL, 0); - xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); - - xml_to_node(root_node, plist); -} |