private int LinearIndexOf(string fieldName, CompareOptions compareOptions)
 {
     CompareInfo compareInfo = this._compareInfo;
     if (compareInfo == null)
     {
         if (-1 != this._defaultLocaleID)
         {
             compareInfo = CompareInfo.GetCompareInfo(this._defaultLocaleID);
         }
         if (compareInfo == null)
         {
             compareInfo = CultureInfo.InvariantCulture.CompareInfo;
         }
         this._compareInfo = compareInfo;
     }
     int length = this._fieldNames.Length;
     for (int i = 0; i < length; i++)
     {
         if (compareInfo.Compare(fieldName, this._fieldNames[i], compareOptions) == 0)
         {
             this._fieldNameLookup[fieldName] = i;
             return i;
         }
     }
     return -1;
 }
예제 #2
0
파일: XQuery.cs 프로젝트: nuxleus/saxonica
        /// <summary>
        /// Create a collation based on a given <c>CompareInfo</c> and <c>CompareOptions</c>    
        /// </summary>
        /// <param name="uri">The collation URI to be used within the XPath expression to refer to this collation</param>
        /// <param name="comparer">The <c>CompareInfo</c>, which determines the language-specific
        /// collation rules to be used</param>
        /// <param name="options">Options to be used in performing comparisons, for example
        /// whether they are to be case-blind and/or accent-blind</param>
        /// <param name="isDefault">If true, this collation will be used as the default collation</param>

        public void DeclareCollation(Uri uri, CompareInfo compareInfo, CompareOptions options, Boolean isDefault) {
            DotNetComparator comparator = new DotNetComparator(compareInfo, options);
            env.declareCollation(uri.ToString(), comparator);
            if(isDefault) {
                env.declareDefaultCollation(uri.ToString());
            }
        }
예제 #3
0
        private unsafe int GetHashCodeOfStringCore(string source, CompareOptions options)
        {
            Debug.Assert(source != null);
            Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);

            if (source.Length == 0)
            {
                return 0;
            }

            int tmpHash = 0;

            fixed (char* pSource = source)
            {
                if (Interop.mincore.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _sortName,
                                                  LCMAP_HASH | (uint)GetNativeCompareFlags(options),
                                                  pSource, source.Length,
                                                  &tmpHash, sizeof(int),
                                                  null, null, _sortHandle) == 0)
                {
                    Environment.FailFast("LCMapStringEx failed!");
                }
            }

            return tmpHash;
        }
 public virtual int Compare(string string1, string string2, CompareOptions options)
 {
     if (options == CompareOptions.OrdinalIgnoreCase)
     {
         return string.Compare(string1, string2, StringComparison.OrdinalIgnoreCase);
     }
     if ((options & CompareOptions.Ordinal) != CompareOptions.None)
     {
         if (options != CompareOptions.Ordinal)
         {
             throw new ArgumentException(Environment.GetResourceString("Argument_CompareOptionOrdinal"), "options");
         }
         return string.CompareOrdinal(string1, string2);
     }
     if ((options & ~(CompareOptions.StringSort | CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase)) != CompareOptions.None)
     {
         throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
     }
     if (string1 == null)
     {
         if (string2 == null)
         {
             return 0;
         }
         return -1;
     }
     if (string2 == null)
     {
         return 1;
     }
     return InternalCompareString(this.m_dataHandle, this.m_sortName, string1, 0, string1.Length, string2, 0, string2.Length, GetNativeCompareFlags(options));
 }
예제 #5
0
파일: SortKey.cs 프로젝트: JonHanna/coreclr
        internal byte[] m_KeyData;        // sortkey data

        //
        // The following constructor is designed to be called from CompareInfo to get the 
        // the sort key of specific string for synthetic culture
        //
        internal SortKey(String localeName, String str, CompareOptions options, byte[] keyData)
        {
            this.m_KeyData = keyData;
            this.localeName = localeName;
            this.options    = options;
            this.m_String   = str;
        }
예제 #6
0
파일: SortKey.cs 프로젝트: JonHanna/coreclr
        internal byte[] _keyData;        // sortkey data

        //
        // The following constructor is designed to be called from CompareInfo to get the 
        // the sort key of specific string for synthetic culture
        //
        internal SortKey(String localeName, String str, CompareOptions options, byte[] keyData)
        {
            _keyData = keyData;
            _localeName = localeName;
            _options    = options;
            _string   = str;
        }
		private int internal_index (string source, int sindex,
		int count, string value,
		CompareOptions options,
		bool first)
		{
			throw new System.NotImplementedException();
		}
		private int internal_compare (string str1, int offset1,
		int length1, string str2,
		int offset2, int length2,
		CompareOptions options)
		{
			throw new System.NotImplementedException();
		}
예제 #9
0
        public void Equals(string cultureName1, CompareOptions options1, string cultureName2, CompareOptions options2, bool expected)
        {
            StringComparer comparer1 = new CultureInfo(cultureName1).CompareInfo.GetStringComparer(options1);
            StringComparer comparer2 = new CultureInfo(cultureName2).CompareInfo.GetStringComparer(options2);

            Assert.Equal(expected, comparer1.Equals(comparer2));
            Assert.Equal(expected, comparer1.GetHashCode().Equals(comparer2.GetHashCode()));
        }
예제 #10
0
 public void IsSuffix(CompareInfo compareInfo, string source, string value, CompareOptions options, bool expected)
 {
     if (options == CompareOptions.None)
     {
         Assert.Equal(expected, compareInfo.IsSuffix(source, value));
     }
     Assert.Equal(expected, compareInfo.IsSuffix(source, value, options));
 }
예제 #11
0
        public static bool CultureContains(this string haystack, string needle, CompareOptions comparison = CompareOptions.IgnoreCase)
        {
            if (Thread.CurrentThread.CurrentCulture.Name != "en-US") {
                Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
            }

            return Thread.CurrentThread.CurrentCulture.CompareInfo.IndexOf(haystack, needle, comparison) >= 0;
        }
 /// <summary>
 /// Gets the sort key for the specified string.
 /// </summary>
 /// <param name="compareInfo"></param>
 /// <param name="source"></param>
 /// <param name="options"></param>
 /// <returns></returns>
 public static SortKey GetSortKey(this CompareInfo compareInfo, string source, CompareOptions options = CompareOptions.None)
 {
     #if PORTABLE
     throw new PlatformNotSupportedException();
     #else
     return compareInfo.GetSortKey(source, options);
     #endif
 }
예제 #13
0
 private unsafe bool EndsWith(string source, string suffix, CompareOptions options)
 {
     fixed (char *pSource = source) fixed (char *pValue = suffix)
     {
         return FindStringOrdinal(pSource, source.Length, pValue, suffix.Length, FindStringOptions.EndsWith,
                                  (options & CompareOptions.IgnoreCase) != 0) >= 0;
     }
 }
예제 #14
0
        private unsafe int CompareString(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options)
        {
            fixed (char *pStr1 = string1) fixed (char *pStr2 = string2)
            {
                char *pString1 = &pStr1[offset1];
                char *pString2 = &pStr2[offset2];

                return CompareString(pString1, length1, pString2, length2, options);
            }
        }
예제 #15
0
		/// <summary>
		/// Compares two strings.
		/// </summary>
		/// <param name="strA">The first string.</param>
		/// <param name="startA">The offset within the first string.</param>
		/// <param name="lengthA">The length within the first string.</param>
		/// <param name="strB">The second string.</param>
		/// <param name="startB">The offset within the second string.</param>
		/// <param name="lengthB">The length within the second string.</param>
		/// <param name="culture">The culture used for the comparison.</param>
		/// <param name="options">The comparison options.</param>
		/// <returns>Zero when string A is equal to string B;
		/// a positive value when string A is greater than string B;
		/// a negative value when string A is less than string B.</returns>
		public static int Compare(string strA, int startA, int lengthA, string strB, int startB, int lengthB, CultureInfo culture, CompareOptions options)
		{
			// TODO: Null?
			// TODO: Contract?
			int minLength = Math.Min(lengthA, lengthB);
			int result = String.Compare(strA, startA, strB, startB, minLength, culture, options);
			if (result == 0)
				result = lengthA.CompareTo(lengthB);
			return result;
		}
