/*
Function:
-ToUpperSimple
-*/
-extern "C" void ToUpperSimple(const UChar* lpSrc, int32_t cwSrcLength, UChar* lpDst, int32_t cwDstLength)
-{
- int32_t srcIdx = 0;
- int32_t dstIdx = 0;
-
- UBool isError = FALSE;
+ChangeCase
- while (srcIdx < cwSrcLength)
- {
- UChar32 srcCodepoint;
- UChar32 dstCodepoint;
-
- U16_NEXT(lpSrc, srcIdx, cwSrcLength, srcCodepoint);
- dstCodepoint = u_toupper(srcCodepoint);
-
- U16_APPEND(lpDst, dstIdx, cwDstLength, dstCodepoint, isError);
-
- // Ensure that we wrote the data and the source codepoint when encoded in UTF16 is the same
- // number of code units as the cased codepoint.
- assert(isError == FALSE && srcIdx == dstIdx);
- }
-}
-
-/*
-Function:
-ToLowerSimple
+Preforms upper or lower casing of a string into a new buffer, preforming special casing for turkish, if needed.
*/
-extern "C" void ToLowerSimple(const UChar* lpSrc, int32_t cwSrcLength, UChar* lpDst, int32_t cwDstLength)
+extern "C" void ChangeCase(const UChar* lpSrc, int32_t cwSrcLength, UChar* lpDst, int32_t cwDstLength, int32_t bToUpper, int32_t bTurkishCasing)
{
int32_t srcIdx = 0;
int32_t dstIdx = 0;
UChar32 srcCodepoint;
UChar32 dstCodepoint;
+ // Decode the next one or two UTF-16 code units into a codepoint and update srcIdx to point to the next UTF-16 code unit to decode.
U16_NEXT(lpSrc, srcIdx, cwSrcLength, srcCodepoint);
- dstCodepoint = u_tolower(srcCodepoint);
-
- U16_APPEND(lpDst, dstIdx, cwDstLength, dstCodepoint, isError);
-
- // Ensure that we wrote the data and the source codepoint when encoded in UTF16 is the same
- // number of code units as the cased codepoint.
- assert(isError == FALSE && srcIdx == dstIdx);
- }
-}
-
-/*
-Function:
-ToUpperSimpleTurkishAzeri
-*/
-extern "C" void ToUpperSimpleTurkishAzeri(const UChar* lpSrc, int32_t cwSrcLength, UChar* lpDst, int32_t cwDstLength)
-{
- int32_t srcIdx = 0;
- int32_t dstIdx = 0;
-
- UBool isError = FALSE;
-
- while (srcIdx < cwSrcLength)
- {
- UChar32 srcCodepoint;
- UChar32 dstCodepoint;
-
- U16_NEXT(lpSrc, srcIdx, cwSrcLength, srcCodepoint);
-
- dstCodepoint = ((srcCodepoint == (UChar32)0x0069) ? (UChar32)0x0130 : u_toupper(srcCodepoint));
-
- U16_APPEND(lpDst, dstIdx, cwDstLength, dstCodepoint, isError);
-
- // Ensure that we wrote the data and the source codepoint when encoded in UTF16 is the same
- // number of code units as the cased codepoint.
- assert(isError == FALSE && srcIdx == dstIdx);
- }
-}
-
-/*
-Function:
-ToLowerSimpleTurkishAzeri
-*/
-extern "C" void ToLowerSimpleTurkishAzeri(const UChar* lpSrc, int32_t cwSrcLength, UChar* lpDst, int32_t cwDstLength)
-{
- int32_t srcIdx = 0;
- int32_t dstIdx = 0;
-
- UBool isError = FALSE;
-
- while (srcIdx < cwSrcLength)
- {
- UChar32 srcCodepoint;
- UChar32 dstCodepoint;
-
- U16_NEXT(lpSrc, srcIdx, cwSrcLength, srcCodepoint);
-
- dstCodepoint = ((srcCodepoint == (UChar32)0x0049) ? (UChar32)0x0131 : u_tolower(srcCodepoint));
+ if (bToUpper)
+ {
+ if (!bTurkishCasing)
+ {
+ dstCodepoint = u_toupper(srcCodepoint);
+ }
+ else
+ {
+ // In turkish casing, LATIN SMALL LETTER I (U+0069) upper cases to LATIN CAPITAL LETTER I WITH DOT ABOVE (U+0130).
+ dstCodepoint = ((srcCodepoint == (UChar32)0x0069) ? (UChar32)0x0130 : u_toupper(srcCodepoint));
+ }
+ }
+ else
+ {
+ if (!bTurkishCasing)
+ {
+ dstCodepoint = u_tolower(srcCodepoint);
+ }
+ else
+ {
+ // In turkish casing, LATIN CAPITAL LETTER I (U+0049) lower cases to LATIN SMALL LETTER DOTLESS I (U+0131).
+ dstCodepoint = ((srcCodepoint == (UChar32)0x0049) ? (UChar32)0x0131 : u_tolower(srcCodepoint));
+ }
+ }
+
+ // Write dstCodepoint into lpDst at offset dstIdx and update dstIdx.
U16_APPEND(lpDst, dstIdx, cwDstLength, dstCodepoint, isError);
// Ensure that we wrote the data and the source codepoint when encoded in UTF16 is the same
using System;
using System.Runtime.InteropServices;
+using System.Text;
internal static partial class Interop
{
internal static partial class GlobalizationInterop
{
[DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode)]
- internal unsafe static extern void ToUpperSimple(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity);
+ internal unsafe static extern void ChangeCase(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bIsUpper, bool bTurkishCasing);
[DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode)]
- internal unsafe static extern void ToLowerSimple(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity);
-
- [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode)]
- internal unsafe static extern void ToUpperSimpleTurkishAzeri(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity);
-
- [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode)]
- internal unsafe static extern void ToLowerSimpleTurkishAzeri(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity);
+ internal unsafe static extern void ChangeCase(string src, int srcLen, StringBuilder dstBuffer, int dstBufferCapacity, bool bIsUpper, bool bTurkishCasing);
}
}
{
Contract.Assert(s != null);
- char[] dstBuf = new char[s.Length];
+ StringBuilder sb = StringBuilderCache.Acquire(s.Length);
- fixed (char* pSrc = s, pDst = dstBuf)
- {
- ChangeCaseCore(pSrc, s.Length, pDst, dstBuf.Length, toUpper);
- }
+ Interop.GlobalizationInterop.ChangeCase(s, s.Length, sb, sb.Capacity, toUpper, m_needsTurkishCasing);
- return new string(dstBuf);
+ return StringBuilderCache.GetStringAndRelease(sb);
}
[System.Security.SecuritySafeCritical]
pSrc[0] = c;
- ChangeCaseCore(pSrc, 1, pDst, 1, toUpper);
+ Interop.GlobalizationInterop.ChangeCase(pSrc, 1, pDst, 1, toUpper, m_needsTurkishCasing);
return pDst[0];
}
// ---- PAL layer ends here ----
// -----------------------------
- private unsafe void ChangeCaseCore(char* pSrc, int cchSrc, char* pDst, int cchDst, bool toUpper)
- {
- if (toUpper)
- {
- if (!m_needsTurkishCasing)
- {
- Interop.GlobalizationInterop.ToUpperSimple(pSrc, cchSrc, pDst, cchDst);
- }
- else
- {
- Interop.GlobalizationInterop.ToUpperSimpleTurkishAzeri(pSrc, cchSrc, pDst, cchDst);
- }
- }
- else
- {
- if (!m_needsTurkishCasing)
- {
- Interop.GlobalizationInterop.ToLowerSimple(pSrc, cchSrc, pDst, cchDst);
- }
- else
- {
- Interop.GlobalizationInterop.ToLowerSimpleTurkishAzeri(pSrc, cchSrc, pDst, cchDst);
- }
- }
- }
-
private bool NeedsTurkishCasing(string localeName)
{
Contract.Assert(localeName != null);