diff options
Diffstat (limited to 'src/mscorlib/corefx/System/Globalization/CompareInfo.cs')
-rw-r--r-- | src/mscorlib/corefx/System/Globalization/CompareInfo.cs | 283 |
1 files changed, 226 insertions, 57 deletions
diff --git a/src/mscorlib/corefx/System/Globalization/CompareInfo.cs b/src/mscorlib/corefx/System/Globalization/CompareInfo.cs index 77778af23c..64dbfe84f7 100644 --- a/src/mscorlib/corefx/System/Globalization/CompareInfo.cs +++ b/src/mscorlib/corefx/System/Globalization/CompareInfo.cs @@ -12,20 +12,15 @@ // //////////////////////////////////////////////////////////////////////////// -using System; -using System.Collections; -using System.Collections.Generic; +using System.Reflection; +using System.Diagnostics; using System.Diagnostics.Contracts; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Serialization; -using System.Threading; namespace System.Globalization { [Flags] [Serializable] - [System.Runtime.InteropServices.ComVisible(true)] public enum CompareOptions { None = 0x00000000, @@ -40,7 +35,6 @@ namespace System.Globalization } [Serializable] - [System.Runtime.InteropServices.ComVisible(true)] public partial class CompareInfo : IDeserializationCallback { // Mask used to check if IndexOf()/LastIndexOf()/IsPrefix()/IsPostfix() has the right flags. @@ -58,6 +52,11 @@ namespace System.Globalization ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType); + // Mask used to check if we have the right flags. + private const CompareOptions ValidSortkeyCtorMaskOffFlags = + ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | + CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.StringSort); + // // CompareInfos have an interesting identity. They are attached to the locale that created them, // ie: en-US would have an en-US sort. For haw-US (custom), then we serialize it as haw-US. @@ -69,6 +68,86 @@ namespace System.Globalization [NonSerialized] private String _sortName; // The name that defines our behavior + [OptionalField(VersionAdded = 3)] + private SortVersion _sortVersion; + + /*=================================GetCompareInfo========================== + **Action: Get the CompareInfo constructed from the data table in the specified assembly for the specified culture. + ** Warning: The assembly versioning mechanism is dead! + **Returns: The CompareInfo for the specified culture. + **Arguments: + ** culture the ID of the culture + ** assembly the assembly which contains the sorting table. + **Exceptions: + ** ArugmentNullException when the assembly is null + ** ArgumentException if culture is invalid. + ============================================================================*/ + // Assembly constructor should be deprecated, we don't act on the assembly information any more + public static CompareInfo GetCompareInfo(int culture, Assembly assembly) + { + // Parameter checking. + if (assembly == null) + { + throw new ArgumentNullException(nameof(assembly)); + } + if (assembly != typeof(Object).Module.Assembly) + { + throw new ArgumentException(SR.Argument_OnlyMscorlib); + } + Contract.EndContractBlock(); + + return GetCompareInfo(culture); + } + + /*=================================GetCompareInfo========================== + **Action: Get the CompareInfo constructed from the data table in the specified assembly for the specified culture. + ** The purpose of this method is to provide version for CompareInfo tables. + **Returns: The CompareInfo for the specified culture. + **Arguments: + ** name the name of the culture + ** assembly the assembly which contains the sorting table. + **Exceptions: + ** ArugmentNullException when the assembly is null + ** ArgumentException if name is invalid. + ============================================================================*/ + // Assembly constructor should be deprecated, we don't act on the assembly information any more + public static CompareInfo GetCompareInfo(String name, Assembly assembly) + { + if (name == null || assembly == null) + { + throw new ArgumentNullException(name == null ? nameof(name) : nameof(assembly)); + } + Contract.EndContractBlock(); + + if (assembly != typeof(Object).Module.Assembly) + { + throw new ArgumentException(SR.Argument_OnlyMscorlib); + } + + return GetCompareInfo(name); + } + + /*=================================GetCompareInfo========================== + **Action: Get the CompareInfo for the specified culture. + ** This method is provided for ease of integration with NLS-based software. + **Returns: The CompareInfo for the specified culture. + **Arguments: + ** culture the ID of the culture. + **Exceptions: + ** ArgumentException if culture is invalid. + ============================================================================*/ + // People really shouldn't be calling LCID versions, no custom support + public static CompareInfo GetCompareInfo(int culture) + { + if (CultureData.IsCustomCultureId(culture)) + { + // Customized culture cannot be created by the LCID. + throw new ArgumentException(SR.Argument_CustomCultureCannotBePassedByNumber, nameof(culture)); + } + + return CultureInfo.GetCultureInfo(culture).CompareInfo; + } + /*=================================GetCompareInfo========================== **Action: Get the CompareInfo for the specified culture. **Returns: The CompareInfo for the specified culture. @@ -82,13 +161,40 @@ namespace System.Globalization { if (name == null) { - throw new ArgumentNullException("name"); + throw new ArgumentNullException(nameof(name)); } Contract.EndContractBlock(); return CultureInfo.GetCultureInfo(name).CompareInfo; } + public static unsafe bool IsSortable(char ch) + { + char *pChar = &ch; + return IsSortable(pChar, 1); + } + + public static unsafe bool IsSortable(string text) + { + if (text == null) + { + // A null param is invalid here. + throw new ArgumentNullException(nameof(text)); + } + + if (0 == text.Length) + { + // A zero length string is not invalid, but it is also not sortable. + return (false); + } + + fixed (char *pChar = text) + { + return IsSortable(pChar, text.Length); + } + } + + [OnDeserializing] private void OnDeserializing(StreamingContext ctx) { @@ -130,12 +236,11 @@ namespace System.Globalization // //////////////////////////////////////////////////////////////////////// - [System.Runtime.InteropServices.ComVisible(false)] public virtual String Name { get { - Contract.Assert(_name != null, "CompareInfo.Name Expected _name to be set"); + Debug.Assert(_name != null, "CompareInfo.Name Expected _name to be set"); if (_name == "zh-CHT" || _name == "zh-CHS") { return _name; @@ -173,14 +278,14 @@ namespace System.Globalization { if (options != CompareOptions.Ordinal) { - throw new ArgumentException(SR.Argument_CompareOptionOrdinal, "options"); + throw new ArgumentException(SR.Argument_CompareOptionOrdinal, nameof(options)); } return String.CompareOrdinal(string1, string2); } if ((options & ValidCompareMaskOffFlags) != 0) { - throw new ArgumentException(SR.Argument_InvalidFlag, "options"); + throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); } //Our paradigm is that null sorts less than any other string and @@ -247,31 +352,31 @@ namespace System.Globalization // Verify inputs if (length1 < 0 || length2 < 0) { - throw new ArgumentOutOfRangeException((length1 < 0) ? "length1" : "length2", SR.ArgumentOutOfRange_NeedPosNum); + throw new ArgumentOutOfRangeException((length1 < 0) ? nameof(length1) : nameof(length2), SR.ArgumentOutOfRange_NeedPosNum); } if (offset1 < 0 || offset2 < 0) { - throw new ArgumentOutOfRangeException((offset1 < 0) ? "offset1" : "offset2", SR.ArgumentOutOfRange_NeedPosNum); + throw new ArgumentOutOfRangeException((offset1 < 0) ? nameof(offset1) : nameof(offset2), SR.ArgumentOutOfRange_NeedPosNum); } if (offset1 > (string1 == null ? 0 : string1.Length) - length1) { - throw new ArgumentOutOfRangeException("string1", SR.ArgumentOutOfRange_OffsetLength); + throw new ArgumentOutOfRangeException(nameof(string1), SR.ArgumentOutOfRange_OffsetLength); } if (offset2 > (string2 == null ? 0 : string2.Length) - length2) { - throw new ArgumentOutOfRangeException("string2", SR.ArgumentOutOfRange_OffsetLength); + throw new ArgumentOutOfRangeException(nameof(string2), SR.ArgumentOutOfRange_OffsetLength); } if ((options & CompareOptions.Ordinal) != 0) { if (options != CompareOptions.Ordinal) { throw new ArgumentException(SR.Argument_CompareOptionOrdinal, - "options"); + nameof(options)); } } else if ((options & ValidCompareMaskOffFlags) != 0) { - throw new ArgumentException(SR.Argument_InvalidFlag, "options"); + throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); } // @@ -318,8 +423,8 @@ namespace System.Globalization // internal static unsafe int CompareOrdinalIgnoreCase(string strA, int indexA, int lengthA, string strB, int indexB, int lengthB) { - Contract.Assert(indexA + lengthA <= strA.Length); - Contract.Assert(indexB + lengthB <= strB.Length); + Debug.Assert(indexA + lengthA <= strA.Length); + Debug.Assert(indexB + lengthB <= strB.Length); int length = Math.Min(lengthA, lengthB); int range = length; @@ -375,7 +480,7 @@ namespace System.Globalization { if (source == null || prefix == null) { - throw new ArgumentNullException((source == null ? "source" : "prefix"), + throw new ArgumentNullException((source == null ? nameof(source) : nameof(prefix)), SR.ArgumentNull_String); } Contract.EndContractBlock(); @@ -402,7 +507,7 @@ namespace System.Globalization if ((options & ValidIndexMaskOffFlags) != 0) { - throw new ArgumentException(SR.Argument_InvalidFlag, "options"); + throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); } return StartsWith(source, prefix, options); @@ -425,7 +530,7 @@ namespace System.Globalization { if (source == null || suffix == null) { - throw new ArgumentNullException((source == null ? "source" : "suffix"), + throw new ArgumentNullException((source == null ? nameof(source) : nameof(suffix)), SR.ArgumentNull_String); } Contract.EndContractBlock(); @@ -452,7 +557,7 @@ namespace System.Globalization if ((options & ValidIndexMaskOffFlags) != 0) { - throw new ArgumentException(SR.Argument_InvalidFlag, "options"); + throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); } return EndsWith(source, suffix, options); @@ -481,7 +586,7 @@ namespace System.Globalization public unsafe virtual int IndexOf(String source, char value) { if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); Contract.EndContractBlock(); return IndexOf(source, value, 0, source.Length, CompareOptions.None); @@ -491,7 +596,7 @@ namespace System.Globalization public unsafe virtual int IndexOf(String source, String value) { if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); Contract.EndContractBlock(); return IndexOf(source, value, 0, source.Length, CompareOptions.None); @@ -501,7 +606,7 @@ namespace System.Globalization public unsafe virtual int IndexOf(String source, char value, CompareOptions options) { if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); Contract.EndContractBlock(); return IndexOf(source, value, 0, source.Length, options); @@ -511,17 +616,34 @@ namespace System.Globalization public unsafe virtual int IndexOf(String source, String value, CompareOptions options) { if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); Contract.EndContractBlock(); return IndexOf(source, value, 0, source.Length, options); } + public unsafe virtual int IndexOf(String source, char value, int startIndex) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + Contract.EndContractBlock(); + + return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None); + } + + public unsafe virtual int IndexOf(String source, String value, int startIndex) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + Contract.EndContractBlock(); + + return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None); + } public unsafe virtual int IndexOf(String source, char value, int startIndex, CompareOptions options) { if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); Contract.EndContractBlock(); return IndexOf(source, value, startIndex, source.Length - startIndex, options); @@ -531,7 +653,7 @@ namespace System.Globalization public unsafe virtual int IndexOf(String source, String value, int startIndex, CompareOptions options) { if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); Contract.EndContractBlock(); return IndexOf(source, value, startIndex, source.Length - startIndex, options); @@ -553,13 +675,13 @@ namespace System.Globalization { // Validate inputs if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); if (startIndex < 0 || startIndex > source.Length) - throw new ArgumentOutOfRangeException("startIndex", SR.ArgumentOutOfRange_Index); + throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index); if (count < 0 || startIndex > source.Length - count) - throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_Count); + throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count); Contract.EndContractBlock(); if (options == CompareOptions.OrdinalIgnoreCase) @@ -570,7 +692,7 @@ namespace System.Globalization // Validate CompareOptions // Ordinal can't be selected with other flags if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal)) - throw new ArgumentException(SR.Argument_InvalidFlag, "options"); + throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); return IndexOfCore(source, new string(value, 1), startIndex, count, options); } @@ -580,13 +702,13 @@ namespace System.Globalization { // Validate inputs if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); if (value == null) - throw new ArgumentNullException("value"); + throw new ArgumentNullException(nameof(value)); if (startIndex > source.Length) { - throw new ArgumentOutOfRangeException("startIndex", SR.ArgumentOutOfRange_Index); + throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index); } Contract.EndContractBlock(); @@ -603,11 +725,11 @@ namespace System.Globalization if (startIndex < 0) { - throw new ArgumentOutOfRangeException("startIndex", SR.ArgumentOutOfRange_Index); + throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index); } if (count < 0 || startIndex > source.Length - count) - throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_Count); + throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count); if (options == CompareOptions.OrdinalIgnoreCase) { @@ -617,7 +739,7 @@ namespace System.Globalization // Validate CompareOptions // Ordinal can't be selected with other flags if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal)) - throw new ArgumentException(SR.Argument_InvalidFlag, "options"); + throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); return IndexOfCore(source, value, startIndex, count, options); } @@ -639,7 +761,7 @@ namespace System.Globalization public unsafe virtual int LastIndexOf(String source, char value) { if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); Contract.EndContractBlock(); // Can't start at negative index, so make sure we check for the length == 0 case. @@ -651,7 +773,7 @@ namespace System.Globalization public virtual int LastIndexOf(String source, String value) { if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); Contract.EndContractBlock(); // Can't start at negative index, so make sure we check for the length == 0 case. @@ -663,7 +785,7 @@ namespace System.Globalization public virtual int LastIndexOf(String source, char value, CompareOptions options) { if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); Contract.EndContractBlock(); // Can't start at negative index, so make sure we check for the length == 0 case. @@ -674,7 +796,7 @@ namespace System.Globalization public unsafe virtual int LastIndexOf(String source, String value, CompareOptions options) { if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); Contract.EndContractBlock(); // Can't start at negative index, so make sure we check for the length == 0 case. @@ -682,6 +804,16 @@ namespace System.Globalization source.Length, options); } + public unsafe virtual int LastIndexOf(String source, char value, int startIndex) + { + return LastIndexOf(source, value, startIndex, startIndex + 1, CompareOptions.None); + } + + + public unsafe virtual int LastIndexOf(String source, String value, int startIndex) + { + return LastIndexOf(source, value, startIndex, startIndex + 1, CompareOptions.None); + } public unsafe virtual int LastIndexOf(String source, char value, int startIndex, CompareOptions options) { @@ -711,7 +843,7 @@ namespace System.Globalization { // Verify Arguments if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); Contract.EndContractBlock(); // Validate CompareOptions @@ -719,7 +851,7 @@ namespace System.Globalization if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal) && (options != CompareOptions.OrdinalIgnoreCase)) - throw new ArgumentException(SR.Argument_InvalidFlag, "options"); + throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); // Special case for 0 length input strings if (source.Length == 0 && (startIndex == -1 || startIndex == 0)) @@ -727,7 +859,7 @@ namespace System.Globalization // Make sure we're not out of range if (startIndex < 0 || startIndex > source.Length) - throw new ArgumentOutOfRangeException("startIndex", SR.ArgumentOutOfRange_Index); + throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index); // Make sure that we allow startIndex == source.Length if (startIndex == source.Length) @@ -739,7 +871,7 @@ namespace System.Globalization // 2nd have of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0. if (count < 0 || startIndex - count + 1 < 0) - throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_Count); + throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count); if (options == CompareOptions.OrdinalIgnoreCase) { @@ -754,9 +886,9 @@ namespace System.Globalization { // Verify Arguments if (source == null) - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); if (value == null) - throw new ArgumentNullException("value"); + throw new ArgumentNullException(nameof(value)); Contract.EndContractBlock(); // Validate CompareOptions @@ -764,7 +896,7 @@ namespace System.Globalization if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal) && (options != CompareOptions.OrdinalIgnoreCase)) - throw new ArgumentException(SR.Argument_InvalidFlag, "options"); + throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); // Special case for 0 length input strings if (source.Length == 0 && (startIndex == -1 || startIndex == 0)) @@ -772,7 +904,7 @@ namespace System.Globalization // Make sure we're not out of range if (startIndex < 0 || startIndex > source.Length) - throw new ArgumentOutOfRangeException("startIndex", SR.ArgumentOutOfRange_Index); + throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index); // Make sure that we allow startIndex == source.Length if (startIndex == source.Length) @@ -788,7 +920,7 @@ namespace System.Globalization // 2nd half of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0. if (count < 0 || startIndex - count + 1 < 0) - throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_Count); + throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count); if (options == CompareOptions.OrdinalIgnoreCase) { @@ -798,8 +930,24 @@ namespace System.Globalization return LastIndexOfCore(source, value, startIndex, count, options); } + //////////////////////////////////////////////////////////////////////// + // + // GetSortKey + // + // Gets the SortKey for the given string with the given options. + // + //////////////////////////////////////////////////////////////////////// + public unsafe virtual SortKey GetSortKey(String source, CompareOptions options) + { + return CreateSortKey(source, options); + } + public unsafe virtual SortKey GetSortKey(String source) + { + return CreateSortKey(source, CompareOptions.None); + } + //////////////////////////////////////////////////////////////////////// // // Equals @@ -872,12 +1020,12 @@ namespace System.Globalization // if (null == source) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if ((options & ValidHashCodeOfStringMaskOffFlags) != 0) { - throw new ArgumentException(SR.Argument_InvalidFlag, "options"); + throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); } Contract.EndContractBlock(); @@ -888,7 +1036,7 @@ namespace System.Globalization { if (source == null) { - throw new ArgumentNullException("source"); + throw new ArgumentNullException(nameof(source)); } if (options == CompareOptions.Ordinal) @@ -921,5 +1069,26 @@ namespace System.Globalization { return ("CompareInfo - " + this.Name); } + + public SortVersion Version + { + get + { + if (_sortVersion == null) + { + _sortVersion = GetSortVersion(); + } + + return _sortVersion; + } + } + + public int LCID + { + get + { + return CultureInfo.GetCultureInfo(Name).LCID; + } + } } } |