OSDN Git Service

Add emulation for an old conversion method between UTF-8 and UTF-16.
authors_kawamoto <s_kawamoto@users.sourceforge.jp>
Sun, 11 Mar 2012 15:47:38 +0000 (00:47 +0900)
committers_kawamoto <s_kawamoto@users.sourceforge.jp>
Sun, 11 Mar 2012 15:47:38 +0000 (00:47 +0900)
FFFTP_Eng_Release/FFFTP.exe
Release/FFFTP.exe
config.h
mbswrapper.c
mbswrapper.h
putty/Release/PuTTY.dll
putty/mbswrapper.c
putty/mbswrapper.h
socketwrapper.c

index e95ea8a..440c244 100644 (file)
Binary files a/FFFTP_Eng_Release/FFFTP.exe and b/FFFTP_Eng_Release/FFFTP.exe differ
index b94c9be..ba91572 100644 (file)
Binary files a/Release/FFFTP.exe and b/Release/FFFTP.exe differ
index 50a28a2..c6365fa 100644 (file)
--- a/config.h
+++ b/config.h
 #define DISABLE_JRE32DLL\r
 // ファイル転送の同時接続数\r
 #define MAX_DATA_CONNECTION 4\r
+// 現在のコードページをShift_JISで置換する\r
+#define FORCE_SJIS_ON_ACTIVE_CODE_PAGE\r
+// UTF-8 UTF-16 LE間の変換処理でWindows XPのエミュレーションを行う\r
+#define EMULATE_UTF8_WCHAR_CONVERSION\r
 \r
 /* HP NonStop Server 用のコードを有効にする */\r
 #define HAVE_TANDEM\r
index 0128606..a051543 100644 (file)
@@ -390,47 +390,48 @@ char* DuplicateWtoA(LPCWSTR lpString, int c)
 \r
 // マルチバイト文字列からコードポイントと次のポインタを取得\r
 // エンコードが不正な場合は0x80000000を返す\r
-DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext)\r
+DWORD GetNextCharM(LPCSTR lpString, LPCSTR pLimit, LPCSTR* ppNext)\r
 {\r
        DWORD Code;\r
        int i;\r
        Code = 0;\r
-       if((*lpString & 0xfe) == 0xfc)\r
-       {\r
-               i = 5;\r
-               Code |= (DWORD)*lpString & 0x01;\r
-       }\r
-       else if((*lpString & 0xfc) == 0xf8)\r
-       {\r
-               i = 4;\r
-               Code |= (DWORD)*lpString & 0x03;\r
-       }\r
-       else if((*lpString & 0xf8) == 0xf0)\r
-       {\r
-               i = 3;\r
-               Code |= (DWORD)*lpString & 0x07;\r
-       }\r
-       else if((*lpString & 0xf0) == 0xe0)\r
-       {\r
-               i = 2;\r
-               Code |= (DWORD)*lpString & 0x0f;\r
-       }\r
-       else if((*lpString & 0xe0) == 0xc0)\r
-       {\r
-               i = 1;\r
-               Code |= (DWORD)*lpString & 0x1f;\r
-       }\r
-       else if((*lpString & 0x80) == 0x00)\r
-       {\r
-               i = 0;\r
-               Code |= (DWORD)*lpString & 0x7f;\r
-       }\r
-       else\r
-               i = -1;\r
-       if(*lpString != 0x00)\r
+       i = -1;\r
+       if(!pLimit)\r
+               pLimit = (LPCSTR)(~0);\r
+       if(lpString < pLimit)\r
        {\r
+               if((*lpString & 0xfe) == 0xfc)\r
+               {\r
+                       i = 5;\r
+                       Code |= (DWORD)*lpString & 0x01;\r
+               }\r
+               else if((*lpString & 0xfc) == 0xf8)\r
+               {\r
+                       i = 4;\r
+                       Code |= (DWORD)*lpString & 0x03;\r
+               }\r
+               else if((*lpString & 0xf8) == 0xf0)\r
+               {\r
+                       i = 3;\r
+                       Code |= (DWORD)*lpString & 0x07;\r
+               }\r
+               else if((*lpString & 0xf0) == 0xe0)\r
+               {\r
+                       i = 2;\r
+                       Code |= (DWORD)*lpString & 0x0f;\r
+               }\r
+               else if((*lpString & 0xe0) == 0xc0)\r
+               {\r
+                       i = 1;\r
+                       Code |= (DWORD)*lpString & 0x1f;\r
+               }\r
+               else if((*lpString & 0x80) == 0x00)\r
+               {\r
+                       i = 0;\r
+                       Code |= (DWORD)*lpString & 0x7f;\r
+               }\r
                lpString++;\r
-               while((*lpString & 0xc0) == 0x80)\r
+               while(lpString < pLimit && i > 0 && (*lpString & 0xc0) == 0x80)\r
                {\r
                        i--;\r
                        Code = Code << 6;\r
@@ -438,8 +439,6 @@ DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext)
                        lpString++;\r
                }\r
        }\r