예제 #16
0
	void AssertCompare (string message, int result, string s1, string s2,
		CompareOptions opt, CompareInfo ci)
	{
		int ret = ci.Compare (s1, s2, opt);
		if (result == 0)
			AssertEquals (message, 0, ret);
		else if (result < 0)
			Assert.IsTrue (message + String.Format ("(neg: {0})", ret), ret < 0);
		else
			Assert.IsTrue (message + String.Format ("(pos: {0})", ret), ret > 0);
	}
예제 #17
0
        private unsafe int GetHashCodeOfStringCore(string source, CompareOptions options)
        {
            bool ignoreCase = (options & (CompareOptions.IgnoreCase | CompareOptions.OrdinalIgnoreCase)) != 0;

            if (ignoreCase)
            {
                return source.ToUpper().GetHashCode();
            }

            return source.GetHashCode();
        }
예제 #18
0
파일: SortKey.cs 프로젝트: runefs/Marvin
		internal SortKey (int lcid, string source, byte [] buffer, CompareOptions opt,
			int lv1Length, int lv2Length, int lv3Length,
			int kanaSmallLength, int markTypeLength,
			int katakanaLength, int kanaWidthLength,
			int identLength)
		{
			this.lcid = lcid;
			this.source = source;
			this.key = buffer;
			this.options = opt;
		}
예제 #19
0
    public static void Compare(string localeName, string left, string right, int expected, CompareOptions options)
    {
        CompareInfo ci = CompareInfo.GetCompareInfo(localeName);        
        
        Assert.Equal(expected, Math.Sign(ci.Compare(left, right, options)));

        if (options == CompareOptions.None)
        {
            Assert.Equal(expected, Math.Sign(ci.Compare(left, right)));
        }
    }
예제 #20
0
 public virtual unsafe int Compare(string string1, string string2, CompareOptions options)
 {
     if (options == CompareOptions.OrdinalIgnoreCase)
     {
         return string.Compare(string1, string2, StringComparison.OrdinalIgnoreCase);
     }
     if ((options & CompareOptions.Ordinal) != CompareOptions.None)
     {
         if (options != CompareOptions.Ordinal)
         {
             throw new ArgumentException(Environment.GetResourceString("Argument_CompareOptionOrdinal"), "options");
         }
         if (string1 == null)
         {
             if (string2 == null)
             {
                 return 0;
             }
             return -1;
         }
         if (string2 == null)
         {
             return 1;
         }
         return string.nativeCompareOrdinal(string1, string2, false);
     }
     if ((options & ~(CompareOptions.StringSort | CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase)) != CompareOptions.None)
     {
         throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
     }
     if (string1 == null)
     {
         if (string2 == null)
         {
             return 0;
         }
         return -1;
     }
     if (string2 == null)
     {
         return 1;
     }
     if (!this.IsSynthetic)
     {
         return Compare(this.m_pSortingTable, this.m_sortingLCID, string1, string2, options);
     }
     if (options == CompareOptions.Ordinal)
     {
         return Compare(CultureInfo.InvariantCulture.CompareInfo.m_pSortingTable, this.m_sortingLCID, string1, string2, options);
     }
     return nativeCompareString(this.m_sortingLCID, string1, 0, string1.Length, string2, 0, string2.Length, GetNativeCompareFlags(options));
 }
예제 #21
0
        public static void Compare(string x, string y, string cultureName, CompareOptions options, int expectedWindows, int expectedICU)
        {
            int expected = s_isWindows ? expectedWindows : expectedICU;
            StringComparer comparer = new CultureInfo(cultureName).CompareInfo.GetStringComparer(options);

            Assert.Equal(expected, Math.Sign(comparer.Compare(x, y)));
            Assert.Equal((expected == 0), comparer.Equals(x, y));

            if (x != null && y != null)
            {
                Assert.Equal((expected == 0), comparer.GetHashCode(x).Equals(comparer.GetHashCode(y)));
            }
        }
예제 #22
0
 private int LinearIndexOf(string fieldName, CompareOptions compareOptions)
 {
     // Tried Array.FindIndex and various other options here; none seemed to be faster than this
     for (var i = 0; i < _fieldNames.Length; ++i)
     {
         if (CultureInfo.InvariantCulture.CompareInfo.Compare(fieldName, _fieldNames[i], compareOptions) == 0)
         {
             _fieldNameLookup[fieldName] = i; // Add an exact match for the future
             return i;
         }
     }
     return -1;
 }
예제 #23
0
 internal IndexInfo(
     string name,
     CultureInfo cultureInfo,
     CompareOptions compareOptions,
     IndexSegment[] indexSegments,
     CreateIndexGrbit grbit)
 {
     this.Name = name;
     this.CultureInfo = cultureInfo;
     this.CompareOptions = compareOptions;
     this.IndexSegments = indexSegments;
     this.Grbit = grbit;
 }
예제 #24
0
		SortKey CreateSortKeyCore (string source, CompareOptions options)
		{
			if (UseManagedCollation)
				return GetCollator ().GetSortKey (source, options);
			SortKey key=new SortKey (culture, source, options);

			/* Need to do the icall here instead of in the
			 * SortKey constructor, as we need access to
			 * this instance's collator.
			 */
			assign_sortkey (key, source, options);
			
			return(key);        	
		}
        private static void CompareVarying(string one, string two, int compareValue, string culture, CompareOptions compareOptions)
        {
            StringComparer comp = new CultureInfo(culture).CompareInfo.GetStringComparer(compareOptions);

            Assert.Equal(compareValue, comp.Compare(one, two));
            if (compareValue == 0)
            {
                Assert.True(comp.Equals(one, two));
            }
            else
            {
                Assert.False(comp.Equals(one, two));
            }
        }
예제 #26
0
파일: sortkey.cs 프로젝트: ArildF/masters
     ////////////////////////////////////////////////////////////////////////
     //
     //  SortKey Constructor
     //
     //  Implements CultureInfo.CompareInfo.GetSortKey().
     //  Package access only.
     //
     ////////////////////////////////////////////////////////////////////////
 
     unsafe internal SortKey(void* pSortingFile, int win32LCID, String str, CompareOptions options)
     {
         if (str==null) {
             throw new ArgumentNullException("str");
         }
 
         //This takes the sort id from CompareInfo, so we should be able to skip initializing it.
         this.win32LCID = win32LCID;
 
         this.options = options;
         m_String = str;
 
         //We need an initialized SortTable here, but since we're getting this as an instance 
         //method off of a CompareInfo, we're guaranteed that that already happened.
         m_KeyData = nativeCreateSortKey(pSortingFile, str, (int)options, win32LCID);
     }
예제 #27
0
 public SearchBox()
 {
     //Rajoute les columns défini par le binding de la fenêtre consommatrice à partir de la propriété ColumnsProperty
     Columns = new ObservableCollection<DataGridColumn>();
     //Évênement CollectionChanged (sender, event args)
     Columns.CollectionChanged += (s, a) =>
     {
         dgResults.Columns.Clear();
         foreach (var column in this.Columns)
             dgResults.Columns.Add(column);
     };
     InitializeComponent();
     if (IsCaseSensitive)
         compareOptions = CompareOptions.None;
     else
         compareOptions = CompareOptions.IgnoreCase;
 }
예제 #28
0
        private unsafe int GetHashCodeOfStringCore(string source, CompareOptions options)
        {
            Contract.Assert(source != null);
            Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);

            // TODO: Implement This Fully.
            int hash = 5381;

            unchecked
            {
                for (int i = 0; i < source.Length; i++)
                {
                    hash = ((hash << 5) + hash) + ChangeCaseAscii(source[i]);
                }
            }

            return hash;
        }
예제 #29
0
 /// <summary>
 /// Initializes a new instance of the IndexInfo class.
 /// </summary>
 /// <param name="name">Name of the index.</param>
 /// <param name="cultureInfo">CultureInfo for string sorting.</param>
 /// <param name="compareOptions">String comparison options.</param>
 /// <param name="indexSegments">Array of index segment descriptions.</param>
 /// <param name="grbit">Index options.</param>
 /// <param name="keys">Number of unique keys in the index.</param>
 /// <param name="entries">Number of entries in the index.</param>
 /// <param name="pages">Number of pages in the index.</param>
 internal IndexInfo(
     string name,
     CultureInfo cultureInfo,
     CompareOptions compareOptions,
     IndexSegment[] indexSegments,
     CreateIndexGrbit grbit,
     int keys,
     int entries,
     int pages)
 {
     this.name = name;
     this.cultureInfo = cultureInfo;
     this.compareOptions = compareOptions;
     this.indexSegments = Array.AsReadOnly(indexSegments);
     this.grbit = grbit;
     this.keys = keys;
     this.entries = entries;
     this.pages = pages;
 }
