diff options
author | Tim Kientzle <kientzle@FreeBSD.org> | 2009-03-03 17:02:51 +0000 |
---|---|---|
committer | Tim Kientzle <kientzle@FreeBSD.org> | 2009-03-03 17:02:51 +0000 |
commit | 690f818afd6c3c0721202dd1e075aeaaae004704 (patch) | |
tree | 1dee8b4b9c023077ab174a6dc9ffbb460e86b36b /lib/libarchive/archive_string.c | |
parent | 6b0ff427a57b12372e9b7181e92e50b17c773ca9 (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.c | 84 |
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 */ |