-       else\r
-               lpString++;\r
        if(i != 0)\r
                Code = 0x80000000;\r
        if(ppNext)\r
@@ -447,6 +446,138 @@ DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext)
        return Code;\r
 }\r
 \r
+// マルチバイト文字列へコードポイントの文字を追加して次のポインタを取得\r
+// 文字の長さを返す\r
+int PutNextCharM(LPSTR lpString, LPSTR pLimit, LPSTR* ppNext, DWORD Code)\r
+{\r
+       int Count;\r
+       int i;\r
+       Count = 0;\r
+       i = -1;\r
+       if(!pLimit)\r
+               pLimit = (LPSTR)(~0);\r
+       if(lpString < pLimit)\r
+       {\r
+               if(Code & 0x7c000000)\r
+               {\r
+                       i = 5;\r
+                       *lpString = 0xfc | ((CHAR)(Code >> 30) & 0x01);\r
+               }\r
+               else if(Code & 0x03e00000)\r
+               {\r
+                       i = 4;\r
+                       *lpString = 0xf8 | ((CHAR)(Code >> 24) & 0x03);\r
+               }\r
+               else if(Code & 0x001f0000)\r
+               {\r
+                       i = 3;\r
+                       *lpString = 0xf0 | ((CHAR)(Code >> 18) & 0x07);\r
+               }\r
+               else if(Code & 0x0000f800)\r
+               {\r
+                       i = 2;\r
+                       *lpString = 0xe0 | ((CHAR)(Code >> 12) & 0x0f);\r
+               }\r
+               else if(Code & 0x00000780)\r
+               {\r
+                       i = 1;\r
+                       *lpString = 0xc0 | ((CHAR)(Code >> 6) & 0x1f);\r
+               }\r
+               else\r
+               {\r
+                       i = 0;\r
+                       *lpString = (CHAR)Code & 0x7f;\r
+               }\r
+               Count = i + 1;\r
+               lpString++;\r
+               while(lpString < pLimit && i > 0)\r
+               {\r
+                       i--;\r
+                       *lpString = 0x80 | ((CHAR)(Code >> (i * 6)) & 0x3f);\r
+                       lpString++;\r
+               }\r
+       }\r
+       if(i != 0)\r
+               Count = 0;\r
+       if(ppNext)\r
+               *ppNext = lpString;\r
+       return Count;\r
+}\r
+\r
+// ワイド文字列からコードポイントと次のポインタを取得\r
+// エンコードが不正な場合は0x80000000を返す\r
+DWORD GetNextCharW(LPCWSTR lpString, LPCWSTR pLimit, LPCWSTR* ppNext)\r
+{\r
+       DWORD Code;\r
+       Code = 0x80000000;\r
+       if(!pLimit)\r
+               pLimit = (LPCWSTR)(~0);\r
+       if(lpString < pLimit)\r
+       {\r
+               if((*lpString & 0xf800) == 0xd800)\r
+               {\r
+                       if((*lpString & 0x0400) == 0x0400)\r
+                       {\r
+                               Code = (DWORD)*lpString & 0x03ff;\r
+                               lpString++;\r
+                               if(lpString < pLimit)\r
+                               {\r
+                                       if((*lpString & 0x0400) == 0x0000)\r
+                                       {\r
+                                               Code |= ((DWORD)*lpString & 0x03ff) << 10;\r
+                                               lpString++;\r
+                                       }\r
+                                       else\r
+                                               Code = 0x80000000;\r
+                               }\r
+                               else\r
+                                       Code = 0x80000000;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       Code = (DWORD)*lpString;\r
+                       lpString++;\r
+               }\r
+       }\r
+       if(ppNext)\r
+               *ppNext = lpString;\r
+       return Code;\r
+}\r
+\r
+// ワイド文字列へコードポイントの文字を追加して次のポインタを取得\r
+// 文字の長さを返す\r
+int PutNextCharW(LPWSTR lpString, LPWSTR pLimit, LPWSTR* ppNext, DWORD Code)\r
+{\r
+       int Count;\r
+       Count = 0;\r
+       if(!pLimit)\r
+               pLimit = (LPWSTR)(~0);\r
+       if(lpString < pLimit)\r
+       {\r
+               if((Code & 0x7fff0000) || (Code & 0x0000f800) == 0x0000d800)\r
+               {\r
+                       *lpString = 0xdc00 | ((WCHAR)Code & 0x03ff);\r
+                       lpString++;\r
+                       if(lpString < pLimit)\r
+                       {\r
+                               *lpString = 0xd800 | ((WCHAR)(Code >> 10) & 0x03ff);\r
+                               lpString++;\r
+                               Count = 2;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       *lpString = (WCHAR)Code;\r
+                       lpString++;\r
+                       Count = 1;\r
+               }\r
+       }\r
+       if(ppNext)\r
+               *ppNext = lpString;\r
+       return Count;\r
+}\r
+\r
 // マルチバイト文字列の冗長表現を修正\r
 // 修正があればTRUEを返す\r
 // 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
@@ -461,7 +592,7 @@ BOOL FixStringM(LPSTR pDst, LPCSTR pSrc)
        p = (char*)pSrc;\r
        while(*pSrc != '\0')\r
        {\r
-               Code = GetNextCharM(pSrc, &pSrc);\r
+               Code = GetNextCharM(pSrc, NULL, &pSrc);\r
                if(Code & 0x80000000)\r
                        continue;\r
                else if(Code & 0x7c000000)\r
@@ -576,6 +707,82 @@ void FreeDuplicatedString(void* p)
        free(p);\r
 }\r
 \r
+// マルチバイト文字列からワイド文字列へ変換\r
+// UTF-8からUTF-16 LEへの変換専用\r
+int MultiByteToWideCharAlternative(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar)\r
+{\r
+       int WideCount;\r
+       LPCSTR pMultiLimit;\r
+       LPWSTR pWideLimit;\r
+       DWORD Code;\r
+       WCHAR Temp[8];\r
+       if(CodePage != CP_UTF8 || dwFlags != 0)\r
+               return MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar);\r
+       WideCount = 0;\r
+       if(cbMultiByte == -1)\r
+               pMultiLimit = lpMultiByteStr + strlen(lpMultiByteStr) + 1;\r
+       else\r
+               pMultiLimit = lpMultiByteStr + cbMultiByte;\r
+       pWideLimit = lpWideCharStr + cchWideChar;\r
+       while(lpMultiByteStr < pMultiLimit)\r
+       {\r
+               Code = GetNextCharM(lpMultiByteStr, pMultiLimit, &lpMultiByteStr);\r
+               if(Code == 0x80000000)\r
+                       continue;\r
+               if(lpWideCharStr)\r
+               {\r
+                       WideCount += PutNextCharW(lpWideCharStr, pWideLimit, &lpWideCharStr, Code);\r
+                       if(lpWideCharStr >= pWideLimit)\r
+                       {\r
+                               WideCount = 0;\r
+                               break;\r
+                       }\r
+               }\r
+               else\r
+                       WideCount += PutNextCharW(Temp, NULL, NULL, Code);\r
+       }\r
+       return WideCount;\r
+}\r
+\r
+// ワイド文字列からマルチバイト文字列へ変換\r
+// UTF-16 LEからUTF-8への変換専用\r
+int WideCharToMultiByteAlternative(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)\r
+{\r
+       int MultiCount;\r
+       LPCWSTR pWideLimit;\r
+       LPSTR pMultiLimit;\r
+       DWORD Code;\r
+       CHAR Temp[8];\r
+       if(CodePage != CP_UTF8 || dwFlags != 0)\r
+               return WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar);\r
+       MultiCount = 0;\r
+       if(cchWideChar == -1)\r
+               pWideLimit = lpWideCharStr + wcslen(lpWideCharStr) + 1;\r
+       else\r
+               pWideLimit = lpWideCharStr + cchWideChar;\r
+       pMultiLimit = lpMultiByteStr + cbMultiByte;\r
+       while(lpWideCharStr < pWideLimit)\r
+       {\r
+               Code = GetNextCharW(lpWideCharStr, pWideLimit, &lpWideCharStr);\r
+               if(Code == 0x80000000)\r
+                       continue;\r
+               if(lpMultiByteStr)\r
+               {\r
+                       MultiCount += PutNextCharM(lpMultiByteStr, pMultiLimit, &lpMultiByteStr, Code);\r
+                       if(lpMultiByteStr >= pMultiLimit)\r
+                       {\r
+                               MultiCount = 0;\r
+                               break;\r
+                       }\r
+               }\r
+               else\r
+                       MultiCount += PutNextCharM(Temp, NULL, NULL, Code);\r
+       }\r
+       if(lpUsedDefaultChar)\r
+               *lpUsedDefaultChar = FALSE;\r
+       return MultiCount;\r
+}\r
+\r
 // 以下ラッパー\r
 // 戻り値バッファ r\r
 // ワイド文字バッファ pw%d\r
