From a0920c7b1d37909ac5faaa3f65dabf48f6a2d5be Mon Sep 17 00:00:00 2001 From: kichik Date: Sat, 11 Dec 2004 16:06:17 +0000 Subject: [PATCH] added implementation of Unicode conversion functions for POSIX, based on iconv git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3821 212acab6-be3b-0410-9dea-997c60f758d6 --- Source/Platform.h | 2 +- Source/util.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++++- Source/util.h | 16 +++----- 3 files changed, 100 insertions(+), 13 deletions(-) diff --git a/Source/Platform.h b/Source/Platform.h index 8072c982..ae0781c6 100644 --- a/Source/Platform.h +++ b/Source/Platform.h @@ -30,7 +30,7 @@ typedef long LONG; typedef unsigned long ULONG; typedef long long INT64, LARGE_INTEGER; typedef unsigned long long UINT64, ULARGE_INTEGER; -typedef int BOOL; +typedef int BOOL, *LPBOOL; typedef void VOID; typedef void *LPVOID; typedef char CHAR, *PCHAR, *LPCH, *PCH, *NPSTR, *LPSTR, *PSTR; diff --git a/Source/util.cpp b/Source/util.cpp index 643c9e12..0f87edd7 100644 --- a/Source/util.cpp +++ b/Source/util.cpp @@ -12,6 +12,7 @@ # include # include // for close(2) # include // for open(2) +# include #endif #include // for assert @@ -368,8 +369,8 @@ int generate_unicons_offsets(unsigned char* exeHeader, unsigned char* uninstIcon #endif // NSIS_CONFIG_UNINSTALL_SUPPORT // returns the number of WCHARs in str including null charcter -int WCStrLen(const WCHAR* szwStr) { - int i; +size_t WCStrLen(const WCHAR* szwStr) { + size_t i; for (i = 0; szwStr[i]; i++); return i+1; } @@ -402,6 +403,96 @@ int wsprintf(char *s, const char *format, ...) { return res; } +// iconv const inconsistency workaround by Alexandre Oliva +template +inline size_t __iconv_adaptor + (size_t (*iconv_func)(iconv_t, T, size_t *, char**,size_t*), + iconv_t cd, char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + return iconv_func (cd, (T)inbuf, inbytesleft, outbuf, outbytesleft); +} + +void static create_code_page_string(char *buf, size_t len, UINT code_page) { + if (code_page == CP_ACP) + code_page = 1252; + + snprintf(buf, len, "CP%d", code_page); +} + +int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, + int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, + LPBOOL lpUsedDefaultChar) { + static char buffer[4096]; + + char cp[128]; + create_code_page_string(cp, sizeof(cp), CodePage); + + iconv_t cd = iconv_open(cp, "UCS-2"); + if (cd == (iconv_t) -1) { + return 0; + } + + if (cchWideChar < 0) { + cchWideChar = (int) WCStrLen(lpWideCharStr); // including null char + } + + if (cbMultiByte == 0) { + cbMultiByte = sizeof(buffer); + lpMultiByteStr = buffer; + } + + char *in = (char *) lpWideCharStr; + char *out = lpMultiByteStr; + size_t inbytes = cchWideChar * sizeof(WCHAR); + size_t outbytes = cbMultiByte; + + if (__iconv_adaptor(iconv, cd, &in, &inbytes, &out, &outbytes) == (size_t) -1) { + iconv_close(cd); + return 0; + } + + iconv_close(cd); + + return cbMultiByte - outbytes; +} + +int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, + int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar) { + static WCHAR buffer[4096]; + + char cp[128]; + create_code_page_string(cp, sizeof(cp), CodePage); + + iconv_t cd = iconv_open("UCS-2", cp); + if (cd == (iconv_t) -1) { + return 0; + } + + if (cbMultiByte < 0) { + cbMultiByte = strlen(lpMultiByteStr) + 1; + } + + if (cchWideChar == 0) { + cchWideChar = sizeof(buffer); + lpWideCharStr = buffer; + } + + char *in = (char *) lpMultiByteStr; + char *out = (char *) lpWideCharStr; + size_t inbytes = cbMultiByte; + size_t outbytes = cchWideChar * sizeof(WCHAR); + + if (__iconv_adaptor(iconv, cd, &in, &inbytes, &out, &outbytes) == (size_t) -1) { + iconv_close(cd); + return 0; + } + + iconv_close(cd); + + return cchWideChar - (outbytes / sizeof (WCHAR)); +} + #define MY_ERROR_MSG(x) {if (g_display_errors) {fprintf(g_output,"%s", x);}} char *my_convert(const char *path) diff --git a/Source/util.h b/Source/util.h index d0b513a7..61aa005f 100644 --- a/Source/util.h +++ b/Source/util.h @@ -31,7 +31,7 @@ int generate_unicons_offsets(unsigned char* exeHeader, unsigned char* uninstIcon #endif//NSIS_CONFIG_UNINSTALL_SUPPORT // returns the number of WCHARs in str including null charcter -int WCStrLen(const WCHAR* szwStr); +size_t WCStrLen(const WCHAR* szwStr); size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm); @@ -55,15 +55,11 @@ std::string get_executable_dir(const char *argv0); char *CharPrev(const char *s, const char *p); char *CharNext(const char *s); int wsprintf(char *s, const char *format, ...); -// iconv const inconsistency workaround by Alexandre Oliva -template -inline size_t __iconv_adaptor - (size_t (*iconv_func)(iconv_t, T, size_t *, char**,size_t*), - iconv_t cd, char **inbuf, size_t *inbytesleft, - char **outbuf, size_t *outbytesleft) -{ - return iconv_func (cd, (T)inbuf, inbytesleft, outbuf, outbytesleft); -} +int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, + int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, + LPBOOL lpUsedDefaultChar); +int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, + int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar); char *my_convert(const char *path); void my_convert_free(char *converted_path);