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); }
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); }