Ignore:
Timestamp:
Sep 26, 2008, 8:47:44 PM (16 years ago)
Author:
イグトランス (egtra)
Message:

#202 Compare/CompareOrdinal完了

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/ablib/src/Classes/System/String.ab

    r621 r634  
    128128
    129129        Const Function Operator == (y As String) As Boolean
    130             Return Compare(This, y) = 0
     130            Return CompareOrdinal(This, y) = 0
    131131        End Function
    132132
    133133        Const Function Operator == (y As *Char) As Boolean
    134             Return Compare(This, y) = 0
     134            Return CompareOrdinal(This, y) = 0
    135135        End Function
    136136
    137137        Const Function Operator <> (y As String) As Boolean
    138             Return Compare(This, y) <> 0
     138            Return CompareOrdinal(This, y) <> 0
    139139        End Function
    140140
    141141        Const Function Operator <> (y As *Char) As Boolean
    142             Return Compare(This, y) <> 0
     142            Return CompareOrdinal(This, y) <> 0
    143143        End Function
    144144
    145145        Const Function Operator < (y As String) As Boolean
    146             Return Compare(This, y) < 0
     146            Return CompareOrdinal(This, y) < 0
    147147        End Function
    148148
    149149        Const Function Operator < (y As *Char) As Boolean
    150             Return Compare(This, y) < 0
     150            Return CompareOrdinal(This, y) < 0
    151151        End Function
    152152
    153153        Const Function Operator > (y As String) As Boolean
    154             Return Compare(This, y) > 0
     154            Return CompareOrdinal(This, y) > 0
    155155        End Function
    156156
    157157        Const Function Operator > (y As *Char) As Boolean
    158             Return Compare(This, y) > 0
     158            Return CompareOrdinal(This, y) > 0
    159159        End Function
    160160
    161161        Const Function Operator <= (y As String) As Boolean
    162             Return Compare(This, y) <= 0
     162            Return CompareOrdinal(This, y) <= 0
    163163        End Function
    164164
    165165        Const Function Operator <= (y As *Char) As Boolean
    166             Return Compare(This, y) <= 0
     166            Return CompareOrdinal(This, y) <= 0
    167167        End Function
    168168
    169169        Const Function Operator >= (y As String) As Boolean
    170             Return Compare(This, y) >= 0
     170            Return CompareOrdinal(This, y) >= 0
    171171        End Function
    172172
    173173        Const Function Operator >= (y As *Char) As Boolean
    174             Return Compare(This, y) >= 0
    175         End Function
    176 
     174            Return CompareOrdinal(This, y) >= 0
     175        End Function
     176
     177        /*!
     178        @brief 単語順での文字列比較
     179        @auther Egtra
     180        */
    177181        Static Function Compare(x As String, y As String) As Long
    178             Return CompareOrdinal(x, y)
    179         End Function
    180 
    181     Public
    182         'Compareなどで、x.Charsではなく、StrPtr(x)と書く理由は、xがNothingの場合のため。
     182            Return Compare(x, y, False)
     183        End Function
     184
     185        Static Function Compare(x As String, y As String, ignoreCase As Boolean) As Long
     186            Dim lhs = removeNull(x)
     187            Dim rhs = removeNull(y)
     188            Return compareImpl(lhs.Chars, lhs.Length, rhs.Chars, rhs.Length, ignoreCase)
     189        End Function
    183190
    184191        Static Function Compare(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
    185             Return CompareOrdinal(x, indexX, y, indexY, length)
    186         End Function
    187 
     192            Return Compare(x, indexX, y, indexY, length, False)
     193        End Function
     194
     195        Static Function Compare(x As String, indexX As Long, y As String, indexY As Long, length As Long, ignoreCase As Boolean) As Long
     196            Dim lhs = removeNull(x)
     197            Dim rhs = removeNull(y)
     198            If lhs.Length > indexX Or indexX < 0 Then
     199                Throw New ArgumentOutOfRangeException("indexX")
     200            ElseIf rhs.Length > indexY Or indexY < 0 Then
     201                Throw New ArgumentOutOfRangeException("indexY")
     202            ElseIf length < 0 Then
     203                Throw New ArgumentOutOfRangeException("length")
     204            End If
     205            Dim cmpLen = Math.Min(Math.Min(lhs.Length - indexX, rhs.Length - indexY), length)
     206            Return compareImpl(VarPtr(lhs.Chars[indexX]), cmpLen, VarPtr(rhs.Chars[indexY]), cmpLen, ignoreCase)
     207        End Function
     208
     209        /*!
     210        @brief 序数での文字列比較
     211        */
    188212        Static Function CompareOrdinal(x As String, y As String) As Long
    189             Return CompareOrdinal(StrPtr(x), StrPtr(y))
     213            Dim lhs = removeNull(x)
     214            Dim rhs = removeNull(y)
     215            Return compareOrdinalImpl(lhs.Chars, lhs.Length, rhs.Chars, rhs.Length)
    190216        End Function
    191217
    192218        Static Function CompareOrdinal(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
    193             Return CompareOrdinal(StrPtr(x), indexX, StrPtr(y), indexY, length)
    194         End Function
     219            Dim lhs = removeNull(x)
     220            Dim rhs = removeNull(y)
     221            If lhs.Length > indexX Or indexX < 0 Then
     222                Throw New ArgumentOutOfRangeException("indexX")
     223            ElseIf rhs.Length > indexY Or indexY < 0 Then
     224                Throw New ArgumentOutOfRangeException("indexY")
     225            ElseIf length < 0 Then
     226                Throw New ArgumentOutOfRangeException("length")
     227            End If
     228            Dim cmpLen = Math.Min(Math.Min(lhs.Length - indexX, rhs.Length - indexY), length)
     229            Return compareOrdinalImpl(VarPtr(lhs.Chars[indexX]), cmpLen, VarPtr(rhs.Chars[indexY]), cmpLen)
     230        End Function
     231
     232        Static Function CompareOrdinal(x As String, y As *Char) As Long
     233            Dim lhs = removeNull(x)
     234            Return compareOrdinalImpl(lhs.Chars, lhs.Length, y, lstrlen(y))
     235        End Function
     236       
    195237    Private
    196         Static Function Compare(x As String, y As *Char) As Long
    197             Return CompareOrdinal(x, y)
    198         End Function
    199 
    200         Static Function CompareOrdinal(x As String, y As *Char) As Long
    201             Return CompareOrdinal(StrPtr(x), y)
    202         End Function
    203 
    204         Static Function CompareOrdinal(x As *Char, y As *Char) As Long
    205             If x = 0 Then
    206                 If y = 0 Then
    207                     Return 0
    208                 Else
    209                     Return -1
    210                 End If
    211             ElseIf y = 0 Then
    212                 Return 1
    213             End If
    214             Return ActiveBasic.Strings.StrCmp(x, y)
    215         End Function
    216 
    217         Static Function CompareOrdinal(x As *Char, indexX As Long, y As *Char, indexY As Long, length As Long) As Long
    218             If x = 0 Then
    219                 If y = 0 Then
    220                     Return 0
    221                 Else
    222                     Return -1
    223                 End If
    224             ElseIf y = 0 Then
    225                 Return 1
    226             End If
    227             Return ActiveBasic.Strings.ChrCmp(VarPtr(x[indexX]), VarPtr(y[indexY]), length As SIZE_T)
    228         End Function
     238        Static Function compareImpl(x As *Char, lenX As Long, y As *Char, lenY As Long, ignoreCase As Boolean) As Long
     239            Dim flags = 0 As DWord
     240            If ignoreCase Then
     241                flags = NORM_IGNORECASE
     242            End If
     243            Dim ret = CompareString(LOCALE_USER_DEFAULT, ignoreCase, x, lenX, y, lenY)
     244            Select Case ret
     245                Case CSTR_LESS_THAN
     246                    compareImpl = -1
     247                Case CSTR_EQUAL
     248                    compareImpl = 0
     249                Case CSTR_GREATER_THAN
     250                    compareImpl = 1
     251                Case Else
     252                    ActiveBasic.Windows.ThrowWithLastError("String.Compare")
     253            End Select
     254        End Function
     255
     256        Static Function compareOrdinalImpl(x As *Char, lenX As Long, y As *Char, lenY As Long) As Long
     257            Return ActiveBasic.Strings.ChrCmp(x, lenX As SIZE_T, y, lenY As SIZE_T)
     258        End Function
     259
    229260    Public
    230261        Function CompareTo(y As String) As Long
Note: See TracChangeset for help on using the changeset viewer.