]> wimlib.net Git - wimlib/blobdiff - src/xml.c
configure.ac: generate version number from git commit and tags
[wimlib] / src / xml.c
index d46470653ab4149d15fa5dfef347844034e32363..3812ce1e19d7926e499a9c230e0bddb9664d02ea 100644 (file)
--- a/src/xml.c
+++ b/src/xml.c
@@ -5,7 +5,7 @@
  */
 
 /*
- * Copyright (C) 2012, 2013, 2015 Eric Biggers
+ * Copyright (C) 2012-2016 Eric Biggers
  *
  * This file 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
@@ -64,12 +64,14 @@ struct wim_xml_info {
        /* The number of WIM images (the length of 'images')  */
        int image_count;
 
+#if TCHAR_IS_UTF16LE
        /* Temporary memory for UTF-8 => 'tchar' string translations.  When an
         * API function needs to return a 'tchar' string, it uses one of these
         * array slots to hold the string and returns a pointer to it.  */
        tchar *strings[128];
        size_t next_string_idx;
        size_t num_strings;
+#endif
 };
 
 /*----------------------------------------------------------------------------*
@@ -144,18 +146,21 @@ node_get_timestamp(const xmlNode *node)
 static int
 tstr_get_utf8(const tchar *tstr, const xmlChar **utf8_ret)
 {
-       if (wimlib_mbs_is_utf8) {
-               *utf8_ret = (xmlChar *)tstr;
-               return 0;
-       }
-       return tstr_to_utf8_simple(tstr, (char **)utf8_ret);
+#if TCHAR_IS_UTF16LE
+       return utf16le_to_utf8(tstr, tstrlen(tstr) * sizeof(tchar),
+                              (char **)utf8_ret, NULL);
+#else
+       *utf8_ret = (const xmlChar *)tstr;
+       return 0;
+#endif
 }
 
 static void
 tstr_put_utf8(const xmlChar *utf8)
 {
-       if (!wimlib_mbs_is_utf8)
-               FREE((void *)utf8);
+#if TCHAR_IS_UTF16LE
+       FREE((char *)utf8);
+#endif
 }
 
 /* Retrieve the text contents of an XML element as a 'tchar' string.  If not
@@ -163,26 +168,29 @@ tstr_put_utf8(const xmlChar *utf8)
 static const tchar *
 node_get_ttext(struct wim_xml_info *info, xmlNode *node)
 {
-       const xmlChar *text;
-       tchar **ttext_p;
+       const xmlChar *text = node_get_text(node);
 
-       text = node_get_text(node);
+#if TCHAR_IS_UTF16LE
+       tchar **ttext_p;
 
-       if (!text || wimlib_mbs_is_utf8)
-               return (const tchar *)text;
+       if (!text)
+               return NULL;
 
        ttext_p = &info->strings[info->next_string_idx];
        if (info->num_strings >= ARRAY_LEN(info->strings)) {
                FREE(*ttext_p);
                *ttext_p = NULL;
        }
-       if (utf8_to_tstr_simple(text, ttext_p))
+       if (utf8_to_tstr(text, strlen(text), ttext_p, NULL))
                return NULL;
        if (info->num_strings < ARRAY_LEN(info->strings))
                info->num_strings++;
        info->next_string_idx++;
        info->next_string_idx %= ARRAY_LEN(info->strings);
        return *ttext_p;
+#else
+       return text;
+#endif
 }
 
 /* Unlink the specified node from its parent, then free it (recursively).  */
@@ -335,22 +343,24 @@ static struct wim_xml_info *
 alloc_wim_xml_info(void)
 {
        struct wim_xml_info *info = MALLOC(sizeof(*info));
+#if TCHAR_IS_UTF16LE
        if (info) {
                info->next_string_idx = 0;
                info->num_strings = 0;
        }
+#endif
        return info;
 }
 
 static bool
-parse_index(xmlChar **pp, uint32_t *index_ret)
+parse_index(xmlChar **pp, u32 *index_ret)
 {
        xmlChar *p = *pp;
-       uint32_t index = 0;
+       u32 index = 0;
 
        *p++ = '\0'; /* overwrite '[' */
        while (*p >= '0' && *p <= '9') {
-               uint32_t n = (index * 10) + (*p++ - '0');
+               u32 n = (index * 10) + (*p++ - '0');
                if (n < index)
                        return false;
                index = n;
@@ -393,7 +403,7 @@ do_xml_path_walk(xmlNode *node, const xmlChar *path, bool create,
        while (c != '\0') {
                const xmlChar *name;
                xmlNode *child;
-               uint32_t index = 1;
+               u32 index = 1;
 
                /* We have another path component.  */
 
@@ -512,37 +522,6 @@ xml_set_ttext_by_path(xmlNode *root, const xmlChar *path, const tchar *ttext)
        }
 }
 
-/* Sets a string property for the specified WIM image.  */
-static int
-set_image_property(WIMStruct *wim, int image, const xmlChar *name,
-                  const tchar *value)
-{
-       struct wim_xml_info *info = wim->xml_info;
-
-       if (image < 1 || image > info->image_count)
-               return WIMLIB_ERR_INVALID_IMAGE;
-
-       return xml_set_ttext_by_path(info->images[image - 1], name, value);
-}
-
-/* Gets a string property for the specified WIM image as a 'tchar' string.
- * Returns a pointer to the property value if found; NULL if the image doesn't
- * exist; or 'default_value' if the property doesn't exist in the image or if
- * the property value could not be translated to a 'tchar' string.  */
-static const tchar *
-get_image_property(const WIMStruct *wim, int image, const xmlChar *name,
-                  const tchar *default_value)
-{
-       struct wim_xml_info *info = wim->xml_info;
-       const tchar *value;
-
-       if (image < 1 || image > info->image_count)
-               return NULL;
-
-       value = xml_get_ttext_by_path(info, info->images[image - 1], name);
-       return value ? value : default_value;
-}
-
 /* Unlink and return the node which represents the INDEX attribute of the
  * specified IMAGE element.  */
 static xmlAttr *
@@ -640,8 +619,10 @@ xml_free_info_struct(struct wim_xml_info *info)
        if (info) {
                xmlFreeDoc(info->doc);
                FREE(info->images);
+       #if TCHAR_IS_UTF16LE
                for (size_t i = 0; i < info->num_strings; i++)
                        FREE(info->strings[i]);
+       #endif
                FREE(info);
        }
 }
@@ -894,6 +875,7 @@ xml_delete_image(struct wim_xml_info *info, int image)
 #define PROCESSOR_ARCHITECTURE_MSIL            8
 #define PROCESSOR_ARCHITECTURE_AMD64           9
 #define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64   10
+#define PROCESSOR_ARCHITECTURE_ARM64           12
 
 static const tchar *
 describe_arch(u64 arch)
@@ -904,6 +886,7 @@ describe_arch(u64 arch)
                [PROCESSOR_ARCHITECTURE_ARM]   = T("ARM"),
                [PROCESSOR_ARCHITECTURE_IA64]  = T("ia64"),
                [PROCESSOR_ARCHITECTURE_AMD64] = T("x86_64"),
+               [PROCESSOR_ARCHITECTURE_ARM64] = T("ARM64"),
        };
 
        if (arch < ARRAY_LEN(descriptions) && descriptions[arch] != NULL)