@@ -2261,7 +2468,7 @@ size_t _mbslenM(const unsigned char * _Str)
 {\r
        size_t r = 0;\r
 START_ROUTINE\r
-       while(GetNextCharM(_Str, &_Str) > 0)\r
+       while(GetNextCharM(_Str, NULL, &_Str) > 0)\r
        {\r
                r++;\r
        }\r
@@ -2275,7 +2482,7 @@ unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)
        unsigned int c;\r
        unsigned char* p;\r
 START_ROUTINE\r
-       while((c = GetNextCharM(_Str, &p)) > 0)\r
+       while((c = GetNextCharM(_Str, NULL, &p)) > 0)\r
        {\r
                if(c == _Ch)\r
                        break;\r
@@ -2293,7 +2500,7 @@ unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)
        unsigned int c;\r
        unsigned char* p;\r
 START_ROUTINE\r
-       while((c = GetNextCharM(_Str, &p)) > 0)\r
+       while((c = GetNextCharM(_Str, NULL, &p)) > 0)\r
        {\r
                if(c == _Ch)\r
                        r = (unsigned char*)_Str;\r
@@ -2342,8 +2549,8 @@ START_ROUTINE
        c2 = 0;\r
        while(_MaxCount > 0)\r
        {\r
-               c1 = GetNextCharM(_Str1, &_Str1);\r
-               c2 = GetNextCharM(_Str2, &_Str2);\r
+               c1 = GetNextCharM(_Str1, NULL, &_Str1);\r
+               c2 = GetNextCharM(_Str2, NULL, &_Str2);\r
                if(c1 != c2)\r
                        break;\r
                _MaxCount--;\r
@@ -2377,7 +2584,7 @@ unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)
 {\r
        unsigned char* r = NULL;\r
 START_ROUTINE\r
-       while(_Count > 0 && GetNextCharM(_Str, &_Str) > 0)\r
+       while(_Count > 0 && GetNextCharM(_Str, NULL, &_Str) > 0)\r
        {\r
                _Count--;\r
        }\r
index 76f336f..0fa455f 100644 (file)
@@ -241,8 +241,15 @@ FILE * fopenM(const char * _Filename, const char * _Mode);
 \r
 #endif\r
 \r
+#ifdef FORCE_SJIS_ON_ACTIVE_CODE_PAGE\r
 #undef CP_ACP\r
 #define CP_ACP 932\r
+#endif\r
+\r
+#ifdef EMULATE_UTF8_WCHAR_CONVERSION\r
+#define MultiByteToWideChar MultiByteToWideCharAlternative\r
+#define WideCharToMultiByte WideCharToMultiByteAlternative\r
+#endif\r
 \r
 int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count);\r
 int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count);\r
