aboutsummaryrefslogtreecommitdiff
path: root/lib/libarchive/archive_string.c
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@FreeBSD.org>2009-03-03 17:02:51 +0000
committerTim Kientzle <kientzle@FreeBSD.org>2009-03-03 17:02:51 +0000
commit690f818afd6c3c0721202dd1e075aeaaae004704 (patch)
tree1dee8b4b9c023077ab174a6dc9ffbb460e86b36b /lib/libarchive/archive_string.c
parent6b0ff427a57b12372e9b7181e92e50b17c773ca9 (diff)
Merge r294:337,r348:350 from libarchive.googlecode.com: A lot
of work to make libarchive work on Windows.
Notes
Notes: svn path=/head/; revision=189308
Diffstat (limited to 'lib/libarchive/archive_string.c')
-rw-r--r--lib/libarchive/archive_string.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/lib/libarchive/archive_string.c b/lib/libarchive/archive_string.c
index fc6a344e9479..c22031706a2f 100644
--- a/lib/libarchive/archive_string.c
+++ b/lib/libarchive/archive_string.c
@@ -40,6 +40,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_WCHAR_H
#include <wchar.h>
#endif
+#ifdef _WIN32
+#include <windows.h>
+#endif
#include "archive_private.h"
#include "archive_string.h"
@@ -175,6 +178,7 @@ __archive_strappend_int(struct archive_string *as, int d, int base)
return (as);
}
+#ifndef _WIN32
/*
* Home-grown wctomb for UTF-8.
*/
@@ -375,3 +379,83 @@ __archive_string_utf8_w(struct archive_string *as)
*dest++ = L'\0';
return (ws);
}
+
+#else
+
+static struct archive_string *
+my_archive_strappend_w(struct archive_string *as,
+ unsigned int codepage, const wchar_t *w)
+{
+ char *p;
+ int l, wl;
+ BOOL useDefaultChar = FALSE;
+
+ wl = (int)wcslen(w);
+ l = wl * 4 + 4;
+ p = malloc(l);
+ if (p == NULL)
+ __archive_errx(1, "Out of memory");
+ /* To check a useDefaultChar is to simulate error handling of
+ * the my_wcstombs() which is running on non Windows system with
+ * wctomb().
+ * And to set NULL for last argument is necessary when a codepage
+ * is not CP_ACP(current locale).
+ */
+ l = WideCharToMultiByte(codepage, 0, w, wl, p, l, NULL,
+ (codepage == CP_ACP) ? &useDefaultChar : NULL);
+ if (l == 0 || useDefaultChar) {
+ free(p);
+ return (NULL);
+ }
+ __archive_string_append(as, p, l);
+ free(p);
+ return (as);
+}
+
+/*
+ * Translates a wide character string into UTF-8 and appends
+ * to the archive_string. Note: returns NULL if conversion fails.
+ */
+struct archive_string *
+__archive_strappend_w_utf8(struct archive_string *as, const wchar_t *w)
+{
+
+ return (my_archive_strappend_w(as, CP_UTF8, w));
+}
+
+/*
+ * Translates a wide character string into current locale character set
+ * and appends to the archive_string. Note: returns NULL if conversion
+ * fails.
+ */
+struct archive_string *
+__archive_strappend_w_mbs(struct archive_string *as, const wchar_t *w)
+{
+
+ return (my_archive_strappend_w(as, CP_ACP, w));
+}
+
+/*
+ * Return a wide-character string by converting this archive_string
+ * from UTF-8.
+ */
+wchar_t *
+__archive_string_utf8_w(struct archive_string *as)
+{
+ wchar_t *ws;
+ int n;
+
+ ws = (wchar_t *)malloc((as->length + 1) * sizeof(wchar_t));
+ if (ws == NULL)
+ __archive_errx(1, "Out of memory");
+ n = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
+ as->s, (int)as->length, ws, (int)as->length);
+ if (n == 0) {
+ free(ws);
+ return (NULL);
+ }
+ ws[n] = L'\0';
+ return (ws);
+}
+
+#endif /* !_WIN32 */