예제 #30
0
        private 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);

            int result = Interop.mincore.CompareStringEx(_sortHandle != IntPtr.Zero ? null : _sortName,
                                                         GetNativeCompareFlags(options),
                                                         string1, offset1, length1,
                                                         string2, offset2, length2,
                                                         _sortHandle);

            if (result == 0)
            {
                Environment.FailFast("CompareStringEx failed");
            }

            // Map CompareStringEx return value to -1, 0, 1.
            return result - 2;
        }
예제 #31
0
        internal unsafe int IndexOfCore(string source, string target, int startIndex, int count, CompareOptions options, int *matchLengthPtr)
        {
            Debug.Assert(!_invariantMode);

            Debug.Assert(!string.IsNullOrEmpty(source));
            Debug.Assert(target != null);
            Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);

            int index;

            if (target.Length == 0)
            {
                if (matchLengthPtr != null)
                {
                    *matchLengthPtr = 0;
                }
                return(startIndex);
            }

            if (options == CompareOptions.Ordinal)
            {
                index = IndexOfOrdinal(source, target, startIndex, count, ignoreCase: false);
                if (index != -1)
                {
                    if (matchLengthPtr != null)
                    {
                        *matchLengthPtr = target.Length;
                    }
                }
                return(index);
            }
#if CORECLR
            if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && target.IsFastSort())
            {
                index = IndexOf(source, target, startIndex, count, GetOrdinalCompareOptions(options));
                if (index != -1)
                {
                    if (matchLengthPtr != null)
                    {
                        *matchLengthPtr = target.Length;
                    }
                }
                return(index);
            }
#endif
            fixed(char *pSource = source)
            {
                index = Interop.GlobalizationInterop.IndexOf(_sortHandle, target, target.Length, pSource + startIndex, count, options, matchLengthPtr);

                return(index != -1 ? index + startIndex : -1);
            }
        }
예제 #32
0
 public static int Compare(String strA, String strB, CultureInfo culture, CompareOptions options)
 {
     Contract.Requires(culture != null);
     return(default(int));
 }
예제 #33
0
        public static int CompareNatural(string strA, string strB, CultureInfo culture, CompareOptions options)
        {
            CompareInfo cmp              = culture.CompareInfo;
            int         iA               = 0;
            int         iB               = 0;
            int         softResult       = 0;
            int         softResultWeight = 0;

            while (iA < strA.Length && iB < strB.Length)
            {
                bool isDigitA = Char.IsDigit(strA[iA]);
                bool isDigitB = Char.IsDigit(strB[iB]);
                if (isDigitA != isDigitB)
                {
                    return(cmp.Compare(strA, iA, strB, iB, options));
                }
                else if (!isDigitA && !isDigitB)
                {
                    int jA = iA + 1;
                    int jB = iB + 1;
                    while (jA < strA.Length && !Char.IsDigit(strA[jA]))
                    {
                        jA++;
                    }
                    while (jB < strB.Length && !Char.IsDigit(strB[jB]))
                    {
                        jB++;
                    }
                    int cmpResult = cmp.Compare(strA, iA, jA - iA, strB, iB, jB - iB, options);
                    if (cmpResult != 0)
                    {
                        // Certain strings may be considered different due to "soft" differences that are
                        // ignored if more significant differences follow, e.g. a hyphen only affects the
                        // comparison if no other differences follow
                        string sectionA = strA.Substring(iA, jA - iA);
                        string sectionB = strB.Substring(iB, jB - iB);
                        if (cmp.Compare(sectionA + "1", sectionB + "2", options) ==
                            cmp.Compare(sectionA + "2", sectionB + "1", options))
                        {
                            return(cmp.Compare(strA, iA, strB, iB, options));
                        }
                        else if (softResultWeight < 1)
                        {
                            softResult       = cmpResult;
                            softResultWeight = 1;
                        }
                    }
                    iA = jA;
                    iB = jB;
                }
                else
                {
                    char zeroA = (char)(strA[iA] - (int)Char.GetNumericValue(strA[iA]));
                    char zeroB = (char)(strB[iB] - (int)Char.GetNumericValue(strB[iB]));
                    int  jA    = iA;
                    int  jB    = iB;
                    while (jA < strA.Length && strA[jA] == zeroA)
                    {
                        jA++;
                    }
                    while (jB < strB.Length && strB[jB] == zeroB)
                    {
                        jB++;
                    }
                    int resultIfSameLength = 0;
                    do
                    {
                        isDigitA = jA < strA.Length && Char.IsDigit(strA[jA]);
                        isDigitB = jB < strB.Length && Char.IsDigit(strB[jB]);
                        int numA = isDigitA ? (int)Char.GetNumericValue(strA[jA]) : 0;
                        int numB = isDigitB ? (int)Char.GetNumericValue(strB[jB]) : 0;
                        if (isDigitA && (char)(strA[jA] - numA) != zeroA)
                        {
                            isDigitA = false;
                        }
                        if (isDigitB && (char)(strB[jB] - numB) != zeroB)
                        {
                            isDigitB = false;
                        }
                        if (isDigitA && isDigitB)
                        {
                            if (numA != numB && resultIfSameLength == 0)
                            {
                                resultIfSameLength = numA < numB ? -1 : 1;
                            }
                            jA++;
                            jB++;
                        }
                    }while (isDigitA && isDigitB);
                    if (isDigitA != isDigitB)
                    {
                        // One number has more digits than the other (ignoring leading zeros) - the longer
                        // number must be larger
                        return(isDigitA ? 1 : -1);
                    }
                    else if (resultIfSameLength != 0)
                    {
                        // Both numbers are the same length (ignoring leading zeros) and at least one of
                        // the digits differed - the first difference determines the result
                        return(resultIfSameLength);
                    }
                    int lA = jA - iA;
                    int lB = jB - iB;
                    if (lA != lB)
                    {
                        // Both numbers are equivalent but one has more leading zeros
                        return(lA > lB ? -1 : 1);
                    }
                    else if (zeroA != zeroB && softResultWeight < 2)
                    {
                        softResult       = cmp.Compare(strA, iA, 1, strB, iB, 1, options);
                        softResultWeight = 2;
                    }
                    iA = jA;
                    iB = jB;
                }
            }
            if (iA < strA.Length || iB < strB.Length)
            {
                return(iA < strA.Length ? 1 : -1);
            }
            else if (softResult != 0)
            {
                return(softResult);
            }
            return(0);
        }
예제 #34
0
        public void Test(CultureInfo culture, string str1, string str2, int expected, CompareOptions options)
        {
            CompareInfo ci = culture.CompareInfo;
            int         i  = ci.IndexOf(str1, str2, options);

            Assert.Equal(expected, i);
        }
