diff options
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 96 |
1 files changed, 94 insertions, 2 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index 5497e2c..903c19c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | |||
@@ -629,6 +629,98 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
629 | } | 629 | } |
630 | } | 630 | } |
631 | 631 | ||
632 | private class AlphanumComparatorFast : IComparer | ||
633 | { | ||
634 | public int Compare(object x, object y) | ||
635 | { | ||
636 | string s1 = x as string; | ||
637 | if (s1 == null) | ||
638 | { | ||
639 | return 0; | ||
640 | } | ||
641 | string s2 = y as string; | ||
642 | if (s2 == null) | ||
643 | { | ||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | int len1 = s1.Length; | ||
648 | int len2 = s2.Length; | ||
649 | int marker1 = 0; | ||
650 | int marker2 = 0; | ||
651 | |||
652 | // Walk through two the strings with two markers. | ||
653 | while (marker1 < len1 && marker2 < len2) | ||
654 | { | ||
655 | char ch1 = s1[marker1]; | ||
656 | char ch2 = s2[marker2]; | ||
657 | |||
658 | // Some buffers we can build up characters in for each chunk. | ||
659 | char[] space1 = new char[len1]; | ||
660 | int loc1 = 0; | ||
661 | char[] space2 = new char[len2]; | ||
662 | int loc2 = 0; | ||
663 | |||
664 | // Walk through all following characters that are digits or | ||
665 | // characters in BOTH strings starting at the appropriate marker. | ||
666 | // Collect char arrays. | ||
667 | do | ||
668 | { | ||
669 | space1[loc1++] = ch1; | ||
670 | marker1++; | ||
671 | |||
672 | if (marker1 < len1) | ||
673 | { | ||
674 | ch1 = s1[marker1]; | ||
675 | } | ||
676 | else | ||
677 | { | ||
678 | break; | ||
679 | } | ||
680 | } while (char.IsDigit(ch1) == char.IsDigit(space1[0])); | ||
681 | |||
682 | do | ||
683 | { | ||
684 | space2[loc2++] = ch2; | ||
685 | marker2++; | ||
686 | |||
687 | if (marker2 < len2) | ||
688 | { | ||
689 | ch2 = s2[marker2]; | ||
690 | } | ||
691 | else | ||
692 | { | ||
693 | break; | ||
694 | } | ||
695 | } while (char.IsDigit(ch2) == char.IsDigit(space2[0])); | ||
696 | |||
697 | // If we have collected numbers, compare them numerically. | ||
698 | // Otherwise, if we have strings, compare them alphabetically. | ||
699 | string str1 = new string(space1); | ||
700 | string str2 = new string(space2); | ||
701 | |||
702 | int result; | ||
703 | |||
704 | if (char.IsDigit(space1[0]) && char.IsDigit(space2[0])) | ||
705 | { | ||
706 | int thisNumericChunk = int.Parse(str1); | ||
707 | int thatNumericChunk = int.Parse(str2); | ||
708 | result = thisNumericChunk.CompareTo(thatNumericChunk); | ||
709 | } | ||
710 | else | ||
711 | { | ||
712 | result = str1.CompareTo(str2); | ||
713 | } | ||
714 | |||
715 | if (result != 0) | ||
716 | { | ||
717 | return result; | ||
718 | } | ||
719 | } | ||
720 | return len1 - len2; | ||
721 | } | ||
722 | } | ||
723 | |||
632 | public list Sort(int stride, int ascending) | 724 | public list Sort(int stride, int ascending) |
633 | { | 725 | { |
634 | if (Data.Length == 0) | 726 | if (Data.Length == 0) |
@@ -647,7 +739,7 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
647 | for (int k = 0; k < Data.Length; k++) | 739 | for (int k = 0; k < Data.Length; k++) |
648 | keys[k] = Data[k].ToString(); | 740 | keys[k] = Data[k].ToString(); |
649 | 741 | ||
650 | Array.Sort(keys, ret); | 742 | Array.Sort( keys, ret, new AlphanumComparatorFast() ); |
651 | 743 | ||
652 | if (ascending == 0) | 744 | if (ascending == 0) |
653 | Array.Reverse(ret); | 745 | Array.Reverse(ret); |
@@ -683,7 +775,7 @@ namespace OpenSim.Region.ScriptEngine.Shared | |||
683 | vals[idx]=o; | 775 | vals[idx]=o; |
684 | } | 776 | } |
685 | 777 | ||
686 | Array.Sort(keys, vals); | 778 | Array.Sort(keys, vals, new AlphanumComparatorFast()); |
687 | if (ascending == 0) | 779 | if (ascending == 0) |
688 | { | 780 | { |
689 | Array.Reverse(vals); | 781 | Array.Reverse(vals); |