diff options
Diffstat (limited to 'src/xplist.c')
-rw-r--r-- | src/xplist.c | 564 |
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); } |