예제 #35
0
        /// <summary>
        /// Compares two Literal Nodes
        /// </summary>
        /// <param name="a">First Literal Node</param>
        /// <param name="b">Second Literal Node</param>
        /// <param name="culture">Culture to use for lexical string comparisons where more natural comparisons are not possible/applicable</param>
        /// <param name="comparisonOptions">String Comparison options used for lexical string comparisons where more natural comparisons are not possible/applicable</param>
        /// <returns></returns>
        public static int CompareLiterals(ILiteralNode a, ILiteralNode b, CultureInfo culture, CompareOptions comparisonOptions)
        {
            if (ReferenceEquals(a, b))
            {
                return(0);
            }
            if (a == null)
            {
                if (b == null)
                {
                    return(0);
                }
                return(-1);
            }
            else if (b == null)
            {
                return(1);
            }

            // initialize required culture and comparison options
            if (culture == null)
            {
                culture = Options.DefaultCulture;
            }
            if (comparisonOptions == CompareOptions.None)
            {
                comparisonOptions = Options.DefaultComparisonOptions;
            }

            //Literal Nodes are ordered based on Type and lexical form
            if (a.DataType == null && b.DataType != null)
            {
                //Untyped Literals are less than Typed Literals
                //Return a -1 to indicate this
                return(-1);
            }
            else if (a.DataType != null && b.DataType == null)
            {
                //Typed Literals are greater than Untyped Literals
                //Return a 1 to indicate this
                return(1);
            }
            else if (a.DataType == null && b.DataType == null)
            {
                return(String.Compare(a.Value, b.Value, culture, comparisonOptions));
            }
            else if (EqualityHelper.AreUrisEqual(a.DataType, b.DataType))
            {
                //Are we using a known and orderable DataType?
                String type = a.DataType.AbsoluteUri;
                if (!XmlSpecsHelper.IsSupportedType(type))
                {
                    //Don't know how to order so use specified order on the value
                    return(String.Compare(a.Value, b.Value, culture, comparisonOptions));
                }
                else
                {
                    try
                    {
                        switch (type)
                        {
                        case XmlSpecsHelper.XmlSchemaDataTypeBoolean:
                            //Can use Lexical ordering for this so use specified order on the value
                            bool aBool, bBool;
                            if (Boolean.TryParse(a.Value, out aBool))
                            {
                                if (Boolean.TryParse(b.Value, out bBool))
                                {
                                    return(aBool.CompareTo(bBool));
                                }
                                else
                                {
                                    return(-1);
                                }
                            }
                            else
                            {
                                if (Boolean.TryParse(b.Value, out bBool))
                                {
                                    return(1);
                                }
                                goto default;
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeByte:
                            //Remember that xsd:byte is actually equivalent to SByte in .Net
                            //Extract the Byte Values and compare
                            sbyte aSByte, bSByte;
                            if (SByte.TryParse(a.Value, out aSByte))
                            {
                                if (SByte.TryParse(b.Value, out bSByte))
                                {
                                    return(aSByte.CompareTo(bSByte));
                                }
                                else
                                {
                                    return(-1);
                                }
                            }
                            else
                            {
                                if (SByte.TryParse(b.Value, out bSByte))
                                {
                                    return(1);
                                }
                                goto default;
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeUnsignedByte:
                            //Remember that xsd:unsignedByte is equivalent to Byte in .Net
                            //Extract the Byte Values and compare
                            byte aByte, bByte;
                            if (Byte.TryParse(a.Value, out aByte))
                            {
                                if (Byte.TryParse(b.Value, out bByte))
                                {
                                    return(aByte.CompareTo(bByte));
                                }
                                else
                                {
                                    return(-1);
                                }
                            }
                            else
                            {
                                if (Byte.TryParse(b.Value, out bByte))
                                {
                                    return(1);
                                }
                                else
                                {
                                    goto default;
                                }
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeInt:
                        case XmlSpecsHelper.XmlSchemaDataTypeInteger:
                        case XmlSpecsHelper.XmlSchemaDataTypeLong:
                        case XmlSpecsHelper.XmlSchemaDataTypeShort:
                            //Extract the Integer Values and compare
                            long aInt64, bInt64;
                            if (Int64.TryParse(a.Value, out aInt64))
                            {
                                if (Int64.TryParse(b.Value, out bInt64))
                                {
                                    return(aInt64.CompareTo(bInt64));
                                }
                                else
                                {
                                    return(-1);
                                }
                            }
                            else
                            {
                                if (Int64.TryParse(b.Value, out bInt64))
                                {
                                    return(1);
                                }
                                else
                                {
                                    goto default;
                                }
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeNegativeInteger:
                        case XmlSpecsHelper.XmlSchemaDataTypeNonPositiveInteger:
                            //Extract the Integer Values, ensure negative and compare
                            long aNegInt, bNegInt;
                            if (Int64.TryParse(a.Value, out aNegInt))
                            {
                                if (Int64.TryParse(b.Value, out bNegInt))
                                {
                                    if (aNegInt >= 0)
                                    {
                                        if (bNegInt >= 0)
                                        {
                                            goto default;
                                        }
                                        else
                                        {
                                            return(1);
                                        }
                                    }
                                    else if (bNegInt >= 0)
                                    {
                                        return(-1);
                                    }
                                    else
                                    {
                                        return(aNegInt.CompareTo(bNegInt));
                                    }
                                }
                                else if (aNegInt >= 0)
                                {
                                    goto default;
                                }
                                else
                                {
                                    return(-1);
                                }
                            }
                            else
                            {
                                if (Int64.TryParse(b.Value, out bNegInt))
                                {
                                    if (bNegInt >= 0)
                                    {
                                        goto default;
                                    }
                                    else
                                    {
                                        return(1);
                                    }
                                }
                                else
                                {
                                    goto default;
                                }
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeUnsignedInt:
                        case XmlSpecsHelper.XmlSchemaDataTypeUnsignedLong:
                        case XmlSpecsHelper.XmlSchemaDataTypeUnsignedShort:
                        case XmlSpecsHelper.XmlSchemaDataTypeNonNegativeInteger:
                        case XmlSpecsHelper.XmlSchemaDataTypePositiveInteger:
                            //Unsigned Integers
                            //Note that for NonNegativeInteger and PositiveInteger we don't need to do the
                            //same checking we have to do for their inverse types since parsing into an
                            //Unsigned Long ensures that they must be positive
                            ulong aUInt64, bUInt64;
                            if (UInt64.TryParse(a.Value, out aUInt64))
                            {
                                if (UInt64.TryParse(b.Value, out bUInt64))
                                {
                                    return(aUInt64.CompareTo(bUInt64));
                                }
                                else
                                {
                                    return(-1);
                                }
                            }
                            else
                            {
                                if (UInt64.TryParse(b.Value, out bUInt64))
                                {
                                    return(1);
                                }
                                else
                                {
                                    goto default;
                                }
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeDouble:
                            //Extract the Double Values and compare
                            double aDouble, bDouble;
                            if (Double.TryParse(a.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out aDouble))
                            {
                                if (Double.TryParse(b.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out bDouble))
                                {
                                    return(aDouble.CompareTo(bDouble));
                                }
                                else
                                {
                                    return(-1);
                                }
                            }
                            else
                            {
                                if (Double.TryParse(b.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out bDouble))
                                {
                                    return(1);
                                }
                                else
                                {
                                    goto default;
                                }
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeDecimal:
                            //Extract the Decimal Values and compare
                            decimal aDecimal, bDecimal;
                            if (decimal.TryParse(a.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out aDecimal))
                            {
                                if (decimal.TryParse(b.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out bDecimal))
                                {
                                    return(aDecimal.CompareTo(bDecimal));
                                }
                                else
                                {
                                    return(-1);
                                }
                            }
                            else
                            {
                                if (decimal.TryParse(b.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out bDecimal))
                                {
                                    return(1);
                                }
                                else
                                {
                                    goto default;
                                }
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeFloat:
                            //Extract the Float Values and compare
                            float aFloat, bFloat;
                            if (Single.TryParse(a.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out aFloat))
                            {
                                if (Single.TryParse(b.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out bFloat))
                                {
                                    return(aFloat.CompareTo(bFloat));
                                }
                                else
                                {
                                    return(-1);
                                }
                            }
                            else
                            {
                                if (Single.TryParse(b.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out bFloat))
                                {
                                    return(1);
                                }
                                else
                                {
                                    goto default;
                                }
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeHexBinary:
                            //Extract the numeric value of the Hex encoded Binary and compare
                            long aHex, bHex;
                            if (Int64.TryParse(a.Value, System.Globalization.NumberStyles.HexNumber, null, out aHex))
                            {
                                if (Int64.TryParse(b.Value, System.Globalization.NumberStyles.HexNumber, null, out bHex))
                                {
                                    return(aHex.CompareTo(bHex));
                                }
                                else
                                {
                                    return(-1);
                                }
                            }
                            else
                            {
                                if (Int64.TryParse(b.Value, System.Globalization.NumberStyles.HexNumber, null, out bHex))
                                {
                                    return(1);
                                }
                                else
                                {
                                    goto default;
                                }
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeBase64Binary:
                            //Extract the numeric value of the Base 64 encoded Binary and compare
                            byte[] aBin, bBin;
                            try
                            {
                                aBin = Convert.FromBase64String(a.Value);
                                try
                                {
                                    bBin = Convert.FromBase64String(b.Value);

                                    if (aBin.Length > bBin.Length)
                                    {
                                        return(1);
                                    }
                                    else if (aBin.Length < bBin.Length)
                                    {
                                        return(-1);
                                    }
                                    else
                                    {
                                        for (int i = 0; i < aBin.Length; i++)
                                        {
                                            if (aBin[i] != bBin[i])
                                            {
                                                return(aBin[i].CompareTo(bBin[i]));
                                            }
                                        }
                                        return(0);
                                    }
                                }
                                catch
                                {
                                    return(-1);
                                }
                            }
                            catch
                            {
                                try
                                {
                                    bBin = Convert.FromBase64String(b.Value);
                                    return(1);
                                }
                                catch
                                {
                                    goto default;
                                }
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeString:
                        //String Type
                        //Can use Lexical Ordering for thisgoto default;

                        case XmlSpecsHelper.XmlSchemaDataTypeAnyUri:
                            //Uri Type
                            //Try and convert to a URI and use lexical ordering
                            Uri aUri, bUri;
                            try
                            {
                                aUri = UriFactory.Create(a.Value);
                                try
                                {
                                    bUri = UriFactory.Create(b.Value);
                                    return(ComparisonHelper.CompareUris(aUri, bUri));
                                }
                                catch
                                {
                                    return(-1);
                                }
                            }
                            catch
                            {
                                try
                                {
                                    bUri = UriFactory.Create(b.Value);
                                    return(1);
                                }
                                catch
                                {
                                    goto default;
                                }
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeDate:
                        case XmlSpecsHelper.XmlSchemaDataTypeDateTime:
                            //Extract the Date Times and compare
                            DateTimeOffset aDateTimeOffset, bDateTimeOffset;
                            if (DateTimeOffset.TryParse(a.Value, out aDateTimeOffset))
                            {
                                if (DateTimeOffset.TryParse(b.Value, out bDateTimeOffset))
                                {
                                    return(aDateTimeOffset.CompareTo(bDateTimeOffset));
                                }
                                else
                                {
                                    return(-1);
                                }
                            }
                            else
                            {
                                if (DateTimeOffset.TryParse(b.Value, out bDateTimeOffset))
                                {
                                    return(1);
                                }
                                else
                                {
                                    goto default;
                                }
                            }

                        case XmlSpecsHelper.XmlSchemaDataTypeDuration:
                        case XmlSpecsHelper.XmlSchemaDataTypeDayTimeDuration:
                            //Extract the TimeSpan's and compare
                            TimeSpan aTimeSpan, bTimeSpan;
                            try
                            {
                                aTimeSpan = XmlConvert.ToTimeSpan(a.Value);
                                try
                                {
                                    bTimeSpan = XmlConvert.ToTimeSpan(b.Value);
                                    return(aTimeSpan.CompareTo(bTimeSpan));
                                }
                                catch
                                {
                                    return(-1);
                                }
                            }
                            catch
                            {
                                try
                                {
                                    bTimeSpan = XmlConvert.ToTimeSpan(b.Value);
                                    return(1);
                                }
                                catch
                                {
                                    goto default;
                                }
                            }

                        default:
                            //Don't know how to order so use lexical ordering on the value
                            return(String.Compare(a.Value, b.Value, culture, comparisonOptions));
                        }
                    }
                    catch
                    {
                        //There was some error suggesting a non-valid value for a type
                        //e.g. "example"^^xsd:integer
                        //In this case just use lexical ordering on the value
                        return(String.Compare(a.Value, b.Value, culture, comparisonOptions));
                    }
                }
            }
            else
            {
                //No way of ordering by value if the Data Types are different
                //Order by Data Type Uri
                //This is required or the Value ordering between types won't occur correctly
                return(ComparisonHelper.CompareUris(a.DataType, b.DataType));
            }
        }
예제 #36
0
 internal SortKey(String localeName, String str, CompareOptions options, byte[] keyData)
 {
     throw new NotImplementedException();
 }
예제 #37
0
        // Determines whether two string regions match.  The substring of strA beginning
        // at indexA of length length is compared with the substring of strB
        // beginning at indexB of the same length.  Case sensitivity is determined by the ignoreCase boolean,
        // and the culture is set by culture.
        //
        public static int Compare(string?strA, int indexA, string?strB, int indexB, int length, bool ignoreCase, CultureInfo?culture)
        {
            CompareOptions options = ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None;

            return(Compare(strA, indexA, strB, indexB, length, culture, options));
        }
예제 #38
0
        public void Test(CultureInfo culture, string str1, string str2, bool expected, CompareOptions options)
        {
            CompareInfo ci = culture.CompareInfo;
            bool        i  = ci.IsPrefix(str1, str2, options);

            Assert.Equal(expected, i);
        }
예제 #39
0
 private static bool CanUseAsciiOrdinalForOptions(CompareOptions options)
 {
     // Unlike the other Ignore options, IgnoreSymbols impacts ASCII characters (e.g. ').
     return((options & CompareOptions.IgnoreSymbols) == 0);
 }
예제 #40
0
        private unsafe int CompareString(ReadOnlySpan <char> string1, ReadOnlySpan <char> string2, CompareOptions options)
        {
            Debug.Assert(!GlobalizationMode.Invariant);
            Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);

            // Unlike NLS, ICU (ucol_getSortKey) allows passing nullptr for either of the source arguments
            // as long as the corresponding length parameter is 0.

            fixed(char *pString1 = &MemoryMarshal.GetReference(string1))
            fixed(char *pString2 = &MemoryMarshal.GetReference(string2))
            {
                return(Interop.Globalization.CompareString(_sortHandle, pString1, string1.Length, pString2, string2.Length, options));
            }
        }
예제 #41
0
        internal unsafe int IndexOfCore(string source, string target, int startIndex, int count, CompareOptions options, int *matchLengthPtr)
        {
            Debug.Assert(!GlobalizationMode.Invariant);

            Debug.Assert(!string.IsNullOrEmpty(source));
            Debug.Assert(target != null);
            Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
            Debug.Assert((options & CompareOptions.Ordinal) == 0);

            int index;

            if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options))
            {
                if ((options & CompareOptions.IgnoreCase) != 0)
                {
                    index = IndexOfOrdinalIgnoreCaseHelper(source.AsSpan(startIndex, count), target.AsSpan(), options, matchLengthPtr, fromBeginning: true);
                }
                else
                {
                    index = IndexOfOrdinalHelper(source.AsSpan(startIndex, count), target.AsSpan(), options, matchLengthPtr, fromBeginning: true);
                }
            }
            else
            {
                fixed(char *pSource = source)
                fixed(char *pTarget = target)
                {
                    index = Interop.Globalization.IndexOf(_sortHandle, pTarget, target.Length, pSource + startIndex, count, options, matchLengthPtr);
                }
            }

            return(index != -1 ? index + startIndex : -1);
        }
예제 #42
0
 public void IndexOf_Aesc_Ligature(CompareInfo compareInfo, string source, string value, int startIndex, int count, CompareOptions options, int expected)
 {
     // TODO: Remove this function, and combine into IndexOf_String once 5463 is fixed
     IndexOf_String(compareInfo, source, value, startIndex, count, options, expected);
 }
예제 #43
0
        private unsafe bool StartsWithOrdinalIgnoreCaseHelper(ReadOnlySpan <char> source, ReadOnlySpan <char> prefix, CompareOptions options)
        {
            Debug.Assert(!GlobalizationMode.Invariant);

            Debug.Assert(!prefix.IsEmpty);
            Debug.Assert(_isAsciiEqualityOrdinal);

            int length = Math.Min(source.Length, prefix.Length);

            fixed(char *ap = &MemoryMarshal.GetReference(source))  // could be null (or otherwise unable to be dereferenced)
            fixed(char *bp = &MemoryMarshal.GetReference(prefix))
            {
                char *a = ap;
                char *b = bp;

                while (length != 0)
                {
                    int charA = *a;
                    int charB = *b;

                    if (charA >= 0x80 || charB >= 0x80 || HighCharTable[charA] || HighCharTable[charB])
                    {
                        goto InteropCall;
                    }

                    if (charA == charB)
                    {
                        a++; b++;
                        length--;
                        continue;
                    }

                    // uppercase both chars - notice that we need just one compare per char
                    if ((uint)(charA - 'a') <= (uint)('z' - 'a'))
                    {
                        charA -= 0x20;
                    }
                    if ((uint)(charB - 'a') <= (uint)('z' - 'a'))
                    {
                        charB -= 0x20;
                    }

                    if (charA == charB)
                    {
                        a++; b++;
                        length--;
                        continue;
                    }

                    // The match may be affected by special character. Verify that the following character is regular ASCII.
                    if (a < ap + source.Length - 1 && *(a + 1) >= 0x80)
                    {
                        goto InteropCall;
                    }
                    if (b < bp + prefix.Length - 1 && *(b + 1) >= 0x80)
                    {
                        goto InteropCall;
                    }
                    return(false);
                }

                // The match may be affected by special character. Verify that the following character is regular ASCII.

                if (source.Length < prefix.Length)
                {
                    if (*b >= 0x80)
                    {
                        goto InteropCall;
                    }
                    return(false);
                }

                if (source.Length > prefix.Length)
                {
                    if (*a >= 0x80)
                    {
                        goto InteropCall;
                    }
                }
                return(true);

InteropCall:
                return(Interop.Globalization.StartsWith(_sortHandle, bp, prefix.Length, ap, source.Length, options));
            }
        }
예제 #44
0
        private unsafe int CompareString(ReadOnlySpan <char> string1, ReadOnlySpan <char> string2, CompareOptions options)
        {
            Debug.Assert(!_invariantMode);
            Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);

            fixed(char *pString1 = &MemoryMarshal.GetReference(string1))
            fixed(char *pString2 = &MemoryMarshal.GetReference(string2))
            {
                return(Interop.GlobalizationInterop.CompareString(_sortHandle, pString1, string1.Length, pString2, string2.Length, options));
            }
        }
예제 #45
0
        // Determines whether two string regions match.  The substring of strA beginning
        // at indexA of length length is compared with the substring of strB
        // beginning at indexB of the same length.
        //
        public static int Compare(string?strA, int indexA, string?strB, int indexB, int length, CultureInfo?culture, CompareOptions options)
        {
            CultureInfo compareCulture = culture ?? CultureInfo.CurrentCulture;
            int         lengthA        = length;
            int         lengthB        = length;

            if (strA != null)
            {
                lengthA = Math.Min(lengthA, strA.Length - indexA);
            }

            if (strB != null)
            {
                lengthB = Math.Min(lengthB, strB.Length - indexB);
            }

            return(compareCulture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, options));
        }
 /// <summary>
 /// Returns true if a string contains a substring, using the specified culture and comparison options.
 /// </summary>
 public static bool Contains(this string s, string value, CultureInfo culture, CompareOptions options = CompareOptions.None)
 {
     return(0 <= culture.CompareInfo.IndexOf(s, value, options));
 }
예제 #47
0
        // Provides a culture-correct string comparison. strA is compared to strB
        // to determine whether it is lexicographically less, equal, or greater, and then a
        // negative integer, 0, or a positive integer is returned; respectively.
        //
        public static int Compare(string?strA, string?strB, CultureInfo?culture, CompareOptions options)
        {
            CultureInfo compareCulture = culture ?? CultureInfo.CurrentCulture;

            return(compareCulture.CompareInfo.Compare(strA, strB, options));
        }
예제 #48
0
 public void IndexOf_Char(CompareInfo compareInfo, string source, char value, int startIndex, int count, CompareOptions options, int expected)
 {
     if (options == CompareOptions.None)
     {
         // Use IndexOf(string, char, int, int) or IndexOf(string, char)
         if (startIndex == 0 && count == source.Length)
         {
             // Use IndexOf(string, char)
             Assert.Equal(expected, compareInfo.IndexOf(source, value));
         }
         // Use IndexOf(string, char, int, int)
         Assert.Equal(expected, compareInfo.IndexOf(source, value, startIndex, count));
     }
     if (startIndex + count == source.Length)
     {
         // Use IndexOf(string, char, int, CompareOptions) or IndexOf(string, char, CompareOptions)
         if (startIndex == 0)
         {
             // Use IndexOf(string, char, CompareOptions)
             Assert.Equal(expected, compareInfo.IndexOf(source, value, options));
         }
         // Use IndexOf(string, char, int, CompareOptions)
         Assert.Equal(expected, compareInfo.IndexOf(source, value, startIndex, options));
     }
     // Use IndexOf(string, char, int, int, CompareOptions)
     Assert.Equal(expected, compareInfo.IndexOf(source, value, startIndex, count, options));
 }
 public static StringComparer GetStringComparer(this CompareInfo compareInfo, CompareOptions options)
 {
     throw null;
 }
        public void SortKeyTest(CompareInfo compareInfo, string string1, string string2, CompareOptions options, int expected)
        {
            SortKey sk1 = compareInfo.GetSortKey(string1, options);
            SortKey sk2 = compareInfo.GetSortKey(string2, options);

            Assert.Equal(expected, SortKey.Compare(sk1, sk2));
            Assert.Equal(string1, sk1.OriginalString);
            Assert.Equal(string2, sk2.OriginalString);
        }
예제 #51
0
        private unsafe int LastIndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
        {
            Debug.Assert(!_invariantMode);

            Debug.Assert(!string.IsNullOrEmpty(source));
            Debug.Assert(target != null);
            Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);

            if (target.Length == 0)
            {
                return(startIndex);
            }

            if (options == CompareOptions.Ordinal)
            {
                return(LastIndexOfOrdinalCore(source, target, startIndex, count, ignoreCase: false));
            }

#if CORECLR
            if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && target.IsFastSort())
            {
                return(LastIndexOf(source, target, startIndex, count, GetOrdinalCompareOptions(options)));
            }
#endif

            // startIndex is the index into source where we start search backwards from. leftStartIndex is the index into source
            // of the start of the string that is count characters away from startIndex.
            int leftStartIndex = (startIndex - count + 1);

            fixed(char *pSource = source)
            {
                int lastIndex = Interop.GlobalizationInterop.LastIndexOf(_sortHandle, target, target.Length, pSource + (startIndex - count + 1), count, options);

                return(lastIndex != -1 ? lastIndex + leftStartIndex : -1);
            }
        }
예제 #52
0
 public virtual int LastIndexOf(string source, char value, CompareOptions options);
예제 #53
0
 /// <summary>
 /// Creates a new string comparer with a specified culture.
 /// </summary>
 public PhpLocaleStringComparer(Context ctx, CultureInfo culture, CompareOptions options)
 {
     _ctx     = ctx;
     _culture = culture ?? CultureInfo.InvariantCulture;
     _options = options;
 }
예제 #54
0
        private unsafe int IndexOfOrdinalHelper(ReadOnlySpan <char> source, ReadOnlySpan <char> target, CompareOptions options, int *matchLengthPtr, bool fromBeginning)
        {
            Debug.Assert(!GlobalizationMode.Invariant);

            Debug.Assert(!target.IsEmpty);
            Debug.Assert(_isAsciiEqualityOrdinal);

            fixed(char *ap = &MemoryMarshal.GetReference(source))
            fixed(char *bp = &MemoryMarshal.GetReference(target))
            {
                char *a = ap;
                char *b = bp;

                for (int j = 0; j < target.Length; j++)
                {
                    char targetChar = *(b + j);
                    if (targetChar >= 0x80 || HighCharTable[targetChar])
                    {
                        goto InteropCall;
                    }
                }

                if (target.Length > source.Length)
                {
                    for (int k = 0; k < source.Length; k++)
                    {
                        char targetChar = *(a + k);
                        if (targetChar >= 0x80 || HighCharTable[targetChar])
                        {
                            goto InteropCall;
                        }
                    }
                    return(-1);
                }

                int startIndex, endIndex, jump;

                if (fromBeginning)
                {
                    // Left to right, from zero to last possible index in the source string.
                    // Incrementing by one after each iteration. Stop condition is last possible index plus 1.
                    startIndex = 0;
                    endIndex   = source.Length - target.Length + 1;
                    jump       = 1;
                }
                else
                {
                    // Right to left, from first possible index in the source string to zero.
                    // Decrementing by one after each iteration. Stop condition is last possible index minus 1.
                    startIndex = source.Length - target.Length;
                    endIndex   = -1;
                    jump       = -1;
                }

                for (int i = startIndex; i != endIndex; i += jump)
                {
                    int targetIndex = 0;
                    int sourceIndex = i;

                    for (; targetIndex < target.Length; targetIndex++, sourceIndex++)
                    {
                        char valueChar  = *(a + sourceIndex);
                        char targetChar = *(b + targetIndex);

                        if (valueChar >= 0x80 || HighCharTable[valueChar])
                        {
                            goto InteropCall;
                        }

                        if (valueChar == targetChar)
                        {
                            continue;
                        }

                        // The match may be affected by special character. Verify that the following character is regular ASCII.
                        if (sourceIndex < source.Length - 1 && *(a + sourceIndex + 1) >= 0x80)
                        {
                            goto InteropCall;
                        }
                        goto Next;
                    }

                    // The match may be affected by special character. Verify that the following character is regular ASCII.
                    if (sourceIndex < source.Length && *(a + sourceIndex) >= 0x80)
                    {
                        goto InteropCall;
                    }
                    if (matchLengthPtr != null)
                    {
                        *matchLengthPtr = target.Length;
                    }
                    return(i);

                    Next :;
                }

                return(-1);

InteropCall:
                if (fromBeginning)
                {
                    return(Interop.Globalization.IndexOf(_sortHandle, b, target.Length, a, source.Length, options, matchLengthPtr));
                }
                else
                {
                    return(Interop.Globalization.LastIndexOf(_sortHandle, b, target.Length, a, source.Length, options));
                }
            }
        }
예제 #55
0
 public virtual int LastIndexOf(string source, char value, int startIndex, int count, CompareOptions options);
예제 #56
0
        private unsafe int LastIndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
        {
            Debug.Assert(!GlobalizationMode.Invariant);

            Debug.Assert(!string.IsNullOrEmpty(source));
            Debug.Assert(target != null);
            Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);

            // startIndex points to the final char to include in the search space.
            // empty target strings trivially occur at the end of the search space.

            if (target.Length == 0)
            {
                return(startIndex + 1);
            }

            if (options == CompareOptions.Ordinal)
            {
                return(LastIndexOfOrdinalCore(source, target, startIndex, count, ignoreCase: false));
            }

            // startIndex is the index into source where we start search backwards from. leftStartIndex is the index into source
            // of the start of the string that is count characters away from startIndex.
            int leftStartIndex = (startIndex - count + 1);

            int lastIndex;

            if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options))
            {
                if ((options & CompareOptions.IgnoreCase) != 0)
                {
                    lastIndex = IndexOfOrdinalIgnoreCaseHelper(source.AsSpan(leftStartIndex, count), target.AsSpan(), options, matchLengthPtr: null, fromBeginning: false);
                }
                else
                {
                    lastIndex = IndexOfOrdinalHelper(source.AsSpan(leftStartIndex, count), target.AsSpan(), options, matchLengthPtr: null, fromBeginning: false);
                }
            }
            else
            {
                fixed(char *pSource = source)
                fixed(char *pTarget = target)
                {
                    lastIndex = Interop.Globalization.LastIndexOf(_sortHandle, pTarget, target.Length, pSource + (startIndex - count + 1), count, options);
                }
            }

            return(lastIndex != -1 ? lastIndex + leftStartIndex : -1);
        }
예제 #57
0
 public virtual bool IsSuffix(string source, string suffix, CompareOptions options);
예제 #58
0
        // For now, this method is only called from Span APIs with either options == CompareOptions.None or CompareOptions.IgnoreCase
        internal unsafe int IndexOfCore(ReadOnlySpan <char> source, ReadOnlySpan <char> target, CompareOptions options, int *matchLengthPtr, bool fromBeginning)
        {
            Debug.Assert(!GlobalizationMode.Invariant);
            Debug.Assert(source.Length != 0);
            Debug.Assert(target.Length != 0);

            if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options))
            {
                if ((options & CompareOptions.IgnoreCase) != 0)
                {
                    return(IndexOfOrdinalIgnoreCaseHelper(source, target, options, matchLengthPtr, fromBeginning));
                }
                else
                {
                    return(IndexOfOrdinalHelper(source, target, options, matchLengthPtr, fromBeginning));
                }
            }
            else
            {
                fixed(char *pSource = &MemoryMarshal.GetReference(source))
                fixed(char *pTarget = &MemoryMarshal.GetReference(target))
                {
                    if (fromBeginning)
                    {
                        return(Interop.Globalization.IndexOf(_sortHandle, pTarget, target.Length, pSource, source.Length, options, matchLengthPtr));
                    }
                    else
                    {
                        return(Interop.Globalization.LastIndexOf(_sortHandle, pTarget, target.Length, pSource, source.Length, options));
                    }
                }
            }
        }
