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