@@ -268,12 +275,17 @@ wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size);
 char* DuplicateWtoM(LPCWSTR lpString, int c);\r
 wchar_t* DuplicateAtoW(LPCSTR lpString, int c);\r
 char* DuplicateWtoA(LPCWSTR lpString, int c);\r
-DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext);\r
+DWORD GetNextCharM(LPCSTR lpString, LPCSTR pLimit, LPCSTR* ppNext);\r
+int PutNextCharM(LPSTR lpString, LPSTR pLimit, LPSTR* ppNext, DWORD Code);\r
+DWORD GetNextCharW(LPCWSTR lpString, LPCWSTR pLimit, LPCWSTR* ppNext);\r
+int PutNextCharW(LPWSTR lpString, LPWSTR pLimit, LPWSTR* ppNext, DWORD Code);\r
 BOOL FixStringM(LPSTR pDst, LPCSTR pSrc);\r
 BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc);\r
 BOOL CheckStringM(LPCSTR lpString);\r
 BOOL CheckMultiStringM(LPCSTR lpString);\r
 void FreeDuplicatedString(void* p);\r
+int MultiByteToWideCharAlternative(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);\r
+int WideCharToMultiByteAlternative(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);\r
 \r
 int WINAPI WinMainM(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);\r
 \r