예제 #59
0
        private unsafe bool StartsWith(ReadOnlySpan <char> source, ReadOnlySpan <char> prefix, CompareOptions options)
        {
            Debug.Assert(!GlobalizationMode.Invariant);

            Debug.Assert(!prefix.IsEmpty);
            Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);

            if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options))
            {
                if ((options & CompareOptions.IgnoreCase) != 0)
                {
                    return(StartsWithOrdinalIgnoreCaseHelper(source, prefix, options));
                }
                else
                {
                    return(StartsWithOrdinalHelper(source, prefix, options));
                }
            }
            else
            {
                fixed(char *pSource = &MemoryMarshal.GetReference(source))  // could be null (or otherwise unable to be dereferenced)
                fixed(char *pPrefix = &MemoryMarshal.GetReference(prefix))
                {
                    return(Interop.Globalization.StartsWith(_sortHandle, pPrefix, prefix.Length, pSource, source.Length, options));
                }
            }
        }
예제 #60
0
        public static IEnumerable <object[]> Compare_TestData()
        {
            CompareOptions ignoreKanaIgnoreWidthIgnoreCase = CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase;

            yield return(new object[] { s_invariantCompare, "\u3042", "\u30A2", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u3042", "\uFF71", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u304D\u3083", "\u30AD\u30E3", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u304D\u3083", "\u30AD\u3083", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u304D \u3083", "\u30AD\u3083", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "\u3044", "I", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "a", "A", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "a", "\uFF41", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "ABCDE", "\uFF21\uFF22\uFF23\uFF24\uFF25", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "ABCDE", "\uFF21\uFF22\uFF23D\uFF25", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "ABCDE", "a\uFF22\uFF23D\uFF25", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "ABCDE", "\uFF41\uFF42\uFF23D\uFF25", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u6FA4", "\u6CA2", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u30D6\u30D9\u30DC", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\u30DC", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u3079\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u30D6", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "\u3071\u3074\u30D7\u307A", "\uFF8B\uFF9F\uFF8C\uFF9F", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u3070\uFF8E\uFF9E\u30D6", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C\u3079\u307C", "\u3079\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "\u3070\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u30D6", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "ABDDE", "D", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "ABCDE", "\uFF43D", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "ABCDE", "c", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "\u3060", "\u305F", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "\u3060", "\uFF80\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u3060", "\u30C0", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u30C7\u30BF\u30D9\u30B9", "\uFF83\uFF9E\uFF80\uFF8D\uFF9E\uFF7D", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u30C7", "\uFF83\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u30C7\u30BF", "\uFF83\uFF9E\uFF80", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u30C7\u30BF\u30D9", "\uFF83\uFF9E\uFF80\uFF8D\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u30BF", "\uFF80", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\uFF83\uFF9E\uFF70\uFF80\uFF8D\uFF9E\uFF70\uFF7D", "\u3067\u30FC\u305F\u3079\u30FC\u3059", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u68EE\u9D0E\u5916", "\u68EE\u9DD7\u5916", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "\u68EE\u9DD7\u5916", "\u68EE\u9DD7\u5916", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u2019\u2019\u2019\u2019", "''''", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "\u2019", "'", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "", "'", ignoreKanaIgnoreWidthIgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "\u4E00", "\uFF11", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "\u2160", "\uFF11", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "0", "\uFF10", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "10", "1\uFF10", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "9999\uFF1910", "1\uFF10", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "9999\uFF191010", "1\uFF10", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "'\u3000'", "' '", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\uFF1B", ";", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\uFF08", "(", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u30FC", "\uFF70", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u30FC", "\uFF0D", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "\u30FC", "\u30FC", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u30FC", "\u2015", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "\u30FC", "\u2010", ignoreKanaIgnoreWidthIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "/", "\uFF0F", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "'", "\uFF07", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\"", "\uFF02", ignoreKanaIgnoreWidthIgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u3042", "\u30A1", CompareOptions.None, s_expectedHiraganaToKatakanaCompare });

            yield return(new object[] { s_invariantCompare, "\u3042", "\u30A2", CompareOptions.None, s_expectedHiraganaToKatakanaCompare });

            yield return(new object[] { s_invariantCompare, "\u3042", "\uFF71", CompareOptions.None, s_expectedHiraganaToKatakanaCompare });

            yield return(new object[] { s_invariantCompare, "\u304D\u3083", "\u30AD\u30E3", CompareOptions.None, s_expectedHiraganaToKatakanaCompare });

            yield return(new object[] { s_invariantCompare, "\u304D\u3083", "\u30AD\u3083", CompareOptions.None, s_expectedHiraganaToKatakanaCompare });

            yield return(new object[] { s_invariantCompare, "\u304D \u3083", "\u30AD\u3083", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "\u3044", "I", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "a", "A", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "a", "\uFF41", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "ABCDE", "\uFF21\uFF22\uFF23\uFF24\uFF25", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "ABCDE", "\uFF21\uFF22\uFF23D\uFF25", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5554) + "b", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "ABCDE", "\uFF41\uFF42\uFF23D\uFF25", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\u6FA4", "\u6CA2", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u30D6\u30D9\u30DC", CompareOptions.None, s_expectedHiraganaToKatakanaCompare });

            yield return(new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\u30DC", CompareOptions.None, s_expectedHiraganaToKatakanaCompare });

            yield return(new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", CompareOptions.None, s_expectedHiraganaToKatakanaCompare });

            yield return(new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", CompareOptions.None, s_expectedHiraganaToKatakanaCompare });

            yield return(new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\uFF8E\uFF9E", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u3079\uFF8E\uFF9E", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u30D6", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "\u3071\u3074\u30D7\u307A", "\uFF8B\uFF9F\uFF8C\uFF9F", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u3070\uFF8E\uFF9E\u30D6", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C\u3079\u307C", "\u3079\uFF8E\uFF9E", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "\u3070\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\u30D6", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "ABDDE", "D", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "ABCDE", "\uFF43D\uFF25", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "ABCDE", "\uFF43D", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "ABCDE", "c", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "\u3060", "\u305F", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\u3060", "\uFF80\uFF9E", CompareOptions.None, s_expectedHiraganaToKatakanaCompare });

            yield return(new object[] { s_invariantCompare, "\u3060", "\u30C0", CompareOptions.None, s_expectedHiraganaToKatakanaCompare });

            yield return(new object[] { s_invariantCompare, "\u68EE\u9D0E\u5916", "\u68EE\u9DD7\u5916", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "\u68EE\u9DD7\u5916", "\u68EE\u9DD7\u5916", CompareOptions.None, 0 });

            yield return(new object[] { s_invariantCompare, "\u2019\u2019\u2019\u2019", "''''", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\u2019\u2019\u2019\u2019", "''''", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\u2019\u2019\u2019\u2019", "''''", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\u2019", "'", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "", "'", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "\u4E00", "\uFF11", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\u2160", "\uFF11", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "0", "\uFF10", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "10", "1\uFF10", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "1\uFF10", "1\uFF10", CompareOptions.None, 0 });

            yield return(new object[] { s_invariantCompare, "9999\uFF1910", "1\uFF10", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "9999\uFF191010", "1\uFF10", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "'\u3000'", "' '", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\uFF1B", ";", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\uFF08", "(", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\u30FC", "\uFF0D", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\u30FC", "\u30FC", CompareOptions.None, 0 });

            yield return(new object[] { s_invariantCompare, "\u30FC", "\u2015", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\u30FC", "\u2010", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "/", "\uFF0F", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "'", "\uFF07", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "\"", "\uFF02", CompareOptions.None, -1 });

            // Hungarian
            yield return(new object[] { s_hungarianCompare, "dzsdzs", "ddzs", CompareOptions.Ordinal, 1 });

            yield return(new object[] { s_invariantCompare, "dzsdzs", "ddzs", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "dzsdzs", "ddzs", CompareOptions.Ordinal, 1 });

            // Turkish
            yield return(new object[] { s_turkishCompare, "i", "I", CompareOptions.None, 1 });

            yield return(new object[] { s_turkishCompare, "i", "I", CompareOptions.IgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "i", "\u0130", CompareOptions.None, -1 });

            yield return(new object[] { s_turkishCompare, "i", "\u0130", CompareOptions.IgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "i", "I", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "i", "I", CompareOptions.IgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "i", "\u0130", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "i", "\u0130", CompareOptions.IgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "\u00C0", "A\u0300", CompareOptions.None, 0 });

            yield return(new object[] { s_invariantCompare, "\u00C0", "A\u0300", CompareOptions.Ordinal, 1 });

            yield return(new object[] { s_invariantCompare, "\u00C0", "a\u0300", CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, "\u00C0", "a\u0300", CompareOptions.IgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u00C0", "a\u0300", CompareOptions.Ordinal, 1 });

            yield return(new object[] { s_invariantCompare, "\u00C0", "a\u0300", CompareOptions.OrdinalIgnoreCase, 1 });

            yield return(new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", CompareOptions.Ordinal, -1 });

            yield return(new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, 0 });

            yield return(new object[] { s_invariantCompare, "Test's", "Tests", CompareOptions.IgnoreSymbols, 0 });

            yield return(new object[] { s_invariantCompare, "Test's", "Tests", CompareOptions.StringSort, -1 });

            yield return(new object[] { s_invariantCompare, null, "Tests", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "Test's", null, CompareOptions.None, 1 });

            yield return(new object[] { s_invariantCompare, null, null, CompareOptions.None, 0 });

            yield return(new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5555), CompareOptions.None, 0 });

            yield return(new object[] { s_invariantCompare, "foobar", "FooB\u00C0R", CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "foobar", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, -1 });

            yield return(new object[] { s_invariantCompare, "\uFF9E", "\u3099", CompareOptions.IgnoreNonSpace, 0 });

            yield return(new object[] { s_invariantCompare, "\uFF9E", "\u3099", CompareOptions.IgnoreCase, 0 });

            yield return(new object[] { s_invariantCompare, "\u20A9", "\uFFE6", CompareOptions.IgnoreWidth, 0 });

            yield return(new object[] { s_invariantCompare, "\u20A9", "\uFFE6", CompareOptions.IgnoreCase, -1 });

            yield return(new object[] { s_invariantCompare, "\u20A9", "\uFFE6", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "\u0021", "\uFF01", CompareOptions.IgnoreSymbols, 0 });

            yield return(new object[] { s_invariantCompare, "\u00A2", "\uFFE0", CompareOptions.IgnoreSymbols, 0 });

            yield return(new object[] { s_invariantCompare, "$", "&", CompareOptions.IgnoreSymbols, 0 });

            yield return(new object[] { s_invariantCompare, "\uFF65", "\u30FB", CompareOptions.IgnoreSymbols, 0 });

            yield return(new object[] { s_invariantCompare, "\u0021", "\uFF01", CompareOptions.IgnoreWidth, 0 });

            yield return(new object[] { s_invariantCompare, "\u0021", "\uFF01", CompareOptions.None, -1 });

            yield return(new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreWidth, 0 });

            yield return(new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreSymbols, s_expectedHalfToFullFormsComparison });

            yield return(new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreCase, s_expectedHalfToFullFormsComparison });

            yield return(new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreNonSpace, s_expectedHalfToFullFormsComparison });

            yield return(new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.None, s_expectedHalfToFullFormsComparison });

            yield return(new object[] { s_invariantCompare, "\u3060", "\u30C0", CompareOptions.IgnoreKanaType, 0 });

            yield return(new object[] { s_invariantCompare, "\u3060", "\u30C0", CompareOptions.IgnoreCase, s_expectedHiraganaToKatakanaCompare });

            yield return(new object[] { s_invariantCompare, "c", "C", CompareOptions.IgnoreKanaType, -1 });
        }