OSDN Git Service

Merge from feature_merge branch. Build TortoiseMerge successfully.
[tortoisegit/TortoiseGitJp.git] / src / Utils / UnicodeUtils.cpp
1 // TortoiseSVN - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2003-2006, 2008 - TortoiseSVN\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #include "StdAfx.h"\r
20 #include "unicodeutils.h"\r
21 \r
22 CUnicodeUtils::CUnicodeUtils(void)\r
23 {\r
24 }\r
25 \r
26 CUnicodeUtils::~CUnicodeUtils(void)\r
27 {\r
28 }\r
29 \r
30 #if defined(_MFC_VER) || defined(CSTRING_AVAILABLE)\r
31 \r
32 CStringA CUnicodeUtils::GetUTF8(const CStringW& string)\r
33 {\r
34         char * buf;\r
35         CStringA retVal;\r
36         int len = string.GetLength();\r
37         if (len==0)\r
38                 return retVal;\r
39         buf = retVal.GetBuffer(len*4 + 1);\r
40 //      SecureZeroMemory(buf, (string.GetLength()*4 + 1)*sizeof(char));\r
41         int lengthIncTerminator = WideCharToMultiByte(CP_UTF8, 0, string, -1, buf, len*4, NULL, NULL);\r
42         retVal.ReleaseBuffer(lengthIncTerminator-1);\r
43         return retVal;\r
44 }\r
45 \r
46 CStringA CUnicodeUtils::GetUTF8(const CStringA& string)\r
47 {\r
48         WCHAR * buf;\r
49         int len = string.GetLength();\r
50         if (len==0)\r
51                 return CStringA();\r
52         buf = new WCHAR[len*4 + 1];\r
53         SecureZeroMemory(buf, (len*4 + 1)*sizeof(WCHAR));\r
54         MultiByteToWideChar(CP_ACP, 0, string, -1, buf, len*4);\r
55         CStringW temp = CStringW(buf);\r
56         delete [] buf;\r
57         return (CUnicodeUtils::GetUTF8(temp));\r
58 }\r
59 \r
60 CString CUnicodeUtils::GetUnicode(const CStringA& string)\r
61 {\r
62         WCHAR * buf;\r
63         int len = string.GetLength();\r
64         if (len==0)\r
65                 return CString();\r
66         buf = new WCHAR[len*4 + 1];\r
67         SecureZeroMemory(buf, (len*4 + 1)*sizeof(WCHAR));\r
68         MultiByteToWideChar(CP_UTF8, 0, string, -1, buf, len*4);\r
69         CString ret = CString(buf);\r
70         delete [] buf;\r
71         return ret;\r
72 }\r
73 \r
74 CStringA CUnicodeUtils::ConvertWCHARStringToUTF8(const CString& string)\r
75 {\r
76         CStringA sRet;\r
77         char * buf;\r
78         buf = new char[string.GetLength()+1];\r
79         if (buf)\r
80         {\r
81                 int i=0;\r
82                 for ( ; i<string.GetLength(); ++i)\r
83                 {\r
84                         buf[i] = (char)string.GetAt(i);\r
85                 }\r
86                 buf[i] = 0;\r
87                 sRet = CStringA(buf);\r
88                 delete [] buf;\r
89         }\r
90         return sRet;\r
91 }\r
92 \r
93 #endif //_MFC_VER\r
94 \r
95 #ifdef UNICODE\r
96 std::string CUnicodeUtils::StdGetUTF8(const wide_string& wide)\r
97 {\r
98         int len = (int)wide.size();\r
99         if (len==0)\r
100                 return std::string();\r
101         int size = len*4;\r
102         char * narrow = new char[size];\r
103         int ret = WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), len, narrow, size-1, NULL, NULL);\r
104         narrow[ret] = 0;\r
105         std::string sRet = std::string(narrow);\r
106         delete [] narrow;\r
107         return sRet;\r
108 }\r
109 \r
110 wide_string CUnicodeUtils::StdGetUnicode(const std::string& multibyte)\r
111 {\r
112         int len = (int)multibyte.size();\r
113         if (len==0)\r
114                 return wide_string();\r
115         int size = len*4;\r
116         wchar_t * wide = new wchar_t[size];\r
117         int ret = MultiByteToWideChar(CP_UTF8, 0, multibyte.c_str(), len, wide, size - 1);\r
118         wide[ret] = 0;\r
119         wide_string sRet = wide_string(wide);\r
120         delete [] wide;\r
121         return sRet;\r
122 }\r
123 #endif\r
124 \r
125 std::string WideToMultibyte(const wide_string& wide)\r
126 {\r
127         char * narrow = new char[wide.length()*3+2];\r
128         BOOL defaultCharUsed;\r
129         int ret = (int)WideCharToMultiByte(CP_ACP, 0, wide.c_str(), (int)wide.size(), narrow, (int)wide.length()*3 - 1, ".", &defaultCharUsed);\r
130         narrow[ret] = 0;\r
131         std::string str = narrow;\r
132         delete[] narrow;\r
133         return str;\r
134 }\r
135 \r
136 std::string WideToUTF8(const wide_string& wide)\r
137 {\r
138         char * narrow = new char[wide.length()*3+2];\r
139         int ret = (int)WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), (int)wide.size(), narrow, (int)wide.length()*3 - 1, NULL, NULL);\r
140         narrow[ret] = 0;\r
141         std::string str = narrow;\r
142         delete[] narrow;\r
143         return str;\r
144 }\r
145 \r
146 wide_string MultibyteToWide(const std::string& multibyte)\r
147 {\r
148         size_t length = multibyte.length();\r
149         if (length == 0)\r
150                 return wide_string();\r
151 \r
152         wchar_t * wide = new wchar_t[multibyte.length()*2+2];\r
153         if (wide == NULL)\r
154                 return wide_string();\r
155         int ret = (int)MultiByteToWideChar(CP_ACP, 0, multibyte.c_str(), (int)multibyte.size(), wide, (int)length*2 - 1);\r
156         wide[ret] = 0;\r
157         wide_string str = wide;\r
158         delete[] wide;\r
159         return str;\r
160 }\r
161 \r
162 wide_string UTF8ToWide(const std::string& multibyte)\r
163 {\r
164         size_t length = multibyte.length();\r
165         if (length == 0)\r
166                 return wide_string();\r
167 \r
168         wchar_t * wide = new wchar_t[length*2+2];\r
169         if (wide == NULL)\r
170                 return wide_string();\r
171         int ret = (int)MultiByteToWideChar(CP_UTF8, 0, multibyte.c_str(), (int)multibyte.size(), wide, (int)length*2 - 1);\r
172         wide[ret] = 0;\r
173         wide_string str = wide;\r
174         delete[] wide;\r
175         return str;\r
176 }\r
177 #ifdef UNICODE\r
178 stdstring UTF8ToString(const std::string& string) {return UTF8ToWide(string);}\r
179 std::string StringToUTF8(const stdstring& string) {return WideToUTF8(string);}\r
180 #else\r
181 stdstring UTF8ToString(const std::string& string) {return WideToMultibyte(UTF8ToWide(string));}\r
182 std::string StringToUTF8(const stdstring& string) {return WideToUTF8(MultibyteToWide(string));}\r
183 #endif\r
184 \r
185 \r
186 #pragma warning(push)\r
187 #pragma warning(disable: 4200)\r
188 struct STRINGRESOURCEIMAGE\r
189 {\r
190         WORD nLength;\r
191         WCHAR achString[];\r
192 };\r
193 #pragma warning(pop)    // C4200\r
194 \r
195 int LoadStringEx(HINSTANCE hInstance, UINT uID, LPTSTR lpBuffer, int nBufferMax, WORD wLanguage)\r
196 {\r
197         const STRINGRESOURCEIMAGE* pImage;\r
198         const STRINGRESOURCEIMAGE* pImageEnd;\r
199         ULONG nResourceSize;\r
200         HGLOBAL hGlobal;\r
201         UINT iIndex;\r
202 #ifndef UNICODE\r
203         BOOL defaultCharUsed;\r
204 #endif\r
205         int ret;\r
206 \r
207         if (lpBuffer == NULL)\r
208                 return 0;\r
209         lpBuffer[0] = 0;\r
210         HRSRC hResource =  FindResourceEx(hInstance, RT_STRING, MAKEINTRESOURCE(((uID>>4)+1)), wLanguage);\r
211         if (!hResource)\r
212         {\r
213                 //try the default language before giving up!\r
214                 hResource = FindResource(hInstance, MAKEINTRESOURCE(((uID>>4)+1)), RT_STRING);\r
215                 if (!hResource)\r
216                         return 0;\r
217         }\r
218         hGlobal = LoadResource(hInstance, hResource);\r
219         if (!hGlobal)\r
220                 return 0;\r
221         pImage = (const STRINGRESOURCEIMAGE*)::LockResource(hGlobal);\r
222         if(!pImage)\r
223                 return 0;\r
224 \r
225         nResourceSize = ::SizeofResource(hInstance, hResource);\r
226         pImageEnd = (const STRINGRESOURCEIMAGE*)(LPBYTE(pImage)+nResourceSize);\r
227         iIndex = uID&0x000f;\r
228 \r
229         while ((iIndex > 0) && (pImage < pImageEnd))\r
230         {\r
231                 pImage = (const STRINGRESOURCEIMAGE*)(LPBYTE(pImage)+(sizeof(STRINGRESOURCEIMAGE)+(pImage->nLength*sizeof(WCHAR))));\r
232                 iIndex--;\r
233         }\r
234         if (pImage >= pImageEnd)\r
235                 return 0;\r
236         if (pImage->nLength == 0)\r
237                 return 0;\r
238 #ifdef UNICODE\r
239         ret = pImage->nLength;\r
240         if (ret > nBufferMax)\r
241                 ret = nBufferMax;\r
242         wcsncpy_s((wchar_t *)lpBuffer, nBufferMax, pImage->achString, ret);\r
243         lpBuffer[ret] = 0;\r
244 #else\r
245         ret = WideCharToMultiByte(CP_ACP, 0, pImage->achString, pImage->nLength, (LPSTR)lpBuffer, nBufferMax-1, ".", &defaultCharUsed);\r
246         lpBuffer[ret] = 0;\r
247 #endif\r
248         return ret;\r
249 }\r
250 \r