summaryrefslogtreecommitdiffstats
path: root/src/xplist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xplist.c')
-rw-r--r--src/xplist.c564
1 files changed, 292 insertions, 272 deletions
diff --git a/src/xplist.c b/src/xplist.c
index 490367e..15c9497 100644
--- a/src/xplist.c
+++ b/src/xplist.c
@@ -8,15 +8,15 @@
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -50,7 +50,7 @@ static const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
/** 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.
@@ -61,303 +61,323 @@ static const char *plist_base = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
*/
static gchar *format_string(const char *buf, int cols, int depth)
{
- int colw = depth + cols + 1;
- int len = strlen(buf);
- int nlines = len / cols + 1;
- gchar *new_buf = (gchar *) g_malloc0(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, (i + 1) * cols <= len ? cols : len - i * 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;
+ int colw = depth + cols + 1;
+ int len = strlen(buf);
+ int nlines = len / cols + 1;
+ gchar *new_buf = (gchar *) g_malloc0(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, (i + 1) * cols <= len ? cols : len - i * 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;
+struct xml_node
+{
+ xmlNodePtr xml;
+ uint32_t depth;
};
/** Creates a new plist XML document.
- *
+ *
* @return The plist XML document.
*/
static xmlDocPtr new_xml_plist(void)
{
- char *plist = strdup(plist_base);
- xmlDocPtr plist_xml = xmlParseMemory(plist, strlen(plist));
+ char *plist = strdup(plist_base);
+ xmlDocPtr plist_xml = xmlParseMemory(plist, strlen(plist));
- if (!plist_xml)
- return NULL;
+ if (!plist_xml)
+ return NULL;
- free(plist);
+ free(plist);
- return plist_xml;
+ return plist_xml;
}
static void node_to_xml(GNode * node, gpointer xml_struct)
{
- struct xml_node *xstruct = NULL;
- plist_data_t node_data = NULL;
-
- xmlNodePtr child_node = NULL;
- char isStruct = FALSE;
-
- const xmlChar *tag = NULL;
- gchar *val = NULL;
-
- //for base64
- gchar *valtmp = NULL;
-
- uint32_t i = 0;
-
- if (!node)
- return;
-
- xstruct = (struct xml_node *) xml_struct;
- node_data = plist_get_data(node);
-
- switch (node_data->type) {
- case PLIST_BOOLEAN:
- {
- if (node_data->boolval)
- tag = XPLIST_TRUE;
- else
- tag = XPLIST_FALSE;
- }
- break;
-
- case PLIST_UINT:
- tag = XPLIST_INT;
- val = g_strdup_printf("%llu", node_data->intval);
- break;
-
- case PLIST_REAL:
- tag = XPLIST_REAL;
- val = g_strdup_printf("%f", node_data->realval);
- break;
-
- case PLIST_STRING:
- tag = XPLIST_STRING;
- val = g_strdup(node_data->strval);
- break;
-
- case PLIST_KEY:
- tag = XPLIST_KEY;
- val = g_strdup((gchar *) node_data->strval);
- break;
-
- case PLIST_DATA:
- tag = XPLIST_DATA;
- if (node_data->length) {
- 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 = XPLIST_ARRAY;
- isStruct = TRUE;
- break;
- case PLIST_DICT:
- tag = XPLIST_DICT;
- isStruct = TRUE;
- break;
- case PLIST_DATE:
- tag = XPLIST_DATE;
- val = g_time_val_to_iso8601(&node_data->timeval);
- break;
- default:
- break;
- }
-
- for (i = 0; i < xstruct->depth; i++) {
- xmlNodeAddContent(xstruct->xml, BAD_CAST("\t"));
- }
- child_node = xmlNewChild(xstruct->xml, NULL, tag, BAD_CAST(val));
- xmlNodeAddContent(xstruct->xml, BAD_CAST("\n"));
- g_free(val);
-
- //add return for structured types
- if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT)
- xmlNodeAddContent(child_node, BAD_CAST("\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) {
-
- for (i = 0; i < xstruct->depth; i++) {
- xmlNodeAddContent(child_node, BAD_CAST("\t"));
- }
- }
-
- return;
+ struct xml_node *xstruct = NULL;
+ plist_data_t node_data = NULL;
+
+ xmlNodePtr child_node = NULL;
+ char isStruct = FALSE;
+
+ const xmlChar *tag = NULL;
+ gchar *val = NULL;
+
+ //for base64
+ gchar *valtmp = NULL;
+
+ uint32_t i = 0;
+
+ if (!node)
+ return;
+
+ xstruct = (struct xml_node *) xml_struct;
+ node_data = plist_get_data(node);
+
+ switch (node_data->type)
+ {
+ case PLIST_BOOLEAN:
+ {
+ if (node_data->boolval)
+ tag = XPLIST_TRUE;
+ else
+ tag = XPLIST_FALSE;
+ }
+ break;
+
+ case PLIST_UINT:
+ tag = XPLIST_INT;
+ val = g_strdup_printf("%llu", node_data->intval);
+ break;
+
+ case PLIST_REAL:
+ tag = XPLIST_REAL;
+ val = g_strdup_printf("%f", node_data->realval);
+ break;
+
+ case PLIST_STRING:
+ tag = XPLIST_STRING;
+ val = g_strdup(node_data->strval);
+ break;
+
+ case PLIST_KEY:
+ tag = XPLIST_KEY;
+ val = g_strdup((gchar *) node_data->strval);
+ break;
+
+ case PLIST_DATA:
+ tag = XPLIST_DATA;
+ if (node_data->length)
+ {
+ 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 = XPLIST_ARRAY;
+ isStruct = TRUE;
+ break;
+ case PLIST_DICT:
+ tag = XPLIST_DICT;
+ isStruct = TRUE;
+ break;
+ case PLIST_DATE:
+ tag = XPLIST_DATE;
+ val = g_time_val_to_iso8601(&node_data->timeval);
+ break;
+ default:
+ break;
+ }
+
+ for (i = 0; i < xstruct->depth; i++)
+ {
+ xmlNodeAddContent(xstruct->xml, BAD_CAST("\t"));
+ }
+ child_node = xmlNewChild(xstruct->xml, NULL, tag, BAD_CAST(val));
+ xmlNodeAddContent(xstruct->xml, BAD_CAST("\n"));
+ g_free(val);
+
+ //add return for structured types
+ if (node_data->type == PLIST_ARRAY || node_data->type == PLIST_DICT)
+ xmlNodeAddContent(child_node, BAD_CAST("\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)
+ {
+
+ for (i = 0; i < xstruct->depth; i++)
+ {
+ xmlNodeAddContent(child_node, BAD_CAST("\t"));
+ }
+ }
+
+ return;
}
static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node)
{
- xmlNodePtr node = NULL;
- plist_data_t data = NULL;
- plist_t subnode = NULL;
-
- //for string
- glong len = 0;
- int type = 0;
-
- if (!xml_node)
- return;
-
- for (node = xml_node->children; node; node = node->next) {
-
- while (node && !xmlStrcmp(node->name, XPLIST_TEXT))
- node = node->next;
- if (!node)
- break;
-
- data = plist_new_plist_data();
- subnode = plist_new_node(data);
- if (*plist_node)
- g_node_append(*plist_node, subnode);
- else
- *plist_node = subnode;
-
- if (!xmlStrcmp(node->name, XPLIST_TRUE)) {
- data->boolval = TRUE;
- data->type = PLIST_BOOLEAN;
- data->length = 1;
- continue;
- }
-
- if (!xmlStrcmp(node->name, XPLIST_FALSE)) {
- data->boolval = FALSE;
- data->type = PLIST_BOOLEAN;
- data->length = 1;
- continue;
- }
-
- if (!xmlStrcmp(node->name, XPLIST_INT)) {
- xmlChar *strval = xmlNodeGetContent(node);
- data->intval = g_ascii_strtoull((char *) strval, NULL, 0);
- data->type = PLIST_UINT;
- data->length = 8;
- xmlFree(strval);
- continue;
- }
-
- if (!xmlStrcmp(node->name, XPLIST_REAL)) {
- xmlChar *strval = xmlNodeGetContent(node);
- data->realval = atof((char *) strval);
- data->type = PLIST_REAL;
- data->length = 8;
- xmlFree(strval);
- continue;
- }
-
- if (!xmlStrcmp(node->name, XPLIST_DATE)) {
- xmlChar *strval = xmlNodeGetContent(node);
- g_time_val_from_iso8601((char *) strval, &data->timeval);
- data->type = PLIST_DATE;
- data->length = sizeof(GTimeVal);
- xmlFree(strval);
- continue;
- }
-
- if (!xmlStrcmp(node->name, XPLIST_STRING)) {
- xmlChar *strval = xmlNodeGetContent(node);
- len = strlen((char *) strval);
- type = xmlDetectCharEncoding(strval, len);
-
- if (XML_CHAR_ENCODING_UTF8 == type || XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type) {
- data->strval = strdup((char *) strval);
- data->type = PLIST_STRING;
- data->length = strlen(data->strval);
- }
- xmlFree(strval);
- continue;
- }
-
- if (!xmlStrcmp(node->name, XPLIST_KEY)) {
- xmlChar *strval = xmlNodeGetContent(node);
- data->strval = strdup((char *) strval);
- data->type = PLIST_KEY;
- data->length = strlen(data->strval);
- xmlFree(strval);
- continue;
- }
-
- if (!xmlStrcmp(node->name, XPLIST_DATA)) {
- xmlChar *strval = xmlNodeGetContent(node);
- gsize size = 0;
- guchar *dec = g_base64_decode((char *) strval, &size);
- data->buff = (uint8_t *) malloc(size * sizeof(uint8_t));
- memcpy(data->buff, dec, size * sizeof(uint8_t));
- g_free(dec);
- data->length = size;
- data->type = PLIST_DATA;
- xmlFree(strval);
- continue;
- }
-
- if (!xmlStrcmp(node->name, XPLIST_ARRAY)) {
- data->type = PLIST_ARRAY;
- xml_to_node(node, &subnode);
- continue;
- }
-
- if (!xmlStrcmp(node->name, XPLIST_DICT)) {
- data->type = PLIST_DICT;
- xml_to_node(node, &subnode);
- continue;
- }
- }
+ xmlNodePtr node = NULL;
+ plist_data_t data = NULL;
+ plist_t subnode = NULL;
+
+ //for string
+ glong len = 0;
+ int type = 0;
+
+ if (!xml_node)
+ return;
+
+ for (node = xml_node->children; node; node = node->next)
+ {
+
+ while (node && !xmlStrcmp(node->name, XPLIST_TEXT))
+ node = node->next;
+ if (!node)
+ break;
+
+ data = plist_new_plist_data();
+ subnode = plist_new_node(data);
+ if (*plist_node)
+ g_node_append(*plist_node, subnode);
+ else
+ *plist_node = subnode;
+
+ if (!xmlStrcmp(node->name, XPLIST_TRUE))
+ {
+ data->boolval = TRUE;
+ data->type = PLIST_BOOLEAN;
+ data->length = 1;
+ continue;
+ }
+
+ if (!xmlStrcmp(node->name, XPLIST_FALSE))
+ {
+ data->boolval = FALSE;
+ data->type = PLIST_BOOLEAN;
+ data->length = 1;
+ continue;
+ }
+
+ if (!xmlStrcmp(node->name, XPLIST_INT))
+ {
+ xmlChar *strval = xmlNodeGetContent(node);
+ data->intval = g_ascii_strtoull((char *) strval, NULL, 0);
+ data->type = PLIST_UINT;
+ data->length = 8;
+ xmlFree(strval);
+ continue;
+ }
+
+ if (!xmlStrcmp(node->name, XPLIST_REAL))
+ {
+ xmlChar *strval = xmlNodeGetContent(node);
+ data->realval = atof((char *) strval);
+ data->type = PLIST_REAL;
+ data->length = 8;
+ xmlFree(strval);
+ continue;
+ }
+
+ if (!xmlStrcmp(node->name, XPLIST_DATE))
+ {
+ xmlChar *strval = xmlNodeGetContent(node);
+ g_time_val_from_iso8601((char *) strval, &data->timeval);
+ data->type = PLIST_DATE;
+ data->length = sizeof(GTimeVal);
+ xmlFree(strval);
+ continue;
+ }
+
+ if (!xmlStrcmp(node->name, XPLIST_STRING))
+ {
+ xmlChar *strval = xmlNodeGetContent(node);
+ len = strlen((char *) strval);
+ type = xmlDetectCharEncoding(strval, len);
+
+ if (XML_CHAR_ENCODING_UTF8 == type || XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type)
+ {
+ data->strval = strdup((char *) strval);
+ data->type = PLIST_STRING;
+ data->length = strlen(data->strval);
+ }
+ xmlFree(strval);
+ continue;
+ }
+
+ if (!xmlStrcmp(node->name, XPLIST_KEY))
+ {
+ xmlChar *strval = xmlNodeGetContent(node);
+ data->strval = strdup((char *) strval);
+ data->type = PLIST_KEY;
+ data->length = strlen(data->strval);
+ xmlFree(strval);
+ continue;
+ }
+
+ if (!xmlStrcmp(node->name, XPLIST_DATA))
+ {
+ xmlChar *strval = xmlNodeGetContent(node);
+ gsize size = 0;
+ guchar *dec = g_base64_decode((char *) strval, &size);
+ data->buff = (uint8_t *) malloc(size * sizeof(uint8_t));
+ memcpy(data->buff, dec, size * sizeof(uint8_t));
+ g_free(dec);
+ data->length = size;
+ data->type = PLIST_DATA;
+ xmlFree(strval);
+ continue;
+ }
+
+ if (!xmlStrcmp(node->name, XPLIST_ARRAY))
+ {
+ data->type = PLIST_ARRAY;
+ xml_to_node(node, &subnode);
+ continue;
+ }
+
+ if (!xmlStrcmp(node->name, XPLIST_DICT))
+ {
+ data->type = PLIST_DICT;
+ xml_to_node(node, &subnode);
+ continue;
+ }
+ }
}
void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length)
{
- xmlDocPtr plist_doc = NULL;
- xmlNodePtr root_node = NULL;
- struct xml_node root = { NULL, 0 };
- int size = 0;
-
- if (!plist || !plist_xml || *plist_xml)
- return;
- plist_doc = new_xml_plist();
- root_node = xmlDocGetRootElement(plist_doc);
- root.xml = root_node;
-
- node_to_xml(plist, &root);
-
- xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, &size);
- if (size >= 0)
- *length = size;
- xmlFreeDoc(plist_doc);
+ xmlDocPtr plist_doc = NULL;
+ xmlNodePtr root_node = NULL;
+ struct xml_node root = { NULL, 0 };
+ int size = 0;
+
+ if (!plist || !plist_xml || *plist_xml)
+ return;
+ plist_doc = new_xml_plist();
+ root_node = xmlDocGetRootElement(plist_doc);
+ root.xml = root_node;
+
+ node_to_xml(plist, &root);
+
+ xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, &size);
+ if (size >= 0)
+ *length = size;
+ xmlFreeDoc(plist_doc);
}
void plist_from_xml(const char *plist_xml, uint32_t length, plist_t * plist)
{
- xmlDocPtr plist_doc = xmlParseMemory(plist_xml, length);
- xmlNodePtr root_node = xmlDocGetRootElement(plist_doc);
+ xmlDocPtr plist_doc = xmlParseMemory(plist_xml, length);
+ xmlNodePtr root_node = xmlDocGetRootElement(plist_doc);
- xml_to_node(root_node, plist);
- xmlFreeDoc(plist_doc);
+ xml_to_node(root_node, plist);
+ xmlFreeDoc(plist_doc);
}