summaryrefslogtreecommitdiff
path: root/src/mscorlib/corefx/System/Globalization/CompareInfo.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/corefx/System/Globalization/CompareInfo.cs')
-rw-r--r--src/mscorlib/corefx/System/Globalization/CompareInfo.cs283
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;
+ }
+ }
}
}