index c664458..42572d6 100644 (file)
Binary files a/putty/Release/PuTTY.dll and b/putty/Release/PuTTY.dll differ
index ce29117..1741a00 100644 (file)
@@ -390,56 +390,192 @@ char* DuplicateWtoA(LPCWSTR lpString, int c)
 \r
 // マルチバイト文字列からコードポイントと次のポインタを取得\r
 // エンコードが不正な場合は0x80000000を返す\r
-DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext)\r
+DWORD GetNextCharM(LPCSTR lpString, LPCSTR pLimit, LPCSTR* ppNext)\r
 {\r
        DWORD Code;\r
        int i;\r
        Code = 0;\r
-       if((*lpString & 0xfe) == 0xfc)\r
+       i = -1;\r
+       if(!pLimit)\r
+               pLimit = (LPCSTR)(~0);\r
+       if(lpString < pLimit)\r
        {\r
-               i = 5;\r
-               Code |= (DWORD)*lpString & 0x01;\r
-       }\r
-       else if((*lpString & 0xfc) == 0xf8)\r
-       {\r
-               i = 4;\r
-               Code |= (DWORD)*lpString & 0x03;\r
-       }\r
-       else if((*lpString & 0xf8) == 0xf0)\r
-       {\r
-               i = 3;\r
-               Code |= (DWORD)*lpString & 0x07;\r
-       }\r
-       else if((*lpString & 0xf0) == 0xe0)\r
-       {\r
-               i = 2;\r
-               Code |= (DWORD)*lpString & 0x0f;\r
+               if((*lpString & 0xfe) == 0xfc)\r
+               {\r
+                       i = 5;\r
+                       Code |= (DWORD)*lpString & 0x01;\r
+               }\r
+               else if((*lpString & 0xfc) == 0xf8)\r
+               {\r
+                       i = 4;\r
+                       Code |= (DWORD)*lpString & 0x03;\r
+               }\r
+               else if((*lpString & 0xf8) == 0xf0)\r
+               {\r
+                       i = 3;\r
+                       Code |= (DWORD)*lpString & 0x07;\r
+               }\r
+               else if((*lpString & 0xf0) == 0xe0)\r
+               {\r
+                       i = 2;\r
+                       Code |= (DWORD)*lpString & 0x0f;\r
+               }\r
+               else if((*lpString & 0xe0) == 0xc0)\r
+               {\r
+                       i = 1;\r
+                       Code |= (DWORD)*lpString & 0x1f;\r
+               }\r
+               else if((*lpString & 0x80) == 0x00)\r
+               {\r
+                       i = 0;\r
+                       Code |= (DWORD)*lpString & 0x7f;\r
+               }\r
+               lpString++;\r
+               while(lpString < pLimit && i > 0 && (*lpString & 0xc0) == 0x80)\r
+               {\r
+                       i--;\r
+                       Code = Code << 6;\r
+                       Code |= (DWORD)*lpString & 0x3f;\r
+                       lpString++;\r
+               }\r
        }\r
-       else if((*lpString & 0xe0) == 0xc0)\r
+       if(i != 0)\r
+               Code = 0x80000000;\r
+       if(ppNext)\r
+               *ppNext = lpString;\r
+       return Code;\r
+}\r
+\r
+// マルチバイト文字列へコードポイントの文字を追加して次のポインタを取得\r
+// 文字の長さを返す\r
+int PutNextCharM(LPSTR lpString, LPSTR pLimit, LPSTR* ppNext, DWORD Code)\r
+{\r
+       int Count;\r
+       int i;\r
+       Count = 0;\r
+       i = -1;\r
+       if(!pLimit)\r
+               pLimit = (LPSTR)(~0);\r
+       if(lpString < pLimit)\r
        {\r
-               i = 1;\r
-               Code |= (DWORD)*lpString & 0x1f;\r
+               if(Code & 0x7c000000)\r
+               {\r
+                       i = 5;\r
+                       *lpString = 0xfc | ((CHAR)(Code >> 30) & 0x01);\r
+               }\r
+               else if(Code & 0x03e00000)\r
+               {\r
+                       i = 4;\r
+                       *lpString = 0xf8 | ((CHAR)(Code >> 24) & 0x03);\r
+               }\r
+               else if(Code & 0x001f0000)\r
+               {\r
+                       i = 3;\r
+                       *lpString = 0xf0 | ((CHAR)(Code >> 18) & 0x07);\r
+               }\r
+               else if(Code & 0x0000f800)\r
+               {\r
+                       i = 2;\r
+                       *lpString = 0xe0 | ((CHAR)(Code >> 12) & 0x0f);\r
+               }\r
+               else if(Code & 0x00000780)\r
+               {\r
+                       i = 1;\r
+                       *lpString = 0xc0 | ((CHAR)(Code >> 6) & 0x1f);\r
+               }\r
+               else\r
+               {\r
+                       i = 0;\r
+                       *lpString = (CHAR)Code & 0x7f;\r
+               }\r
+               Count = i + 1;\r
+               lpString++;\r
+               while(lpString < pLimit && i > 0)\r
+               {\r
+                       i--;\r
+                       *lpString = 0x80 | ((CHAR)(Code >> (i * 6)) & 0x3f);\r
+                       lpString++;\r
+               }\r
        }\r
-       else if((*lpString & 0x80) == 0x00)\r
+       if(i != 0)\r
+               Count = 0;\r
+       if(ppNext)\r
+               *ppNext = lpString;\r
+       return Count;\r
+}\r
+\r
+// ワイド文字列からコードポイントと次のポインタを取得\r
+// エンコードが不正な場合は0x80000000を返す\r
+DWORD GetNextCharW(LPCWSTR lpString, LPCWSTR pLimit, LPCWSTR* ppNext)\r
+{\r
+       DWORD Code;\r
+       Code = 0x80000000;\r
+       if(!pLimit)\r
+               pLimit = (LPCWSTR)(~0);\r
+       if(lpString < pLimit)\r
        {\r
-               i = 0;\r
-               Code |= (DWORD)*lpString & 0x7f;\r
+               if((*lpString & 0xf800) == 0xd800)\r
+               {\r
+                       if((*lpString & 0x0400) == 0x0400)\r
+                       {\r
+                               Code = (DWORD)*lpString & 0x03ff;\r
+                               lpString++;\r
+                               if(lpString < pLimit)\r
+                               {\r
+                                       if((*lpString & 0x0400) == 0x0000)\r
+                                       {\r
+                                               Code |= ((DWORD)*lpString & 0x03ff) << 10;\r
+                                               lpString++;\r
+                                       }\r
+                                       else\r
+                                               Code = 0x80000000;\r
+                               }\r
+                               else\r
+                                       Code = 0x80000000;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       Code = (DWORD)*lpString;\r
+                       lpString++;\r
+               }\r
        }\r
-       else\r
-               i = -1;\r
-       lpString++;\r
-       while((*lpString & 0xc0) == 0x80)\r
+       if(ppNext)\r
+               *ppNext = lpString;\r
+       return Code;\r
+}\r
+\r
+// ワイド文字列へコードポイントの文字を追加して次のポインタを取得\r
+// 文字の長さを返す\r
+int PutNextCharW(LPWSTR lpString, LPWSTR pLimit, LPWSTR* ppNext, DWORD Code)\r
+{\r
+       int Count;\r
+       Count = 0;\r
+       if(!pLimit)\r
+               pLimit = (LPWSTR)(~0);\r
+       if(lpString < pLimit)\r
        {\r
-               i--;\r
-               Code = Code << 6;\r
-               Code |= (DWORD)*lpString & 0x3f;\r
-               lpString++;\r
+               if((Code & 0x7fff0000) || (Code & 0x0000f800) == 0x0000d800)\r
+               {\r
+                       *lpString = 0xdc00 | ((WCHAR)Code & 0x03ff);\r
+                       lpString++;\r
+                       if(lpString < pLimit)\r
+                       {\r
+                               *lpString = 0xd800 | ((WCHAR)(Code >> 10) & 0x03ff);\r
+                               lpString++;\r
+                               Count = 2;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       *lpString = (WCHAR)Code;\r
+                       lpString++;\r
+                       Count = 1;\r
+               }\r
        }\r
-       if(i != 0)\r
-               Code = 0x80000000;\r
        if(ppNext)\r
                *ppNext = lpString;\r
-       return Code;\r
+       return Count;\r
 }\r
 \r
 // マルチバイト文字列の冗長表現を修正\r
@@ -456,7 +592,7 @@ BOOL FixStringM(LPSTR pDst, LPCSTR pSrc)
        p = (char*)pSrc;\r
        while(*pSrc != '\0')\r
        {\r
-               Code = GetNextCharM(pSrc, &pSrc);\r
+               Code = GetNextCharM(pSrc, NULL, &pSrc);\r
                if(Code & 0x80000000)\r
                        continue;\r
                else if(Code & 0x7c000000)\r
@@ -571,6 +707,82 @@ void FreeDuplicatedString(void* p)
        free(p);\r
 }\r
 \r
+// マルチバイト文字列からワイド文字列へ変換\r
+// UTF-8からUTF-16 LEへの変換専用\r
+int MultiByteToWideCharAlternative(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar)\r
+{\r
+       int WideCount;\r
+       LPCSTR pMultiLimit;\r
+       LPWSTR pWideLimit;\r
+       DWORD Code;\r
+       WCHAR Temp[8];\r
+       if(CodePage != CP_UTF8 || dwFlags != 0)\r
+               return MultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar);\r
+       WideCount = 0;\r
+       if(cbMultiByte == -1)\r
+               pMultiLimit = lpMultiByteStr + strlen(lpMultiByteStr) + 1;\r
+       else\r
+               pMultiLimit = lpMultiByteStr + cbMultiByte;\r
+       pWideLimit = lpWideCharStr + cchWideChar;\r
+       while(lpMultiByteStr < pMultiLimit)\r
+       {\r
+               Code = GetNextCharM(lpMultiByteStr, pMultiLimit, &lpMultiByteStr);\r
+               if(Code == 0x80000000)\r
+                       continue;\r
+               if(lpWideCharStr)\r
+               {\r
+                       WideCount += PutNextCharW(lpWideCharStr, pWideLimit, &lpWideCharStr, Code);\r
+                       if(lpWideCharStr >= pWideLimit)\r
+                       {\r
+                               WideCount = 0;\r
+                               break;\r
+                       }\r
+               }\r
+               else\r
+                       WideCount += PutNextCharW(Temp, NULL, NULL, Code);\r
+       }\r
+       return WideCount;\r
+}\r
+\r
+// ワイド文字列からマルチバイト文字列へ変換\r
+// UTF-16 LEからUTF-8への変換専用\r
+int WideCharToMultiByteAlternative(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)\r
+{\r
+       int MultiCount;\r
+       LPCWSTR pWideLimit;\r
+       LPSTR pMultiLimit;\r
+       DWORD Code;\r
+       CHAR Temp[8];\r
+       if(CodePage != CP_UTF8 || dwFlags != 0)\r
+               return WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar);\r
+       MultiCount = 0;\r
+       if(cchWideChar == -1)\r
+               pWideLimit = lpWideCharStr + wcslen(lpWideCharStr) + 1;\r
+       else\r
+               pWideLimit = lpWideCharStr + cchWideChar;\r
+       pMultiLimit = lpMultiByteStr + cbMultiByte;\r
+       while(lpWideCharStr < pWideLimit)\r
+       {\r
+               Code = GetNextCharW(lpWideCharStr, pWideLimit, &lpWideCharStr);\r
+               if(Code == 0x80000000)\r
+                       continue;\r
+               if(lpMultiByteStr)\r
+               {\r
+                       MultiCount += PutNextCharM(lpMultiByteStr, pMultiLimit, &lpMultiByteStr, Code);\r
+                       if(lpMultiByteStr >= pMultiLimit)\r
+                       {\r
+                               MultiCount = 0;\r
+                               break;\r
+                       }\r
+               }\r
+               else\r
+                       MultiCount += PutNextCharM(Temp, NULL, NULL, Code);\r
+       }\r
+       if(lpUsedDefaultChar)\r
+               *lpUsedDefaultChar = FALSE;\r
+       return MultiCount;\r
+}\r
+\r
 // 以下ラッパー\r
 // 戻り値バッファ r\r
 // ワイド文字バッファ pw%d\r
