1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 // ---------------------------------------------------------------------------
8 // ---------------------------------------------------------------------------
21 #pragma optimize("t", on)
24 #define MAX_LENGTH 0x1fffff00
27 HRESULT Unicode_Utf8_Length(__in_z LPCWSTR pString, __out bool * pAllAscii, __out DWORD * pLength)
44 // Single check for termination and non ASCII
45 if (((unsigned) (ch - 1)) >= 0x7F)
60 if ((p - pString) > MAX_LENGTH)
62 return COR_E_OVERFLOW;
65 * pLength = (DWORD) (p - pString);
67 else // use WideCharToMultiByte to calculate result length
69 * pLength = WszWideCharToMultiByte(CP_UTF8, 0, pString, -1, NULL, 0, NULL, NULL);
73 return HRESULT_FROM_GetLastError();
76 // Remove the count of null terminator, to be consistent with the all-ASCII case.
79 if (*pLength > MAX_LENGTH)
81 return COR_E_OVERFLOW;
90 HRESULT Unicode_Utf8(__in_z LPCWSTR pString, bool allAscii, __out_z LPSTR pBuffer, DWORD length)
107 LPCWSTR endP = p + length - 8;
109 // Unfold to optimize for long string: 8 chars per iteration
130 * q ++ = (char) * p ++;
135 length = WszWideCharToMultiByte(CP_UTF8, 0, pString, -1, pBuffer, (int) length + 1, NULL, NULL);
139 return HRESULT_FROM_GetLastError();
147 HRESULT Utf8_Unicode_Length(__in_z LPCSTR pString, __out bool * pAllAscii, __out DWORD * pLength)
164 // Single check for termination and non ASCII
165 if (((unsigned) (ch - 1)) >= 0x7F)
180 if ((p - pString) > MAX_LENGTH)
182 return COR_E_OVERFLOW;
185 * pLength = (DWORD)(p - pString);
189 * pLength = WszMultiByteToWideChar(CP_UTF8, 0, pString, -1, NULL, 0);
193 return HRESULT_FROM_GetLastError();
196 // Remove the count of null terminator, to be consistent with the all-ASCII case.
199 if (* pLength > MAX_LENGTH)
201 return COR_E_OVERFLOW;
211 HRESULT Utf8_Unicode(__in_z LPCSTR pString, bool allAscii, __out_z LPWSTR pBuffer, DWORD length)
228 LPCSTR endP = p + length - 8;
230 // Unfold to optimize for long string: 4 chars per iteration
251 * q ++ = (WCHAR) * p ++;
256 length = WszMultiByteToWideChar(CP_UTF8, 0, pString, -1, pBuffer, (int) length + 1);
260 return HRESULT_FROM_GetLastError();
268 HRESULT ConvertUnicode_Utf8(__in_z LPCWSTR pString, __out_z LPSTR * pBuffer)
273 HRESULT hr = Unicode_Utf8_Length(pString, & allAscii, & length);
277 * pBuffer = new (nothrow) char[length + 1];
279 if (* pBuffer == NULL)
285 hr = Unicode_Utf8(pString, allAscii, * pBuffer, length);
293 HRESULT ConvertUtf8_Unicode(__in_z LPCSTR pString, __out_z LPWSTR * pBuffer)
298 HRESULT hr = Utf8_Unicode_Length(pString, & allAscii, & length);
302 * pBuffer = new (nothrow) WCHAR[length + 1];
304 if (* pBuffer == NULL)
310 hr = Utf8_Unicode(pString, allAscii, * pBuffer, length);
319 #pragma optimize("", on)
322 } // namespace FString