@@ -1056,7 +1039,7 @@ xml_print_image_info(struct wim_xml_info *info, int image)
  *----------------------------------------------------------------------------*/
 
 static int
-image_node_get_index(const xmlNode *node)
+image_node_get_index(xmlNode *node)
 {
        u64 v = node_get_number((const xmlNode *)xmlHasProp(node, "INDEX"), 10);
        return min(v, INT_MAX);
@@ -1419,13 +1402,19 @@ wimlib_image_name_in_use(const WIMStruct *wim, const tchar *name)
 WIMLIBAPI const tchar *
 wimlib_get_image_name(const WIMStruct *wim, int image)
 {
-       return get_image_property(wim, image, "NAME", T(""));
+       const struct wim_xml_info *info = wim->xml_info;
+       const tchar *name;
+
+       if (image < 1 || image > info->image_count)
+               return NULL;
+       name = wimlib_get_image_property(wim, image, T("NAME"));
+       return name ? name : T("");
 }
 
 WIMLIBAPI const tchar *
 wimlib_get_image_description(const WIMStruct *wim, int image)
 {
-       return get_image_property(wim, image, "DESCRIPTION", NULL);
+       return wimlib_get_image_property(wim, image, T("DESCRIPTION"));
 }
 
 WIMLIBAPI const tchar *
@@ -1434,12 +1423,15 @@ wimlib_get_image_property(const WIMStruct *wim, int image,
 {
        const xmlChar *name;
        const tchar *value;
+       struct wim_xml_info *info = wim->xml_info;
 
        if (!property_name || !*property_name)
                return NULL;
+       if (image < 1 || image > info->image_count)
+               return NULL;
        if (tstr_get_utf8(property_name, &name))
                return NULL;
-       value = get_image_property(wim, image, name, NULL);
+       value = xml_get_ttext_by_path(info, info->images[image - 1], name);
        tstr_put_utf8(name);
        return value;
 }
@@ -1447,22 +1439,19 @@ wimlib_get_image_property(const WIMStruct *wim, int image,
 WIMLIBAPI int
 wimlib_set_image_name(WIMStruct *wim, int image, const tchar *name)
 {
-       if (image_name_in_use(wim, name, image))
-               return WIMLIB_ERR_IMAGE_NAME_COLLISION;
-
-       return set_image_property(wim, image, "NAME", name);
+       return wimlib_set_image_property(wim, image, T("NAME"), name);
 }
 
 WIMLIBAPI int
 wimlib_set_image_descripton(WIMStruct *wim, int image, const tchar *description)
 {
-       return set_image_property(wim, image, "DESCRIPTION", description);
+       return wimlib_set_image_property(wim, image, T("DESCRIPTION"), description);
 }
 
 WIMLIBAPI int
 wimlib_set_image_flags(WIMStruct *wim, int image, const tchar *flags)
 {
-       return set_image_property(wim, image, "FLAGS", flags);
+       return wimlib_set_image_property(wim, image, T("FLAGS"), flags);
 }
 
 WIMLIBAPI int
@@ -1470,15 +1459,23 @@ wimlib_set_image_property(WIMStruct *wim, int image, const tchar *property_name,
                          const tchar *property_value)
 {
        const xmlChar *name;
+       struct wim_xml_info *info = wim->xml_info;
        int ret;
 
        if (!property_name || !*property_name)
                return WIMLIB_ERR_INVALID_PARAM;
 
+       if (image < 1 || image > info->image_count)
+               return WIMLIB_ERR_INVALID_IMAGE;
+
+       if (!tstrcmp(property_name, T("NAME")) &&
+           image_name_in_use(wim, property_value, image))
+               return WIMLIB_ERR_IMAGE_NAME_COLLISION;
+
        ret = tstr_get_utf8(property_name, &name);
        if (ret)
                return ret;
-       ret = set_image_property(wim, image, name, property_value);
+       ret = xml_set_ttext_by_path(info->images[image - 1], name, property_value);
        tstr_put_utf8(name);
        return ret;
 }