@@ -828,7 +1040,7 @@ size_t _mbslenM(const unsigned char * _Str)
 {\r
        size_t r = 0;\r
 START_ROUTINE\r
-       while(GetNextCharM(_Str, &_Str) > 0)\r
+       while(GetNextCharM(_Str, NULL, &_Str) > 0)\r
        {\r
                r++;\r
        }\r
@@ -842,7 +1054,7 @@ unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)
        unsigned int c;\r
        unsigned char* p;\r
 START_ROUTINE\r
-       while((c = GetNextCharM(_Str, &p)) > 0)\r
+       while((c = GetNextCharM(_Str, NULL, &p)) > 0)\r
        {\r
                if(c == _Ch)\r
                        break;\r
@@ -860,7 +1072,7 @@ unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)
        unsigned int c;\r
        unsigned char* p;\r
 START_ROUTINE\r
-       while((c = GetNextCharM(_Str, &p)) > 0)\r
+       while((c = GetNextCharM(_Str, NULL, &p)) > 0)\r
        {\r
                if(c == _Ch)\r
                        r = (unsigned char*)_Str;\r
@@ -909,8 +1121,8 @@ START_ROUTINE
        c2 = 0;\r
        while(_MaxCount > 0)\r
        {\r
-               c1 = GetNextCharM(_Str1, &_Str1);\r
-               c2 = GetNextCharM(_Str2, &_Str2);\r
+               c1 = GetNextCharM(_Str1, NULL, &_Str1);\r
+               c2 = GetNextCharM(_Str2, NULL, &_Str2);\r
                if(c1 != c2)\r
                        break;\r
                _MaxCount--;\r
@@ -944,7 +1156,7 @@ unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)
 {\r
        unsigned char* r = NULL;\r
 START_ROUTINE\r
-       while(_Count > 0 && GetNextCharM(_Str, &_Str) > 0)\r
+       while(_Count > 0 && GetNextCharM(_Str, NULL, &_Str) > 0)\r
        {\r
                _Count--;\r
        }\r
index 9a3496d..eb639f7 100644 (file)
@@ -125,12 +125,17 @@ wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size);
 char* DuplicateWtoM(LPCWSTR lpString, int c);\r
 wchar_t* DuplicateAtoW(LPCSTR lpString, int c);\r
 char* DuplicateWtoA(LPCWSTR lpString, int c);\r
-DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext);\r
+DWORD GetNextCharM(LPCSTR lpString, LPCSTR pLimit, LPCSTR* ppNext);\r
+int PutNextCharM(LPSTR lpString, LPSTR pLimit, LPSTR* ppNext, DWORD Code);\r
+DWORD GetNextCharW(LPCWSTR lpString, LPCWSTR pLimit, LPCWSTR* ppNext);\r
+int PutNextCharW(LPWSTR lpString, LPWSTR pLimit, LPWSTR* ppNext, DWORD Code);\r
 BOOL FixStringM(LPSTR pDst, LPCSTR pSrc);\r
 BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc);\r
 BOOL CheckStringM(LPCSTR lpString);\r
 BOOL CheckMultiStringM(LPCSTR lpString);\r
 void FreeDuplicatedString(void* p);\r
+int MultiByteToWideCharAlternative(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);\r
+int WideCharToMultiByteAlternative(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);\r
 \r
 #endif\r
 \r
index caae589..5d45fdf 100644 (file)
@@ -902,7 +902,7 @@ BOOL ConvertDomainNameToPunycode(LPSTR Output, DWORD Count, LPCSTR Input)
                Length = 0;\r
                while(*InputString != '\0')\r
                {\r
-                       *p = (punycode_uint)GetNextCharM(InputString, &InputString);\r
+                       *p = (punycode_uint)GetNextCharM(InputString, NULL, &InputString);\r
                        if(*p >= 0x80)\r
                                bNeeded = TRUE;\r
                        p++;\r