summaryrefslogtreecommitdiff
path: root/src/mscorlib/corefx/System/Globalization/TextInfo.Win32.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/corefx/System/Globalization/TextInfo.Win32.cs')
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextInfo.Win32.cs114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/mscorlib/corefx/System/Globalization/TextInfo.Win32.cs b/src/mscorlib/corefx/System/Globalization/TextInfo.Win32.cs
new file mode 100644
index 0000000000..1a40b0b44a
--- /dev/null
+++ b/src/mscorlib/corefx/System/Globalization/TextInfo.Win32.cs
@@ -0,0 +1,114 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using System.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ public partial class TextInfo
+ {
+ //////////////////////////////////////////////////////////////////////////
+ ////
+ //// TextInfo Constructors
+ ////
+ //// Implements CultureInfo.TextInfo.
+ ////
+ //////////////////////////////////////////////////////////////////////////
+ internal unsafe TextInfo(CultureData cultureData)
+ {
+ const uint LCMAP_SORTHANDLE = 0x20000000;
+
+ // This is our primary data source, we don't need most of the rest of this
+ this.m_cultureData = cultureData;
+ this.m_cultureName = this.m_cultureData.CultureName;
+ this.m_textInfoName = this.m_cultureData.STEXTINFO;
+
+ long handle;
+ int ret = Interop.mincore.LCMapStringEx(m_textInfoName, LCMAP_SORTHANDLE, null, 0, (IntPtr)(&handle), IntPtr.Size, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
+
+ _sortHandle = ret > 0 ? (IntPtr)handle : IntPtr.Zero;
+ }
+
+ private unsafe string ChangeCase(string s, bool toUpper)
+ {
+ Contract.Assert(s != null);
+
+ //
+ // Get the length of the string.
+ //
+ int nLengthInput = s.Length;
+
+ //
+ // Check if we have the empty string.
+ //
+ if (nLengthInput == 0)
+ {
+ return s;
+ }
+ else
+ {
+ int result;
+
+ // Check for Invariant to avoid A/V in LCMapStringEx
+ uint linguisticCasing = IsInvariantLocale(m_textInfoName) ? 0 : LCMAP_LINGUISTIC_CASING;
+
+ //
+ // Create the result string.
+ //
+ char[] buffer = new char[nLengthInput];
+ fixed (char* pBuffer = buffer)
+ {
+ result = Interop.mincore.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : m_textInfoName,
+ toUpper ? LCMAP_UPPERCASE | linguisticCasing : LCMAP_LOWERCASE | linguisticCasing,
+ s,
+ nLengthInput,
+ (IntPtr)pBuffer,
+ nLengthInput,
+ IntPtr.Zero,
+ IntPtr.Zero,
+ _sortHandle);
+ }
+
+ if (0 == result)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
+
+ Contract.Assert(result == nLengthInput, "Expected getting the same length of the original string");
+ return new string(buffer, 0, result);
+ }
+ }
+
+ private unsafe char ChangeCase(char c, bool toUpper)
+ {
+ char retVal = '\0';
+
+ // Check for Invariant to avoid A/V in LCMapStringEx
+ uint linguisticCasing = IsInvariantLocale(m_textInfoName) ? 0 : LCMAP_LINGUISTIC_CASING;
+
+ Interop.mincore.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : m_textInfoName,
+ toUpper ? LCMAP_UPPERCASE | linguisticCasing : LCMAP_LOWERCASE | linguisticCasing,
+ new string(c, 1),
+ 1,
+ (IntPtr)(&retVal),
+ 1,
+ IntPtr.Zero,
+ IntPtr.Zero,
+ _sortHandle);
+
+ return retVal;
+ }
+
+ // PAL Ends here
+
+ private readonly IntPtr _sortHandle;
+
+ private const uint LCMAP_LINGUISTIC_CASING = 0x01000000;
+ private const uint LCMAP_LOWERCASE = 0x00000100;
+ private const uint LCMAP_UPPERCASE = 0x00000200;
+
+ private static bool IsInvariantLocale(string localeName)
+ {
+ return localeName == "";
+ }
+ }
+} \ No newline at end of file