예제 #1
0
            public int Compare(UnmanagedStringArray.UnmanagedString string1, UnmanagedStringArray.UnmanagedString string2)
            {
                Debug.Assert(string1.IsNull == false);
                Debug.Assert(string2.IsNull == false);

                var string1State = new AlphanumericStringComparisonState(string1);
                var string2State = new AlphanumericStringComparisonState(string2);

                // Walk through two the strings with two markers.
                while (string1State.CurPositionInString < string1State.StringLength &&
                       string2State.CurPositionInString < string2State.StringLength)
                {
                    string1State.ScanNextAlphabeticOrNumericSequence();
                    string2State.ScanNextAlphabeticOrNumericSequence();

                    var result = string1State.CompareWithAnotherState(string2State);

                    if (result != 0)
                    {
                        return(result);
                    }
                }

                if (string1State.CurPositionInString < string1State.StringLength)
                {
                    return(1);
                }
                if (string2State.CurPositionInString < string2State.StringLength)
                {
                    return(-1);
                }

                return(0);
            }
                public int CompareWithAnotherState(AlphanumericStringComparisonState other)
                {
                    var string1State = this;
                    var string2State = other;

                    // if both seqeunces are numbers, compare between them
                    if (string1State.CurSequenceIsNumber && string2State.CurSequenceIsNumber)
                    {
                        // if effective numbers are not of the same length, it means that we can tell which is greatedr (in an order of magnitude, actually)
                        if (string1State.NumberLength != string2State.NumberLength)
                        {
                            return(string1State.NumberLength.CompareTo(string2State.NumberLength));
                        }

                        // else, it means they should be compared by string, again, we compare only the effective numbers
                        return(System.Globalization.CultureInfo.InvariantCulture.CompareInfo.Compare(
                                   string1State.OriginalString, string1State.CurPositionInString - string1State.NumberLength, string1State.NumberLength,
                                   string2State.OriginalString, string2State.CurPositionInString - string2State.NumberLength, string1State.NumberLength));
                    }

                    // if one of the sequences is a number and the other is not, the number is always smaller
                    if (string1State.CurSequenceIsNumber != string2State.CurSequenceIsNumber)
                    {
                        if (string1State.CurSequenceIsNumber)
                        {
                            return(-1);
                        }
                        return(1);
                    }

                    return(System.Globalization.CultureInfo.InvariantCulture.CompareInfo.Compare(
                               string1State.OriginalString, string1State.CurSequenceStartPosition, string1State.CurPositionInString - string1State.CurSequenceStartPosition,
                               string2State.OriginalString, string2State.CurSequenceStartPosition, string2State.CurPositionInString - string2State.CurSequenceStartPosition));
                }
            public unsafe int Compare(string string1, string string2)
            {
                if (string1 == null)
                {
                    return(0);
                }

                if (string2 == null)
                {
                    return(0);
                }

                var string1State = new AlphanumericStringComparisonState(string1);
                var string2State = new AlphanumericStringComparisonState(string2);

                // Walk through two the strings with two markers.
                while (string1State.CurPositionInString < string1State.StringLength &&
                       string2State.CurPositionInString < string2State.StringLength)
                {
                    string1State.ScanNextAlphabeticOrNumericSequence();
                    string2State.ScanNextAlphabeticOrNumericSequence();

                    var result = string1State.CompareWithAnotherState(string2State);

                    if (result != 0)
                    {
                        return(result);
                    }
                }

                if (string1State.CurPositionInString < string1State.StringLength)
                {
                    return(1);
                }
                if (string2State.CurPositionInString < string2State.StringLength)
                {
                    return(-1);
                }

                return(0);
            }
예제 #4
0
                public int CompareWithAnotherState(AlphanumericStringComparisonState other)
                {
                    var string1State = this;
                    var string2State = other;

                    // if both sequences are numbers, compare between them
                    if (string1State.CurSequenceIsNumber && string2State.CurSequenceIsNumber)
                    {
                        // if effective numbers are not of the same length, it means that we can tell which is greater (in an order of magnitude, actually)
                        if (string1State.NumberLength != string2State.NumberLength)
                        {
                            return(string1State.NumberLength.CompareTo(string2State.NumberLength));
                        }

                        // else, it means they should be compared by string, again, we compare only the effective numbers
                        // One digit is always one byte, so no need to care about chars vs bytes
                        return(string1State.OriginalString.StringAsBytes.Slice(string1State.StringBufferOffset - string1State.NumberLength, string1State.NumberLength)
                               .SequenceCompareTo(string2State.OriginalString.StringAsBytes.Slice(string2State.StringBufferOffset - string2State.NumberLength,
                                                                                                  string2State.NumberLength)));
                    }

                    // if one of the sequences is a number and the other is not, the number is always smaller
                    if (string1State.CurSequenceIsNumber != string2State.CurSequenceIsNumber)
                    {
                        if (string1State.CurSequenceIsNumber)
                        {
                            return(-1);
                        }
                        return(1);
                    }

                    // should be case insensitive
                    char ch1     = default;
                    char ch2     = default;
                    var  offset1 = string1State.CurSequenceStartPosition;
                    var  offset2 = string2State.CurSequenceStartPosition;

                    var length1 = string1State.StringBufferOffset - string1State.CurSequenceStartPosition;
                    var length2 = string2State.StringBufferOffset - string2State.CurSequenceStartPosition;

                    while (length1 > 0 && length2 > 0)
                    {
                        var read1 = ReadOneChar(string1State.OriginalString.StringAsBytes, offset1, ref ch1);
                        var read2 = ReadOneChar(string2State.OriginalString.StringAsBytes, offset2, ref ch2);

                        length1 -= read1;
                        length2 -= read2;

                        var result = char.ToLowerInvariant(ch1) - char.ToLowerInvariant(ch2);

                        if (result == 0)
                        {
                            offset1 += read1;
                            offset2 += read2;
                            continue;
                        }

                        return(result);
                    }

                    return(length1 - length2);
                }