*/
/*
- * Copyright (C) 2012 Eric Biggers
+ * Copyright (C) 2012, 2013 Eric Biggers
*
* This file is part of wimlib, a library for working with WIM files.
*
* along with wimlib; if not, see http://www.gnu.org/licenses/.
*/
+#include "config.h"
#include "wimlib.h"
#include "util.h"
#include "endianness.h"
#include <errno.h>
#ifdef WITH_NTFS_3G
-#include <ntfs-3g/volume.h>
-#include <ntfs-3g/unistr.h>
+# include <ntfs-3g/volume.h>
+# include <ntfs-3g/unistr.h>
+#elif defined(__WIN32__)
+# include <wchar.h>
+# include <stdlib.h>
#else
-#include <iconv.h>
+# include <iconv.h>
#endif
/*
* libntfs-3g/unistr.c in the NTFS-3g sources. (Modified slightly to remove
* unneeded functionality.)
*/
-#ifndef WITH_NTFS_3G
+#if !defined(WITH_NTFS_3G) && !defined(__WIN32__)
/*
* Return the amount of 8-bit elements in UTF-8 needed (without the terminating
* null) to store a given UTF-16LE string.
}
return count;
}
-#endif /* !WITH_NTFS_3G */
+
+static iconv_t cd_utf8_to_utf16 = (iconv_t)(-1);
+static iconv_t cd_utf16_to_utf8 = (iconv_t)(-1);
+
+int iconv_global_init()
+{
+ if (cd_utf16_to_utf8 == (iconv_t)(-1)) {
+ cd_utf16_to_utf8 = iconv_open("UTF-8", "UTF-16LE");
+ if (cd_utf16_to_utf8 == (iconv_t)-1) {
+ ERROR_WITH_ERRNO("Failed to get conversion descriptor "
+ "for converting UTF-16LE to UTF-8");
+ if (errno == ENOMEM)
+ return WIMLIB_ERR_NOMEM;
+ else
+ return WIMLIB_ERR_ICONV_NOT_AVAILABLE;
+ }
+ }
+
+ if (cd_utf8_to_utf16 == (iconv_t)(-1)) {
+ cd_utf8_to_utf16 = iconv_open("UTF-16LE", "UTF-8");
+ if (cd_utf8_to_utf16 == (iconv_t)-1) {
+ ERROR_WITH_ERRNO("Failed to get conversion descriptor "
+ "for converting UTF-8 to UTF-16LE");
+ if (errno == ENOMEM)
+ return WIMLIB_ERR_NOMEM;
+ else
+ return WIMLIB_ERR_ICONV_NOT_AVAILABLE;
+ }
+ }
+ return 0;
+}
+
+void iconv_global_cleanup()
+{
+ if (cd_utf8_to_utf16 != (iconv_t)(-1))
+ iconv_close(cd_utf8_to_utf16);
+ if (cd_utf16_to_utf8 != (iconv_t)(-1))
+ iconv_close(cd_utf16_to_utf8);
+}
+#endif /* !WITH_NTFS_3G && !__WIN32__ */
/* Converts a string in the UTF-16LE encoding to a newly allocated string in the
* UTF-8 encoding.
else
ret = WIMLIB_ERR_INVALID_UTF16_STRING;
}
-#else /* WITH_NTFS_3G */
- static iconv_t cd_utf16_to_utf8 = (iconv_t)(-1);
- if (cd_utf16_to_utf8 == (iconv_t)(-1)) {
- cd_utf16_to_utf8 = iconv_open("UTF-8", "UTF-16LE");
- if (cd_utf16_to_utf8 == (iconv_t)-1) {
- ERROR_WITH_ERRNO("Failed to get conversion descriptor "
- "for converting UTF-16LE to UTF-8");
- if (errno == ENOMEM)
- return WIMLIB_ERR_NOMEM;
- else
- return WIMLIB_ERR_ICONV_NOT_AVAILABLE;
+#elif defined(__WIN32__)
+ char *utf8_str;
+ size_t utf8_nbytes;
+ utf8_nbytes = wcstombs(NULL, (const wchar_t*)utf16_str, 0);
+ if (utf8_nbytes == (size_t)(-1)) {
+ ret = WIMLIB_ERR_INVALID_UTF16_STRING;
+ } else {
+ utf8_str = MALLOC(utf8_nbytes + 1);
+ if (!utf8_str) {
+ ret = WIMLIB_ERR_NOMEM;
+ } else {
+ wcstombs(utf8_str, (const wchar_t*)utf16_str, utf8_nbytes + 1);
+ *utf8_str_ret = utf8_str;
+ *utf8_nbytes_ret = utf8_nbytes;
+ ret = 0;
}
}
+#else
+ ret = iconv_global_init();
+ if (ret != 0)
+ return ret;
+
ret = utf16_to_utf8_size((const u16*)utf16_str, utf16_nbytes / 2);
if (ret >= 0) {
size_t utf8_expected_nbytes;
else
ret = WIMLIB_ERR_INVALID_UTF8_STRING;
}
-#else /* WITH_NTFS_3G */
- static iconv_t cd_utf8_to_utf16 = (iconv_t)(-1);
- if (cd_utf8_to_utf16 == (iconv_t)(-1)) {
- cd_utf8_to_utf16 = iconv_open("UTF-16LE", "UTF-8");
- if (cd_utf8_to_utf16 == (iconv_t)-1) {
- ERROR_WITH_ERRNO("Failed to get conversion descriptor "
- "for converting UTF-8 to UTF-16LE");
- if (errno == ENOMEM)
- return WIMLIB_ERR_NOMEM;
- else
- return WIMLIB_ERR_ICONV_NOT_AVAILABLE;
+#elif defined(__WIN32__)
+
+ char *utf16_str;
+ size_t utf16_nchars;
+ utf16_nchars = mbstowcs(NULL, utf8_str, 0);
+ if (utf16_nchars == (size_t)(-1)) {
+ ret = WIMLIB_ERR_INVALID_UTF8_STRING;
+ } else {
+ utf16_str = MALLOC((utf16_nchars + 1) * sizeof(wchar_t));
+ if (!utf16_str) {
+ ret = WIMLIB_ERR_NOMEM;
+ } else {
+ mbstowcs((wchar_t*)utf16_str, utf8_str,
+ utf16_nchars + 1);
+ *utf16_str_ret = utf16_str;
+ *utf16_nbytes_ret = utf16_nchars * sizeof(wchar_t);
+ ret = 0;
}
}
-
+
+#else
+ ret = iconv_global_init();
+ if (ret != 0)
+ return ret;
ret = utf8_to_utf16_size(utf8_str);
if (ret >= 0) {
size_t utf16_expected_nbytes;