diff options
Diffstat (limited to 'src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs')
-rw-r--r-- | src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs | 140 |
1 files changed, 111 insertions, 29 deletions
diff --git a/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs b/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs index 2aaf5a22fa..21c3c9f7e4 100644 --- a/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs +++ b/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics; using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -17,7 +18,6 @@ namespace System.Globalization [NonSerialized] private bool _isAsciiEqualityOrdinal; - [SecuritySafeCritical] internal CompareInfo(CultureInfo culture) { _name = culture.m_name; @@ -27,14 +27,23 @@ namespace System.Globalization private void InitSort(CultureInfo culture) { _sortName = culture.SortName; - _sortHandle = Interop.GlobalizationInterop.GetSortHandle(GetNullTerminatedUtf8String(_sortName)); + Interop.GlobalizationInterop.ResultCode resultCode = Interop.GlobalizationInterop.GetSortHandle(GetNullTerminatedUtf8String(_sortName), out _sortHandle); + if (resultCode != Interop.GlobalizationInterop.ResultCode.Success) + { + _sortHandle.Dispose(); + + if (resultCode == Interop.GlobalizationInterop.ResultCode.OutOfMemory) + throw new OutOfMemoryException(); + + throw new ExternalException(SR.Arg_ExternalException); + } _isAsciiEqualityOrdinal = (_sortName == "en-US" || _sortName == ""); } internal static unsafe int IndexOfOrdinal(string source, string value, int startIndex, int count, bool ignoreCase) { - Contract.Assert(source != null); - Contract.Assert(value != null); + Debug.Assert(source != null); + Debug.Assert(value != null); if (value.Length == 0) { @@ -77,8 +86,8 @@ namespace System.Globalization internal static unsafe int LastIndexOfOrdinal(string source, string value, int startIndex, int count, bool ignoreCase) { - Contract.Assert(source != null); - Contract.Assert(value != null); + Debug.Assert(source != null); + Debug.Assert(value != null); if (value.Length == 0) { @@ -124,8 +133,8 @@ namespace System.Globalization private int GetHashCodeOfStringCore(string source, CompareOptions options) { - Contract.Assert(source != null); - Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); + Debug.Assert(source != null); + Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); return GetHashCodeOfStringCore(source, options, forceRandomizedHashing: false, additionalEntropy: 0); } @@ -137,9 +146,9 @@ namespace System.Globalization private unsafe int CompareString(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options) { - Contract.Assert(string1 != null); - Contract.Assert(string2 != null); - Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); + Debug.Assert(string1 != null); + Debug.Assert(string2 != null); + Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); fixed (char* pString1 = string1) { @@ -152,9 +161,9 @@ namespace System.Globalization private unsafe int IndexOfCore(string source, string target, int startIndex, int count, CompareOptions options) { - Contract.Assert(!string.IsNullOrEmpty(source)); - Contract.Assert(target != null); - Contract.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0); + Debug.Assert(!string.IsNullOrEmpty(source)); + Debug.Assert(target != null); + Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0); if (target.Length == 0) { @@ -181,9 +190,9 @@ namespace System.Globalization private unsafe int LastIndexOfCore(string source, string target, int startIndex, int count, CompareOptions options) { - Contract.Assert(!string.IsNullOrEmpty(source)); - Contract.Assert(target != null); - Contract.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0); + Debug.Assert(!string.IsNullOrEmpty(source)); + Debug.Assert(target != null); + Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0); if (target.Length == 0) { @@ -212,12 +221,11 @@ namespace System.Globalization } } - [SecuritySafeCritical] private bool StartsWith(string source, string prefix, CompareOptions options) { - Contract.Assert(!string.IsNullOrEmpty(source)); - Contract.Assert(!string.IsNullOrEmpty(prefix)); - Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); + Debug.Assert(!string.IsNullOrEmpty(source)); + Debug.Assert(!string.IsNullOrEmpty(prefix)); + Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && prefix.IsFastSort()) { @@ -227,12 +235,11 @@ namespace System.Globalization return Interop.GlobalizationInterop.StartsWith(_sortHandle, prefix, prefix.Length, source, source.Length, options); } - [SecuritySafeCritical] private bool EndsWith(string source, string suffix, CompareOptions options) { - Contract.Assert(!string.IsNullOrEmpty(source)); - Contract.Assert(!string.IsNullOrEmpty(suffix)); - Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); + Debug.Assert(!string.IsNullOrEmpty(source)); + Debug.Assert(!string.IsNullOrEmpty(suffix)); + Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && suffix.IsFastSort()) { @@ -241,16 +248,81 @@ namespace System.Globalization return Interop.GlobalizationInterop.EndsWith(_sortHandle, suffix, suffix.Length, source, source.Length, options); } + + private unsafe SortKey CreateSortKey(String source, CompareOptions options) + { + if (source==null) { throw new ArgumentNullException(nameof(source)); } + Contract.EndContractBlock(); + + if ((options & ValidSortkeyCtorMaskOffFlags) != 0) + { + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options)); + } + + byte [] keyData; + if (source.Length == 0) + { + keyData = EmptyArray<Byte>.Value; + } + else + { + int sortKeyLength = Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, null, 0, options); + keyData = new byte[sortKeyLength]; + + fixed (byte* pSortKey = keyData) + { + Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options); + } + } + + return new SortKey(Name, source, options, keyData); + } + + private unsafe static bool IsSortable(char *text, int length) + { + int index = 0; + UnicodeCategory uc; + + while (index < length) + { + if (Char.IsHighSurrogate(text[index])) + { + if (index == length - 1 || !Char.IsLowSurrogate(text[index+1])) + return false; // unpaired surrogate + + uc = CharUnicodeInfo.InternalGetUnicodeCategory(Char.ConvertToUtf32(text[index], text[index+1])); + if (uc == UnicodeCategory.PrivateUse || uc == UnicodeCategory.OtherNotAssigned) + return false; + + index += 2; + continue; + } + + if (Char.IsLowSurrogate(text[index])) + { + return false; // unpaired surrogate + } + + uc = CharUnicodeInfo.GetUnicodeCategory(text[index]); + if (uc == UnicodeCategory.PrivateUse || uc == UnicodeCategory.OtherNotAssigned) + { + return false; + } + + index++; + } + + return true; + } // ----------------------------- // ---- PAL layer ends here ---- // ----------------------------- - [SecuritySafeCritical] internal unsafe int GetHashCodeOfStringCore(string source, CompareOptions options, bool forceRandomizedHashing, long additionalEntropy) { - Contract.Assert(source != null); - Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); + Debug.Assert(source != null); + Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); if (source.Length == 0) { @@ -307,9 +379,19 @@ namespace System.Globalization int bytesWritten = System.Text.Encoding.UTF8.GetBytes(s, 0, s.Length, buffer, 0); - Contract.Assert(bytesWritten == byteLen); + Debug.Assert(bytesWritten == byteLen); return buffer; } + + private SortVersion GetSortVersion() + { + int sortVersion = Interop.GlobalizationInterop.GetSortVersion(); + return new SortVersion(sortVersion, LCID, new Guid(sortVersion, 0, 0, 0, 0, 0, 0, + (byte) (LCID >> 24), + (byte) ((LCID & 0x00FF0000) >> 16), + (byte) ((LCID & 0x0000FF00) >> 8), + (byte) (LCID & 0xFF))); + } } } |