Ignore:
Timestamp:
May 12, 2007, 6:31:13 PM (17 years ago)
Author:
dai
Message:

Objectクラス、Stringクラスの定義をSystem名前空間に入れると共に、コンパイラ側で両者のクラスをSystem名前空間に依存しない特殊型として扱うようにした。
System.Diagnostics名前空間を導入した。
Namespaceステートメントのコード補間機能に対応。

File:
1 edited

Legend:

Unmodified
Added
Removed
  • Include/Classes/System/String.ab

    r237 r246  
    1515#endif
    1616
    17 Class String
    18 '   Inherits IComparable, ICloneable, IConvertible, IEnumerable
    19 
    20     m_Length As Long
    21 Public
    22     Chars As *StrChar
    23 
    24     Sub String()
    25         Chars = _System_malloc(SizeOf (StrChar))
    26         Chars[0] = 0
    27         m_Length = 0
    28     End Sub
    29 
    30     Sub String(initStr As PCSTR)
    31         Assign(initStr)
    32     End Sub
    33 
    34     Sub String(initStr As PCSTR, length As Long)
    35         Assign(initStr, length)
    36     End Sub
    37 
    38     Sub String(initStr As PCWSTR)
    39         Assign(initStr)
    40     End Sub
    41 
    42     Sub String(initStr As PCWSTR, length As Long)
    43         Assign(initStr, length)
    44     End Sub
    45 
    46     Sub String(ByRef initStr As String)
    47         Assign(initStr)
    48     End Sub
    49 
    50     Sub String(length As Long)
    51         ReSize(length)
    52     End Sub
    53 
    54     Sub String(initChar As StrChar, length As Long)
    55         ReSize(length, initChar)
    56     End Sub
    57 
    58     Sub ~String()
    59         _System_free(Chars)
    60         Chars = 0
     17Namespace System
     18
     19    Class String
     20    '   Inherits IComparable, ICloneable, IConvertible, IEnumerable
     21
     22        m_Length As Long
     23    Public
     24        Chars As *StrChar
     25
     26        Sub String()
     27            Chars = _System_malloc(SizeOf (StrChar))
     28            Chars[0] = 0
     29            m_Length = 0
     30        End Sub
     31
     32        Sub String(initStr As PCSTR)
     33            Assign(initStr)
     34        End Sub
     35
     36        Sub String(initStr As PCSTR, length As Long)
     37            Assign(initStr, length)
     38        End Sub
     39
     40        Sub String(initStr As PCWSTR)
     41            Assign(initStr)
     42        End Sub
     43
     44        Sub String(initStr As PCWSTR, length As Long)
     45            Assign(initStr, length)
     46        End Sub
     47
     48        Sub String(ByRef initStr As String)
     49            Assign(initStr)
     50        End Sub
     51
     52        Sub String(length As Long)
     53            ReSize(length)
     54        End Sub
     55
     56        Sub String(initChar As StrChar, length As Long)
     57            ReSize(length, initChar)
     58        End Sub
     59
     60        Sub ~String()
     61            _System_free(Chars)
     62            Chars = 0
    6163#ifdef _DEBUG
    62         m_Length = 0
    63 #endif
    64     End Sub
    65 
    66     Const Function Length() As Long
    67         Return m_Length
    68     End Function
    69 
    70     Function Operator() As *StrChar
    71         Return Chars
    72     End Function
    73 
    74     Const Function Operator [] (n As Long) As StrChar
     64            m_Length = 0
     65#endif
     66        End Sub
     67
     68        Const Function Length() As Long
     69            Return m_Length
     70        End Function
     71
     72        Function Operator() As *StrChar
     73            Return Chars
     74        End Function
     75
     76        Const Function Operator [] (n As Long) As StrChar
    7577#ifdef _DEBUG
    76         If n > Length Then
    77             'Throw ArgumentOutOfRangeException
    78             Debug
    79         End If
    80 #endif
    81         Return Chars[n]
    82     End Function
    83 
    84     Sub Operator []= (n As Long, c As StrChar)
     78            If n > Length Then
     79                'Throw ArgumentOutOfRangeException
     80                Debug
     81            End If
     82#endif
     83            Return Chars[n]
     84        End Function
     85
     86        Sub Operator []= (n As Long, c As StrChar)
    8587#ifdef _DEBUG
    86         If n >= Length Then
    87             'Throw ArgumentOutOfRangeException
    88             Debug
    89         End If
    90 #endif
    91         Chars[n] = c
    92     End Sub
    93 
    94 /*  Const Function Operator + (text As *Byte) As String
    95         Return Concat(text As PCTSTR, lstrlen(text))
    96     End Function*/
    97 
    98     Const Function Operator + (text As PCSTR) As String
    99         Return Concat(text, lstrlenA(text))
    100     End Function
    101 
    102     Const Function Operator + (text As PCWSTR) As String
    103         Return Concat(text, lstrlenW(text))
    104     End Function
    105 
    106     Const Function Operator + (objString As String) As String
    107         Return Concat(objString.Chars, objString.m_Length)
    108     End Function
    109 
    110     Const Function Operator & (text As PCSTR) As String
    111         Dim tempString = This + text
    112         Return tempString
    113     End Function
    114 
    115     Const Function Operator & (text As PCWSTR) As String
    116         Dim tempString = This + text
    117         Return tempString
    118     End Function
    119 
    120     Const Function Operator & (objString As String) As String
    121         Dim tempString = This + objString
    122         Return tempString
    123     End Function
    124 
    125     Const Function Operator == (objString As String) As Boolean
    126         Return String.Compare(This, objString) = 0
    127     End Function
    128 
    129     Const Function Operator == (text As *StrChar) As Boolean
    130         Return _System_StrCmp(This.Chars, text) = 0
    131     End Function
    132 
    133     Const Function Operator <> (objString As String) As Boolean
    134         Return String.Compare(This, objString) <> 0
    135     End Function
    136 
    137     Const Function Operator <> (text As *StrChar) As Boolean
    138         Return _System_StrCmp(This.Chars, text) <> 0
    139     End Function
    140 
    141     Const Function Operator < (objString As String) As Boolean
    142         Return String.Compare(This, objString) < 0
    143     End Function
    144 
    145     Const Function Operator < (text As *StrChar) As Boolean
    146         Return _System_StrCmp(This.Chars, text) < 0
    147     End Function
    148 
    149     Const Function Operator > (objString As String) As Boolean
    150         Return String.Compare(This, objString) > 0
    151     End Function
    152 
    153     Const Function Operator > (text As *StrChar) As Boolean
    154         Return _System_StrCmp(This.Chars, text) > 0
    155     End Function
    156 
    157     Const Function Operator <= (objString As String) As Boolean
    158         Return String.Compare(This, objString) <= 0
    159     End Function
    160 
    161     Const Function Operator <= (text As *StrChar) As Boolean
    162         Return _System_StrCmp(This.Chars, text) <= 0
    163     End Function
    164 
    165     Const Function Operator >= (objString As String) As Boolean
    166         Return String.Compare(This, objString) >= 0
    167     End Function
    168 
    169     Const Function Operator >= (text As *StrChar) As Boolean
    170         Return _System_StrCmp(This.Chars, text) >= 0
    171     End Function
    172 
    173     Static Function Compare(x As String, y As String) As Long
    174         Return CompareOrdinal(x, y)
    175     End Function
    176 
    177     Static Function Compare(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
    178         Return CompareOrdinal(x, indexX, y, indexY, length)
    179     End Function
    180 
    181     Static Function CompareOrdinal(x As String, y As String) As Long
    182         Return _System_StrCmp(x.Chars, y.Chars)
    183     End Function
    184 
    185     Static Function CompareOrdinal(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
    186         If Object.ReferenceEquals(x, Nothing) Then
    187             If Object.ReferenceEquals(y, Nothing) Then
     88            If n >= Length Then
     89                'Throw ArgumentOutOfRangeException
     90                Debug
     91            End If
     92#endif
     93            Chars[n] = c
     94        End Sub
     95
     96    /*  Const Function Operator + (text As *Byte) As String
     97            Return Concat(text As PCTSTR, lstrlen(text))
     98        End Function*/
     99
     100        Const Function Operator + (text As PCSTR) As String
     101            Return Concat(text, lstrlenA(text))
     102        End Function
     103
     104        Const Function Operator + (text As PCWSTR) As String
     105            Return Concat(text, lstrlenW(text))
     106        End Function
     107
     108        Const Function Operator + (objString As String) As String
     109            Return Concat(objString.Chars, objString.m_Length)
     110        End Function
     111
     112        Const Function Operator & (text As PCSTR) As String
     113            Dim tempString = This + text
     114            Return tempString
     115        End Function
     116
     117        Const Function Operator & (text As PCWSTR) As String
     118            Dim tempString = This + text
     119            Return tempString
     120        End Function
     121
     122        Const Function Operator & (objString As String) As String
     123            Dim tempString = This + objString
     124            Return tempString
     125        End Function
     126
     127        Const Function Operator == (objString As String) As Boolean
     128            Return String.Compare(This, objString) = 0
     129        End Function
     130
     131        Const Function Operator == (text As *StrChar) As Boolean
     132            Return _System_StrCmp(This.Chars, text) = 0
     133        End Function
     134
     135        Const Function Operator <> (objString As String) As Boolean
     136            Return String.Compare(This, objString) <> 0
     137        End Function
     138
     139        Const Function Operator <> (text As *StrChar) As Boolean
     140            Return _System_StrCmp(This.Chars, text) <> 0
     141        End Function
     142
     143        Const Function Operator < (objString As String) As Boolean
     144            Return String.Compare(This, objString) < 0
     145        End Function
     146
     147        Const Function Operator < (text As *StrChar) As Boolean
     148            Return _System_StrCmp(This.Chars, text) < 0
     149        End Function
     150
     151        Const Function Operator > (objString As String) As Boolean
     152            Return String.Compare(This, objString) > 0
     153        End Function
     154
     155        Const Function Operator > (text As *StrChar) As Boolean
     156            Return _System_StrCmp(This.Chars, text) > 0
     157        End Function
     158
     159        Const Function Operator <= (objString As String) As Boolean
     160            Return String.Compare(This, objString) <= 0
     161        End Function
     162
     163        Const Function Operator <= (text As *StrChar) As Boolean
     164            Return _System_StrCmp(This.Chars, text) <= 0
     165        End Function
     166
     167        Const Function Operator >= (objString As String) As Boolean
     168            Return String.Compare(This, objString) >= 0
     169        End Function
     170
     171        Const Function Operator >= (text As *StrChar) As Boolean
     172            Return _System_StrCmp(This.Chars, text) >= 0
     173        End Function
     174
     175        Static Function Compare(x As String, y As String) As Long
     176            Return CompareOrdinal(x, y)
     177        End Function
     178
     179        Static Function Compare(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
     180            Return CompareOrdinal(x, indexX, y, indexY, length)
     181        End Function
     182
     183        Static Function CompareOrdinal(x As String, y As String) As Long
     184            Return _System_StrCmp(x.Chars, y.Chars)
     185        End Function
     186
     187        Static Function CompareOrdinal(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
     188            If Object.ReferenceEquals(x, Nothing) Then
     189                If Object.ReferenceEquals(y, Nothing) Then
     190                    Return 0
     191                Else
     192                    Return -1
     193                End If
     194            ElseIf Object.ReferenceEquals(y, Nothing) Then
     195                Return 1
     196            End If
     197            Return _System_StrCmpN(VarPtr(x.Chars[indexX]), VarPtr(y.Chars[indexY]), length As SIZE_T)
     198        End Function
     199
     200        Function CompareTo(y As String) As Long
     201            Return String.Compare(This, y)
     202        End Function
     203
     204        Function CompareTo(y As Object) As Long
     205            Dim s = y As String
     206    '       If y is not String Then
     207    '           Throw New ArgumentException
     208    '       End If
     209            Return CompareTo(y)
     210        End Function
     211
     212        Const Function StrPtr() As *StrChar
     213            Return Chars
     214        End Function
     215
     216        Sub ReSize(allocLength As Long)
     217            If allocLength < 0 Then Exit Sub
     218            If allocLength > m_Length Then
     219                Dim oldLength As Long
     220                oldLength = m_Length
     221                If AllocStringBuffer(allocLength) <> 0 Then
     222                    ZeroMemory(VarPtr(Chars[oldLength]), SizeOf (StrChar) * (m_Length - oldLength + 1))
     223                End If
     224            Else
     225                m_Length = allocLength
     226                Chars[m_Length] = 0
     227            End If
     228        End Sub
     229
     230        Sub ReSize(allocLength As Long, c As StrChar)
     231            If allocLength < 0 Then
     232                Exit Sub
     233            ElseIf allocLength > m_Length Then
     234                Dim oldLength As Long
     235                oldLength = m_Length
     236                If AllocStringBuffer(allocLength) <> 0 Then
     237                    Dim p = VarPtr(Chars[oldLength]) As *StrChar
     238                    Dim fillLen = m_Length - oldLength
     239                    Dim i As Long
     240                    For i = 0 To ELM(fillLen)
     241                        p[i] = c
     242                    Next
     243                End If
     244            Else
     245                m_Length = allocLength
     246            End If
     247            Chars[m_Length] = 0
     248        End Sub
     249
     250        Sub Assign(text As PCSTR, textLengthA As Long)
     251#ifdef __STRING_IS_NOT_UNICODE
     252            AssignFromStrChar(text, textLengthA)
     253#else
     254            Dim textLengthW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, textLengthA, 0, 0)
     255            If AllocStringBuffer(textLengthW) <> 0 Then
     256                MultiByteToWideChar(CP_THREAD_ACP, 0, text, textLengthA, Chars, textLengthW)
     257                Chars[textLengthW] = 0
     258            End If
     259#endif
     260        End Sub
     261
     262        Sub Assign(text As PCWSTR, textLengthW As Long)
     263#ifdef __STRING_IS_NOT_UNICODE
     264            Dim textLengthA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, 0, 0, 0, 0)
     265            If AllocStringBuffer(textLengthA) <> 0 Then
     266                WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, Chars, textLengthA, 0, 0)
     267                Chars[textLengthA] = 0
     268            End If
     269#else
     270            AssignFromStrChar(text, textLengthW)
     271#endif
     272        End Sub
     273
     274        Sub Assign(ByRef objString As String)
     275            Assign(objString.Chars, objString.m_Length)
     276        End Sub
     277
     278        Sub Assign(text As PCSTR)
     279            If text Then
     280                Assign(text, lstrlenA(text))
     281            Else
     282                If Chars <> 0 Then
     283                    Chars[0] = 0
     284                End If
     285                m_Length = 0
     286            End If
     287        End Sub
     288
     289        Sub Assign(text As PCWSTR)
     290            If text Then
     291                Assign(text, lstrlenW(text))
     292            Else
     293                If Chars <> 0 Then
     294                    Chars[0] = 0
     295                End If
     296                m_Length = 0
     297            End If
     298        End Sub
     299
     300        Sub Append(text As *StrChar, textLength As Long)
     301            Dim prevLen As Long
     302            prevLen = m_Length
     303            If AllocStringBuffer(m_Length + textLength) <> 0 Then
     304                memcpy(VarPtr(Chars[prevLen]), text, SizeOf (StrChar) * textLength)
     305                Chars[m_Length] = 0
     306            End If
     307        End Sub
     308
     309        Sub Append(text As *StrChar)
     310            Append(text, lstrlen(text))
     311        End Sub
     312
     313        Sub Append(ByRef str As String)
     314            Append(str.Chars, str.m_Length)
     315        End Sub
     316
     317        Const Function Clone() As String
     318            Return This
     319        End Function
     320    Private
     321        Static Function ConcatStrChar(text1 As *StrChar, text1Length As Long, text2 As *StrChar, text2Length As Long) As String
     322            ConcatStrChar = New String()
     323            With ConcatStrChar
     324                .AllocStringBuffer(text1Length + text2Length)
     325                memcpy(.Chars, text1, SizeOf (StrChar) * text1Length)
     326                memcpy(VarPtr(.Chars[text1Length]), text2, SizeOf (StrChar) * text2Length)
     327                .Chars[text1Length + text2Length] = 0
     328            End With
     329        End Function
     330    Public
     331        Const Function Concat(text As PCSTR, len As Long) As String
     332#ifdef __STRING_IS_NOT_UNICODE
     333            Return ConcatStrChar(This.Chars, m_Length, text, len)
     334#else
     335            With Concat
     336                Dim lenW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, 0, 0)
     337                .AllocStringBuffer(m_Length + lenW)
     338                memcpy(.Chars, This.Chars, m_Length)
     339                MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenW)
     340                .Chars[m_Length + lenW] = 0
     341            End With
     342#endif
     343        End Function
     344
     345        Const Function Concat(text As PCWSTR, len As Long) As String
     346#ifdef __STRING_IS_NOT_UNICODE
     347            With Concat
     348                Dim lenA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, len, 0, 0, 0, 0)
     349                .AllocStringBuffer(m_Length + lenA)
     350                memcpy(.Chars, This.Chars, m_Length)
     351                WideCharToMultiByte(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenA, 0, 0)
     352                .Chars[m_Length + lenA] = 0
     353            End With
     354#else
     355            Return ConcatStrChar(This.Chars, m_Length, text, len)
     356#endif
     357        End Function
     358
     359        Static Function Concat(x As String, y As String) As String
     360            If String.IsNullOrEmpty(x) Then
     361                Return y
     362            Else
     363                Return x.Concat(y.Chars, y.m_Length)
     364            End If
     365        End Function
     366
     367        Static Function Concat(x As Object, y As Object) As String
     368            Return String.Concat(x.ToString, y.ToString)
     369        End Function
     370
     371        Const Function Contains(objString As String) As Boolean
     372            Return IndexOf(objString, 0, m_Length) >= 0
     373        End Function
     374
     375        Const Function Contains(lpszText As *StrChar) As Boolean
     376            Return IndexOf(lpszText, 0, m_Length) >= 0
     377        End Function
     378
     379        Const Function IndexOf(lpszText As *StrChar) As Long
     380            Return IndexOf(lpszText, 0, m_Length)
     381        End Function
     382
     383        Const Function IndexOf(lpszText As *StrChar, startIndex As Long) As Long
     384            Return IndexOf(lpszText, startIndex, m_Length - startIndex)
     385        End Function
     386
     387        Const Function IndexOf(lpszText As *StrChar, startIndex As Long, count As Long) As Long
     388            Dim length = lstrlen(lpszText)
     389
     390            If startIndex < 0 Then Return -1
     391            If count < 1 Or count + startIndex > m_Length Then Return -1
     392            If length > m_Length Then Return -1
     393
     394            If length = 0 Then Return startIndex
     395
     396            Dim i As Long, j As Long
     397            For i = startIndex To startIndex + count - 1
     398                For j = 0 To length - 1
     399                    If Chars[i + j] = lpszText[j] Then
     400                        If j = length - 1 Then Return i
     401                    Else
     402                        Exit For
     403                    End If
     404                Next
     405            Next
     406            Return -1
     407        End Function
     408
     409        Const Function LastIndexOf(lpszText As *StrChar) As Long
     410            Return LastIndexOf(lpszText, m_Length - 1, m_Length)
     411        End Function
     412
     413        Const Function LastIndexOf(lpszText As *StrChar, startIndex As Long) As Long
     414            Return LastIndexOf(lpszText As *StrChar, startIndex, startIndex + 1)
     415        End Function
     416
     417        Const Function LastIndexOf(lpszText As *StrChar, startIndex As Long, count As Long) As Long
     418            Dim length = lstrlen(lpszText)
     419
     420            If startIndex < 0 Or startIndex > m_Length - 1 Then Return -1
     421            If count < 1 Or count > startIndex + 2 Then Return -1
     422            If length > m_Length Then Return -1
     423
     424            If length = 0 Then Return startIndex
     425
     426            Dim i As Long, j As Long
     427            For i = startIndex To  startIndex - count + 1 Step -1
     428                For j = length - 1 To 0 Step -1
     429                    If Chars[i + j] = lpszText[j] Then
     430                        If j = 0 Then Return i
     431                    Else
     432                        Exit For
     433                    End If
     434                Next
     435            Next
     436            Return -1
     437        End Function
     438
     439        Const Function StartsWith(lpszText As *StrChar) As Boolean
     440            Return IndexOf(lpszText) = 0
     441        End Function
     442
     443        Const Function EndsWith(lpszText As *StrChar) As Boolean
     444            Return LastIndexOf(lpszText) = m_Length - lstrlen(lpszText)
     445        End Function
     446
     447        Const Function Insert(startIndex As Long, text As String) As String
     448            Return Insert(startIndex, text.Chars, text.Length)
     449        End Function
     450
     451        Const Function Insert(startIndex As Long, text As *StrChar) As String
     452            Return Insert(startIndex, text, lstrlen(text))
     453        End Function
     454
     455        Const Function Insert(startIndex As Long, text As *StrChar, length As Long) As String
     456            If startIndex < 0 Or startIndex > m_Length Or length < 0 Then
     457                Debug 'ArgumentOutOfRangeException
     458
     459            End If
     460            Insert.ReSize(m_Length + length)
     461            memcpy(Insert.Chars, Chars, SizeOf (StrChar) * startIndex)
     462            memcpy(VarPtr(Insert.Chars[startIndex]), text, SizeOf (StrChar) * length)
     463            memcpy(VarPtr(Insert.Chars[startIndex + length]), VarPtr(Chars[startIndex]), SizeOf (StrChar) * (m_Length - startIndex + 1))
     464        End Function
     465
     466        Const Function SubString(startIndex As Long) As String
     467            Return SubString(startIndex, m_Length - startIndex)
     468        End Function
     469
     470        Const Function SubString(startIndex As Long, length As Long) As String
     471            If startIndex < 0 Or length <= 0 Then Return ""
     472            If startIndex + length > m_Length Then Return ""
     473
     474            Dim temp As String
     475            temp.AllocStringBuffer(length)
     476            memcpy(temp.Chars, VarPtr(Chars[startIndex]), SizeOf (StrChar) * length)
     477            temp.Chars[m_Length] = 0
     478            Return temp
     479        End Function
     480
     481        Const Function Remove(startIndex As Long) As String
     482            If startIndex < 0 Or startIndex > m_Length Then
     483                Debug 'ArgumentOutOfRangeException
     484            End If
     485
     486            Remove.ReSize(startIndex)
     487            memcpy(Remove.Chars, This.Chars, SizeOf (StrChar) * startIndex)
     488        End Function
     489
     490        Const Function Remove(startIndex As Long, count As Long) As String
     491            If startIndex < 0 Or count < 0 Or startIndex + count > m_Length Then
     492                Debug 'ArgumentOutOfRangeException
     493            End If
     494
     495            Remove.ReSize(m_Length - count)
     496            memcpy(Remove.Chars, This.Chars, SizeOf (StrChar) * startIndex)
     497            memcpy(VarPtr(Remove.Chars[startIndex]), VarPtr(This.Chars[startIndex + count]), SizeOf (StrChar) * (m_Length - startIndex - count))
     498        End Function
     499
     500        Static Function IsNullOrEmpty(s As String) As Boolean
     501            If Not Object.ReferenceEquals(s, Nothing) Then
     502                If s.m_Length > 0 Then
     503                    Return False
     504                End If
     505            End If
     506            Return True
     507        End Function
     508
     509        Const Function Replace(oldChar As StrChar, newChar As StrChar) As String
     510            Replace = Copy(This)
     511            With Replace
     512                Dim i As Long
     513                For i = 0 To ELM(.m_Length)
     514                    If .Chars[i] = oldChar Then
     515                        .Chars[i] = newChar
     516                    End If
     517                Next
     518            End With
     519        End Function
     520
     521        Const Function Replace(ByRef oldStr As String, ByRef newStr As String) As String
     522    '       If oldStr = Nothing Then Throw ArgumentNullException
     523    '
     524    '       If newStr = Nothing Then
     525    '           Return ReplaceCore(oldStr, oldStr.m_Length, "", 0)
     526    '       Else
     527                Return ReplaceCore(oldStr, oldStr.m_Length, newStr, newStr.m_Length)
     528    '       End If
     529        End Function
     530
     531        Const Function Replace(oldStr As *StrChar, newStr As *StrChar) As String
     532            If oldStr = 0 Then Debug 'Throw ArgumentNullException
     533            If newStr = 0 Then newStr = ""
     534            Return ReplaceCore(oldStr, lstrlen(oldStr), newStr, lstrlen(newStr))
     535        End Function
     536
     537        Const Function Replace(oldStr As *StrChar, oldLen As Long, newStr As *StrChar, newLen As Long) As String
     538            If oldStr = 0 Then Debug 'Throw ArgumentNullException
     539            If newStr = 0 Then
     540                newStr = ""
     541                newLen = 0
     542            End If
     543            Return ReplaceCore(oldStr, oldLen, newStr, newLen)
     544        End Function
     545
     546        Const Function ToLower() As String
     547            ToLower.ReSize(m_Length)
     548            Dim i As Long
     549            For i = 0 To ELM(m_Length)
     550                ToLower.Chars[i] = _System_ASCII_ToLower(Chars[i])
     551            Next
     552        End Function
     553
     554        Const Function ToUpper() As String
     555            ToUpper.ReSize(m_Length)
     556            Dim i As Long
     557            For i = 0 To ELM(m_Length)
     558                ToUpper.Chars[i] = _System_ASCII_ToUpper(Chars[i])
     559            Next
     560        End Function
     561    /*
     562        Sub Swap(ByRef x As String)
     563            Dim tempLen As Long
     564            Dim tempChars As *StrChar
     565            tempLen = x.m_Length
     566            tempChars = x.Chars
     567            x.m_Length = This.m_Length
     568            x.Chars = This.Chars
     569            This.m_Length = tempLen
     570            This.Chars = tempChars
     571        End Sub
     572    */
     573        Override Function ToString() As String
     574            Return This
     575        End Function
     576
     577        Static Function Copy(s As String) As String
     578            Copy.ReSize(s.m_Length)
     579            memcpy(Copy.Chars, This.Chars, SizeOf (StrChar) * m_Length)
     580        End Function
     581
     582        Override Function GetHashCode() As Long
     583#ifdef __STRING_IS_NOT_UNICODE
     584            Dim size = (m_Length + 1) >> 1
     585#else
     586            Dim size = m_Length
     587#endif
     588            Return _System_GetHashFromWordArray(Chars As *Word, size)
     589        End Function
     590    Private
     591        ' メモリ確保に失敗すると元の文字列は失われない。(例外安全でいう強い保障)
     592        Function AllocStringBuffer(textLength As Long) As *StrChar
     593            If textLength < 0 Then
    188594                Return 0
     595            ElseIf textLength > m_Length or Chars = 0 Then
     596                AllocStringBuffer = _System_realloc(Chars, SizeOf(StrChar) * (textLength + 1))
     597                If AllocStringBuffer <> 0 Then
     598                    m_Length = textLength
     599                    Chars = AllocStringBuffer
     600                End If
    189601            Else
    190                 Return -1
    191             End If
    192         ElseIf Object.ReferenceEquals(y, Nothing) Then
    193             Return 1
    194         End If
    195         Return _System_StrCmpN(VarPtr(x.Chars[indexX]), VarPtr(y.Chars[indexY]), length As SIZE_T)
    196     End Function
    197 
    198     Function CompareTo(y As String) As Long
    199         Return String.Compare(This, y)
    200     End Function
    201 
    202     Function CompareTo(y As Object) As Long
    203         Dim s = y As String
    204 '       If y is not String Then
    205 '           Throw New ArgumentException
    206 '       End If
    207         Return CompareTo(y)
    208     End Function
    209 
    210     Const Function StrPtr() As *StrChar
    211         Return Chars
    212     End Function
    213 
    214     Sub ReSize(allocLength As Long)
    215         If allocLength < 0 Then Exit Sub
    216         If allocLength > m_Length Then
    217             Dim oldLength As Long
    218             oldLength = m_Length
    219             If AllocStringBuffer(allocLength) <> 0 Then
    220                 ZeroMemory(VarPtr(Chars[oldLength]), SizeOf (StrChar) * (m_Length - oldLength + 1))
    221             End If
    222         Else
    223             m_Length = allocLength
    224             Chars[m_Length] = 0
    225         End If
    226     End Sub
    227 
    228     Sub ReSize(allocLength As Long, c As StrChar)
    229         If allocLength < 0 Then
    230             Exit Sub
    231         ElseIf allocLength > m_Length Then
    232             Dim oldLength As Long
    233             oldLength = m_Length
    234             If AllocStringBuffer(allocLength) <> 0 Then
    235                 Dim p = VarPtr(Chars[oldLength]) As *StrChar
    236                 Dim fillLen = m_Length - oldLength
    237                 Dim i As Long
    238                 For i = 0 To ELM(fillLen)
    239                     p[i] = c
    240                 Next
    241             End If
    242         Else
    243             m_Length = allocLength
    244         End If
    245         Chars[m_Length] = 0
    246     End Sub
    247 
    248     Sub Assign(text As PCSTR, textLengthA As Long)
    249 #ifdef __STRING_IS_NOT_UNICODE
    250         AssignFromStrChar(text, textLengthA)
    251 #else
    252         Dim textLengthW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, textLengthA, 0, 0)
    253         If AllocStringBuffer(textLengthW) <> 0 Then
    254             MultiByteToWideChar(CP_THREAD_ACP, 0, text, textLengthA, Chars, textLengthW)
    255             Chars[textLengthW] = 0
    256         End If
    257 #endif
    258     End Sub
    259 
    260     Sub Assign(text As PCWSTR, textLengthW As Long)
    261 #ifdef __STRING_IS_NOT_UNICODE
    262         Dim textLengthA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, 0, 0, 0, 0)
    263         If AllocStringBuffer(textLengthA) <> 0 Then
    264             WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, Chars, textLengthA, 0, 0)
    265             Chars[textLengthA] = 0
    266         End If
    267 #else
    268         AssignFromStrChar(text, textLengthW)
    269 #endif
    270     End Sub
    271 
    272     Sub Assign(ByRef objString As String)
    273         Assign(objString.Chars, objString.m_Length)
    274     End Sub
    275 
    276     Sub Assign(text As PCSTR)
    277         If text Then
    278             Assign(text, lstrlenA(text))
    279         Else
    280             If Chars <> 0 Then
    281                 Chars[0] = 0
    282             End If
    283             m_Length = 0
    284         End If
    285     End Sub
    286 
    287     Sub Assign(text As PCWSTR)
    288         If text Then
    289             Assign(text, lstrlenW(text))
    290         Else
    291             If Chars <> 0 Then
    292                 Chars[0] = 0
    293             End If
    294             m_Length = 0
    295         End If
    296     End Sub
    297 
    298     Sub Append(text As *StrChar, textLength As Long)
    299         Dim prevLen As Long
    300         prevLen = m_Length
    301         If AllocStringBuffer(m_Length + textLength) <> 0 Then
    302             memcpy(VarPtr(Chars[prevLen]), text, SizeOf (StrChar) * textLength)
    303             Chars[m_Length] = 0
    304         End If
    305     End Sub
    306 
    307     Sub Append(text As *StrChar)
    308         Append(text, lstrlen(text))
    309     End Sub
    310 
    311     Sub Append(ByRef str As String)
    312         Append(str.Chars, str.m_Length)
    313     End Sub
    314 
    315     Const Function Clone() As String
    316         Return This
    317     End Function
    318 Private
    319     Static Function ConcatStrChar(text1 As *StrChar, text1Length As Long, text2 As *StrChar, text2Length As Long) As String
    320         ConcatStrChar = New String()
    321         With ConcatStrChar
    322             .AllocStringBuffer(text1Length + text2Length)
    323             memcpy(.Chars, text1, SizeOf (StrChar) * text1Length)
    324             memcpy(VarPtr(.Chars[text1Length]), text2, SizeOf (StrChar) * text2Length)
    325             .Chars[text1Length + text2Length] = 0
    326         End With
    327     End Function
    328 Public
    329     Const Function Concat(text As PCSTR, len As Long) As String
    330 #ifdef __STRING_IS_NOT_UNICODE
    331         Return ConcatStrChar(This.Chars, m_Length, text, len)
    332 #else
    333         With Concat
    334             Dim lenW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, 0, 0)
    335             .AllocStringBuffer(m_Length + lenW)
    336             memcpy(.Chars, This.Chars, m_Length)
    337             MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenW)
    338             .Chars[m_Length + lenW] = 0
    339         End With
    340 #endif
    341     End Function
    342 
    343     Const Function Concat(text As PCWSTR, len As Long) As String
    344 #ifdef __STRING_IS_NOT_UNICODE
    345         With Concat
    346             Dim lenA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, len, 0, 0, 0, 0)
    347             .AllocStringBuffer(m_Length + lenA)
    348             memcpy(.Chars, This.Chars, m_Length)
    349             WideCharToMultiByte(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenA, 0, 0)
    350             .Chars[m_Length + lenA] = 0
    351         End With
    352 #else
    353         Return ConcatStrChar(This.Chars, m_Length, text, len)
    354 #endif
    355     End Function
    356 
    357     Static Function Concat(x As String, y As String) As String
    358         If String.IsNullOrEmpty(x) Then
    359             Return y
    360         Else
    361             Return x.Concat(y.Chars, y.m_Length)
    362         End If
    363     End Function
    364 
    365     Static Function Concat(x As Object, y As Object) As String
    366         Return String.Concat(x.ToString, y.ToString)
    367     End Function
    368 
    369     Const Function Contains(objString As String) As Boolean
    370         Return IndexOf(objString, 0, m_Length) >= 0
    371     End Function
    372 
    373     Const Function Contains(lpszText As *StrChar) As Boolean
    374         Return IndexOf(lpszText, 0, m_Length) >= 0
    375     End Function
    376 
    377     Const Function IndexOf(lpszText As *StrChar) As Long
    378         Return IndexOf(lpszText, 0, m_Length)
    379     End Function
    380 
    381     Const Function IndexOf(lpszText As *StrChar, startIndex As Long) As Long
    382         Return IndexOf(lpszText, startIndex, m_Length - startIndex)
    383     End Function
    384 
    385     Const Function IndexOf(lpszText As *StrChar, startIndex As Long, count As Long) As Long
    386         Dim length = lstrlen(lpszText)
    387 
    388         If startIndex < 0 Then Return -1
    389         If count < 1 Or count + startIndex > m_Length Then Return -1
    390         If length > m_Length Then Return -1
    391 
    392         If length = 0 Then Return startIndex
    393 
    394         Dim i As Long, j As Long
    395         For i = startIndex To startIndex + count - 1
    396             For j = 0 To length - 1
    397                 If Chars[i + j] = lpszText[j] Then
    398                     If j = length - 1 Then Return i
    399                 Else
    400                     Exit For
    401                 End If
    402             Next
    403         Next
    404         Return -1
    405     End Function
    406 
    407     Const Function LastIndexOf(lpszText As *StrChar) As Long
    408         Return LastIndexOf(lpszText, m_Length - 1, m_Length)
    409     End Function
    410 
    411     Const Function LastIndexOf(lpszText As *StrChar, startIndex As Long) As Long
    412         Return LastIndexOf(lpszText As *StrChar, startIndex, startIndex + 1)
    413     End Function
    414 
    415     Const Function LastIndexOf(lpszText As *StrChar, startIndex As Long, count As Long) As Long
    416         Dim length = lstrlen(lpszText)
    417 
    418         If startIndex < 0 Or startIndex > m_Length - 1 Then Return -1
    419         If count < 1 Or count > startIndex + 2 Then Return -1
    420         If length > m_Length Then Return -1
    421 
    422         If length = 0 Then Return startIndex
    423 
    424         Dim i As Long, j As Long
    425         For i = startIndex To  startIndex - count + 1 Step -1
    426             For j = length - 1 To 0 Step -1
    427                 If Chars[i + j] = lpszText[j] Then
    428                     If j = 0 Then Return i
    429                 Else
    430                     Exit For
    431                 End If
    432             Next
    433         Next
    434         Return -1
    435     End Function
    436 
    437     Const Function StartsWith(lpszText As *StrChar) As Boolean
    438         Return IndexOf(lpszText) = 0
    439     End Function
    440 
    441     Const Function EndsWith(lpszText As *StrChar) As Boolean
    442         Return LastIndexOf(lpszText) = m_Length - lstrlen(lpszText)
    443     End Function
    444 
    445     Const Function Insert(startIndex As Long, text As String) As String
    446         Return Insert(startIndex, text.Chars, text.Length)
    447     End Function
    448 
    449     Const Function Insert(startIndex As Long, text As *StrChar) As String
    450         Return Insert(startIndex, text, lstrlen(text))
    451     End Function
    452 
    453     Const Function Insert(startIndex As Long, text As *StrChar, length As Long) As String
    454         If startIndex < 0 Or startIndex > m_Length Or length < 0 Then
    455             Debug 'ArgumentOutOfRangeException
    456 
    457         End If
    458         Insert.ReSize(m_Length + length)
    459         memcpy(Insert.Chars, Chars, SizeOf (StrChar) * startIndex)
    460         memcpy(VarPtr(Insert.Chars[startIndex]), text, SizeOf (StrChar) * length)
    461         memcpy(VarPtr(Insert.Chars[startIndex + length]), VarPtr(Chars[startIndex]), SizeOf (StrChar) * (m_Length - startIndex + 1))
    462     End Function
    463 
    464     Const Function SubString(startIndex As Long) As String
    465         Return SubString(startIndex, m_Length - startIndex)
    466     End Function
    467 
    468     Const Function SubString(startIndex As Long, length As Long) As String
    469         If startIndex < 0 Or length <= 0 Then Return ""
    470         If startIndex + length > m_Length Then Return ""
    471 
    472         Dim temp As String
    473         temp.AllocStringBuffer(length)
    474         memcpy(temp.Chars, VarPtr(Chars[startIndex]), SizeOf (StrChar) * length)
    475         temp.Chars[m_Length] = 0
    476         Return temp
    477     End Function
    478 
    479     Const Function Remove(startIndex As Long) As String
    480         If startIndex < 0 Or startIndex > m_Length Then
    481             Debug 'ArgumentOutOfRangeException
    482         End If
    483 
    484         Remove.ReSize(startIndex)
    485         memcpy(Remove.Chars, This.Chars, SizeOf (StrChar) * startIndex)
    486     End Function
    487 
    488     Const Function Remove(startIndex As Long, count As Long) As String
    489         If startIndex < 0 Or count < 0 Or startIndex + count > m_Length Then
    490             Debug 'ArgumentOutOfRangeException
    491         End If
    492 
    493         Remove.ReSize(m_Length - count)
    494         memcpy(Remove.Chars, This.Chars, SizeOf (StrChar) * startIndex)
    495         memcpy(VarPtr(Remove.Chars[startIndex]), VarPtr(This.Chars[startIndex + count]), SizeOf (StrChar) * (m_Length - startIndex - count))
    496     End Function
    497 
    498     Static Function IsNullOrEmpty(s As String) As Boolean
    499         If Not Object.ReferenceEquals(s, Nothing) Then
    500             If s.m_Length > 0 Then
    501                 Return False
    502             End If
    503         End If
    504         Return True
    505     End Function
    506 
    507     Const Function Replace(oldChar As StrChar, newChar As StrChar) As String
    508         Replace = Copy(This)
    509         With Replace
    510             Dim i As Long
    511             For i = 0 To ELM(.m_Length)
    512                 If .Chars[i] = oldChar Then
    513                     .Chars[i] = newChar
    514                 End If
    515             Next
    516         End With
    517     End Function
    518 
    519     Const Function Replace(ByRef oldStr As String, ByRef newStr As String) As String
    520 '       If oldStr = Nothing Then Throw ArgumentNullException
    521 '
    522 '       If newStr = Nothing Then
    523 '           Return ReplaceCore(oldStr, oldStr.m_Length, "", 0)
    524 '       Else
    525             Return ReplaceCore(oldStr, oldStr.m_Length, newStr, newStr.m_Length)
    526 '       End If
    527     End Function
    528 
    529     Const Function Replace(oldStr As *StrChar, newStr As *StrChar) As String
    530         If oldStr = 0 Then Debug 'Throw ArgumentNullException
    531         If newStr = 0 Then newStr = ""
    532         Return ReplaceCore(oldStr, lstrlen(oldStr), newStr, lstrlen(newStr))
    533     End Function
    534 
    535     Const Function Replace(oldStr As *StrChar, oldLen As Long, newStr As *StrChar, newLen As Long) As String
    536         If oldStr = 0 Then Debug 'Throw ArgumentNullException
    537         If newStr = 0 Then
    538             newStr = ""
    539             newLen = 0
    540         End If
    541         Return ReplaceCore(oldStr, oldLen, newStr, newLen)
    542     End Function
    543 
    544     Const Function ToLower() As String
    545         ToLower.ReSize(m_Length)
    546         Dim i As Long
    547         For i = 0 To ELM(m_Length)
    548             ToLower.Chars[i] = _System_ASCII_ToLower(Chars[i])
    549         Next
    550     End Function
    551 
    552     Const Function ToUpper() As String
    553         ToUpper.ReSize(m_Length)
    554         Dim i As Long
    555         For i = 0 To ELM(m_Length)
    556             ToUpper.Chars[i] = _System_ASCII_ToUpper(Chars[i])
    557         Next
    558     End Function
    559 /*
    560     Sub Swap(ByRef x As String)
    561         Dim tempLen As Long
    562         Dim tempChars As *StrChar
    563         tempLen = x.m_Length
    564         tempChars = x.Chars
    565         x.m_Length = This.m_Length
    566         x.Chars = This.Chars
    567         This.m_Length = tempLen
    568         This.Chars = tempChars
    569     End Sub
    570 */
    571     Override Function ToString() As String
    572         Return This
    573     End Function
    574 
    575     Static Function Copy(s As String) As String
    576         Copy.ReSize(s.m_Length)
    577         memcpy(Copy.Chars, This.Chars, SizeOf (StrChar) * m_Length)
    578     End Function
    579 
    580     Override Function GetHashCode() As Long
    581 #ifdef __STRING_IS_NOT_UNICODE
    582         Dim size = (m_Length + 1) >> 1
    583 #else
    584         Dim size = m_Length
    585 #endif
    586         Return _System_GetHashFromWordArray(Chars As *Word, size)
    587     End Function
    588 Private
    589     ' メモリ確保に失敗すると元の文字列は失われない。(例外安全でいう強い保障)
    590     Function AllocStringBuffer(textLength As Long) As *StrChar
    591         If textLength < 0 Then
    592             Return 0
    593         ElseIf textLength > m_Length or Chars = 0 Then
    594             AllocStringBuffer = _System_realloc(Chars, SizeOf(StrChar) * (textLength + 1))
    595             If AllocStringBuffer <> 0 Then
    596602                m_Length = textLength
    597                 Chars = AllocStringBuffer
    598             End If
    599         Else
    600             m_Length = textLength
    601             AllocStringBuffer = Chars
    602         End If
    603     End Function
    604 
    605     Function ReplaceCore(oldStr As *StrChar, oldLen As Long, newStr As *StrChar, newLen As Long) As String
    606         If oldLen = 0 Then
    607             Debug 'Throw ArgumentException
    608         End If
    609         Dim tmp As String
    610         With tmp
    611             Dim current = 0 As Long
    612             Do
    613                 Dim pos = IndexOf(oldStr, current)
    614                 If pos = -1 Then
    615                     Exit Do
    616                 End If
    617                 .Append(VarPtr(Chars[current]), pos - current)
    618                 .Append(newStr, newLen)
    619                 current = pos + oldLen
    620             Loop
    621             .Append(VarPtr(Chars[current]), m_Length - current)
    622         End With
    623         Return tmp
    624     End Function
    625 
    626     Sub AssignFromStrChar(text As *StrChar, textLength As Long)
    627         If text = Chars Then Exit Sub
    628         If AllocStringBuffer(textLength) <> 0 Then
    629             memcpy(Chars, text, SizeOf (StrChar) * textLength)
    630             Chars[m_Length] = 0
    631         End If
    632     End Sub
    633 End Class
     603                AllocStringBuffer = Chars
     604            End If
     605        End Function
     606
     607        Function ReplaceCore(oldStr As *StrChar, oldLen As Long, newStr As *StrChar, newLen As Long) As String
     608            If oldLen = 0 Then
     609                Debug 'Throw ArgumentException
     610            End If
     611            Dim tmp As String
     612            With tmp
     613                Dim current = 0 As Long
     614                Do
     615                    Dim pos = IndexOf(oldStr, current)
     616                    If pos = -1 Then
     617                        Exit Do
     618                    End If
     619                    .Append(VarPtr(Chars[current]), pos - current)
     620                    .Append(newStr, newLen)
     621                    current = pos + oldLen
     622                Loop
     623                .Append(VarPtr(Chars[current]), m_Length - current)
     624            End With
     625            Return tmp
     626        End Function
     627
     628        Sub AssignFromStrChar(text As *StrChar, textLength As Long)
     629            If text = Chars Then Exit Sub
     630            If AllocStringBuffer(textLength) <> 0 Then
     631                memcpy(Chars, text, SizeOf (StrChar) * textLength)
     632                Chars[m_Length] = 0
     633            End If
     634        End Sub
     635    End Class
     636
     637End Namespace
Note: See TracChangeset for help on using the changeset viewer.