From bfd57eb1cf738ed62e17941e855347772ce48ef2 Mon Sep 17 00:00:00 2001 From: Jonathan Beck Date: Thu, 22 Jan 2009 22:18:43 +0100 Subject: Add Unicode support. --- src/Makefile.am | 2 +- src/bplist.c | 38 +++++++++++++++++++++++++------------- src/plist.c | 9 +++++---- src/plist.h | 3 +-- src/utils.c | 3 --- src/xplist.c | 33 +++++++++++++++++++++++++++------ 6 files changed, 59 insertions(+), 29 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 3178d8a..eb9cd08 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ INCLUDES = -I$(top_srcdir)/include -AM_CFLAGS = $(GLOBAL_CFLAGS) $(libxml2_CFLAGS) $(libglib2_CFLAGS) -D_GNU_SOURCE +AM_CFLAGS = $(GLOBAL_CFLAGS) $(libxml2_CFLAGS) $(libglib2_CFLAGS) AM_LDFLAGS = $(libxml2_LIBS) $(libglib2_LIBS) lib_LTLIBRARIES = libplist.la diff --git a/src/bplist.c b/src/bplist.c index fd0280c..67d7f72 100644 --- a/src/bplist.c +++ b/src/bplist.c @@ -21,7 +21,6 @@ #include "plist.h" -#include #include #include #include @@ -152,7 +151,7 @@ static plist_t parse_date_node(char *bnode, uint8_t size) return node; } -static plist_t parse_string_node(char *bnode, uint8_t size) +static plist_t parse_string_node(char *bnode, uint64_t size) { plist_data_t data = plist_new_plist_data(); @@ -165,16 +164,17 @@ static plist_t parse_string_node(char *bnode, uint8_t size) return g_node_new(data); } -static plist_t parse_unicode_node(char *bnode, uint8_t size) +static plist_t parse_unicode_node(char *bnode, uint64_t size) { plist_data_t data = plist_new_plist_data(); - + uint64_t i = 0; data->type = PLIST_UNICODE; - data->unicodeval = (wchar_t *) malloc(sizeof(wchar_t) * (size + 1)); - memcpy(data->unicodeval, bnode, size); - data->unicodeval[size] = '\0'; - data->length = wcslen(data->unicodeval); - + data->unicodeval = (gunichar2 *) malloc(sizeof(gunichar2) * (size + 1)); + memcpy(data->unicodeval, bnode, sizeof(gunichar2) * size); + data->unicodeval[sizeof(gunichar2) * size] = '\0'; + data->length = size; + for (i = 0; i <= size; i++) + byte_convert(data->unicodeval + i, sizeof(gunichar2)); return g_node_new(data); } @@ -338,7 +338,8 @@ static gpointer copy_plist_data(gconstpointer src, gpointer data) dstdata->strval = strdup(srcdata->strval); break; case PLIST_UNICODE: - dstdata->unicodeval = wcsdup(srcdata->unicodeval); + dstdata->unicodeval = (gunichar2*) malloc(srcdata->length * sizeof(gunichar2)); + memcpy(dstdata->unicodeval, srcdata->unicodeval, srcdata->length * sizeof(gunichar2)); break; case PLIST_DATA: case PLIST_ARRAY: @@ -493,7 +494,7 @@ static guint plist_data_hash(gconstpointer key) break; case PLIST_UNICODE: buff = (char *) data->unicodeval; - size = strlen(buff) * sizeof(wchar_t); + size = data->length; break; case PLIST_DATA: case PLIST_ARRAY: @@ -544,7 +545,7 @@ static gboolean plist_data_compare(gconstpointer a, gconstpointer b) else return FALSE; case PLIST_UNICODE: - if (!wcscmp(val_a->unicodeval, val_b->unicodeval)) + if (!memcmp(val_a->unicodeval, val_b->unicodeval,val_a->length)) return TRUE; else return FALSE; @@ -662,6 +663,17 @@ static void write_string(GByteArray * bplist, char *val) write_raw_data(bplist, BPLIST_STRING, (uint8_t *) val, size); } +static void write_unicode(GByteArray * bplist, gunichar2 *val, uint64_t size) +{ + uint64_t i = 0; + uint64_t size2 = size * sizeof(gunichar2); + uint8_t* buff = (uint8_t*) malloc(size2); + memcpy(buff, val, size2); + for (i = 0; i < size; i++) + byte_convert(buff + i * sizeof(gunichar2), sizeof(gunichar2)); + write_raw_data(bplist, BPLIST_STRING, buff, size2); +} + static void write_array(GByteArray * bplist, GNode * node, GHashTable * ref_table, uint8_t dict_param_size) { uint64_t size = g_node_n_children(node); @@ -784,7 +796,7 @@ void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) write_string(bplist_buff, data->strval); break; case PLIST_UNICODE: - //TODO + write_unicode(bplist_buff, data->unicodeval, data->length); break; case PLIST_DATA: write_data(bplist_buff, data->buff, data->length); diff --git a/src/plist.c b/src/plist.c index e5cf2db..74868cc 100644 --- a/src/plist.c +++ b/src/plist.c @@ -24,7 +24,6 @@ #include #include "utils.h" #include "plist.h" -#include #include #include @@ -99,7 +98,8 @@ plist_t plist_add_sub_element(plist_t node, plist_type type, void *value, uint64 data->strval = strdup((char *) value); break; case PLIST_UNICODE: - data->unicodeval = wcsdup((wchar_t *) value); + data->unicodeval = (gunichar2*) malloc(length * sizeof(gunichar2)); + memcpy(data->unicodeval, value, length * sizeof(gunichar2)); break; case PLIST_DATA: memcpy(data->buff, value, length); @@ -158,7 +158,7 @@ static char compare_node_value(plist_type type, plist_data_t data, void *value, res = !strcmp(data->strval, ((char *) value)); break; case PLIST_UNICODE: - res = !wcscmp(data->unicodeval, ((wchar_t *) value)); + res = !memcpy(data->unicodeval, value, length); break; case PLIST_DATA: res = memcmp(data->buff, (char *) value, length); @@ -229,7 +229,8 @@ void plist_get_type_and_value(plist_t node, plist_type * type, void *value, uint *((char **) value) = strdup(data->strval); break; case PLIST_UNICODE: - *((wchar_t **) value) = wcsdup(data->unicodeval); + *((gunichar2 **) value) = malloc (*length * sizeof(gunichar2)); + memcpy(*((gunichar2 **) value), data->unicodeval, *length * sizeof(gunichar2)); break; case PLIST_DATA: case PLIST_ARRAY: diff --git a/src/plist.h b/src/plist.h index 449a3f7..80a3f7f 100644 --- a/src/plist.h +++ b/src/plist.h @@ -25,7 +25,6 @@ #include "plist/plist.h" #include -#include #include #include @@ -42,7 +41,7 @@ struct plist_data_s { uint64_t intval; double realval; char *strval; - wchar_t *unicodeval; + gunichar2 *unicodeval; uint8_t *buff; GTimeVal timeval; }; diff --git a/src/utils.c b/src/utils.c index ceb1f5d..920b347 100644 --- a/src/utils.c +++ b/src/utils.c @@ -35,8 +35,6 @@ void iphone_set_debug(int level) toto_debug = level; } - - void log_debug_msg(const char *format, ...) { #ifndef STRIP_DEBUG_CODE @@ -60,7 +58,6 @@ inline void log_debug_buffer(const char *data, const int length) /* run the real fprintf */ if (toto_debug) fwrite(data, 1, length, stderr); - #endif } diff --git a/src/xplist.c b/src/xplist.c index 0b803cf..e61797c 100644 --- a/src/xplist.c +++ b/src/xplist.c @@ -24,7 +24,6 @@ #include #include "utils.h" #include "plist.h" -#include #include #include @@ -139,6 +138,12 @@ static void node_to_xml(GNode * node, gpointer xml_struct) const xmlChar *tag = NULL; gchar *val = NULL; + //for unicode + glong len = 0; + glong items_read = 0; + glong items_written = 0; + GError *error = NULL; + switch (node_data->type) { case PLIST_BOOLEAN: { @@ -166,7 +171,8 @@ static void node_to_xml(GNode * node, gpointer xml_struct) case PLIST_UNICODE: tag = XPLIST_STRING; - val = g_strdup((gchar *) node_data->unicodeval); + len = node_data->length; + val = g_utf16_to_utf8(node_data->unicodeval, len, &items_read, &items_written, &error); break; case PLIST_KEY: @@ -278,13 +284,28 @@ static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node) g_time_val_from_iso8601((char *) xmlNodeGetContent(node), &data->timeval); data->type = PLIST_DATE; data->length = sizeof(GTimeVal); - continue; //TODO : handle date tag + continue; } if (!xmlStrcmp(node->name, XPLIST_STRING)) { - data->strval = strdup((char *) xmlNodeGetContent(node)); - data->type = PLIST_STRING; - data->length = strlen(data->strval); + + unsigned char *tmp = xmlNodeGetContent(node); + glong len = strlen((char*)tmp); + glong items_read = 0; + glong items_written = 0; + GError *error = NULL; + int type = xmlDetectCharEncoding(tmp, len); + + if (XML_CHAR_ENCODING_UTF8 == type) { + data->unicodeval = g_utf8_to_utf16((char*) tmp, len, &items_read, &items_written, &error); + data->type = PLIST_UNICODE; + data->length = items_written; + } + else if (XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type) { + data->strval = strdup((char *) xmlNodeGetContent(node)); + data->type = PLIST_STRING; + data->length = strlen(data->strval); + } continue; } -- cgit v1.1-32-gdbae