source: Include/Classes/System/String.ab@ 285

Last change on this file since 285 was 285, checked in by イグトランス (egtra), 17 years ago

wtypes.abを追加

File size: 16.3 KB
RevLine 
[132]1' Classes/System/String.ab
2
3#require <basic/function.sbp>
[272]4#require <Classes/System/Text/StringBuilder.ab>
5#require <Classes/ActiveBasic/Strings/Strings.ab>
[132]6
[139]7#ifdef __STRING_IS_NOT_ALWAYS_UNICODE
8TypeDef StrChar = Char
9#ifndef UNICODE
10#define __STRING_IS_NOT_UNICODE
11#endif
12#else
13TypeDef StrChar = WCHAR
[142]14#ifndef UNICODE
15#define __STRING_UNICODE_WINDOWS_ANSI
[139]16#endif
[142]17#endif
[139]18
[246]19Namespace System
[203]20
[246]21 Class String
22 ' Inherits IComparable, ICloneable, IConvertible, IEnumerable
[1]23
[246]24 m_Length As Long
25 Chars As *StrChar
[1]26
[272]27 Sub validPointerCheck(p As VoidPtr, size = 1 As Long)
28 If p As ULONG_PTR < &h10000 Then
29 'Throw ArgumentException
30 Debug
31 ElseIf IsBadReadPtr(p, size As ULONG_PTR) Then
32 'Throw ArgumentException
33 Debug
34 End If
35 End Sub
36 Public
37 Static Const Empty = New String
38
[246]39 Sub String()
[272]40' Chars = 0
41' m_Length = 0
[246]42 End Sub
[30]43
[272]44 Sub String(initStr As PCWSTR)
45 validPointerCheck(initStr)
46 Assign(initStr, lstrlenW(initStr))
[246]47 End Sub
[125]48
[272]49 Sub String(initStr As PCWSTR, length As Long)
50 validPointerCheck(initStr, length)
[246]51 Assign(initStr, length)
52 End Sub
[139]53
[272]54 Sub String(initStr As PCWSTR, start As Long, length As Long)
55 If start < 0 Or length Or start + length < 0 Then
56 'Throw New ArgumentOutOfRangeException
57 End If
58 validPointerCheck(initStr + start, length)
59 Assign(initStr + start, length)
[246]60 End Sub
[139]61
[272]62 Sub String(initStr As PCSTR)
63 validPointerCheck(initStr)
64 Assign(initStr, lstrlenA(initStr))
[246]65 End Sub
[49]66
[272]67 Sub String(initStr As PCSTR, length As Long)
68 validPointerCheck(initStr, length)
69 Assign(initStr, length)
[246]70 End Sub
[121]71
[272]72 Sub String(initStr As PCSTR, start As Long, length As Long)
73 If start < 0 Or length Or start + length < 0 Then
74 'Throw New ArgumentOutOfRangeException
75 End If
76 validPointerCheck(initStr + start, length)
77 Assign(initStr + start, length)
[246]78 End Sub
[272]79
80 Sub String(initStr As String)
81 If Not String.IsNullOrEmpty(initStr) Then
82 Assign(initStr.Chars, initStr.m_Length)
83 End If
84 End Sub
[1]85
[246]86 Sub String(initChar As StrChar, length As Long)
[272]87 AllocStringBuffer(length)
88 ActiveBasic.Strings.ChrFill(Chars, length, initChar)
89 Chars[length] = 0
[246]90 End Sub
91
[272]92 Sub String(sb As System.Text.StringBuilder)
93 Chars = StrPtr(sb)
94 m_Length = sb.Length
95 sb.__Stringized()
[246]96 End Sub
[1]97
[246]98 Const Function Length() As Long
99 Return m_Length
100 End Function
[30]101
[246]102 Function Operator() As *StrChar
103 Return Chars
104 End Function
[1]105
[246]106 Const Function Operator [] (n As Long) As StrChar
[272]107 rangeCheck(n)
[246]108 Return Chars[n]
109 End Function
[1]110
[272]111 Const Function Operator + (y As PCSTR) As String
112 Return Concat(y, lstrlenA(y))
[246]113 End Function
[139]114
[272]115 Const Function Operator + (y As PCWSTR) As String
116 Return Concat(y, lstrlenW(y))
[246]117 End Function
[139]118
[272]119 Const Function Operator + (y As String) As String
120 Return Concat(y.Chars, y.m_Length)
[246]121 End Function
[1]122
[272]123 Const Function Operator & (y As PCSTR) As String
124 Return This + y
[246]125 End Function
[1]126
[272]127 Const Function Operator & (y As PCWSTR) As String
128 Dim tempString = This + y
[246]129 Return tempString
130 End Function
[139]131
[272]132 Const Function Operator & (y As String) As String
133 Dim tempString = This + y
[246]134 Return tempString
135 End Function
[1]136
[272]137 Const Function Operator == (y As String) As Boolean
138 Return String.Compare(This, y) = 0
[246]139 End Function
[1]140
[272]141 Const Function Operator == (y As *StrChar) As Boolean
142 Return String.Compare(This, y) = 0
[246]143 End Function
[1]144
[272]145 Const Function Operator <> (y As String) As Boolean
146 Return String.Compare(This, y) <> 0
[246]147 End Function
[1]148
[272]149 Const Function Operator <> (y As *StrChar) As Boolean
150 Return String.Compare(This, y) <> 0
[246]151 End Function
[1]152
[272]153 Const Function Operator < (y As String) As Boolean
154 Return String.Compare(This, y) < 0
[246]155 End Function
[1]156
[272]157 Const Function Operator < (y As *StrChar) As Boolean
158 Return String.Compare(This, y) < 0
[246]159 End Function
[1]160
[272]161 Const Function Operator > (y As String) As Boolean
162 Return String.Compare(This, y) > 0
[246]163 End Function
[1]164
[272]165 Const Function Operator > (y As *StrChar) As Boolean
166 Return String.Compare(This, y) > 0
[246]167 End Function
[1]168
[272]169 Const Function Operator <= (y As String) As Boolean
170 Return String.Compare(This, y) <= 0
[246]171 End Function
[1]172
[272]173 Const Function Operator <= (y As *StrChar) As Boolean
174 Return String.Compare(This, y) <= 0
[246]175 End Function
[1]176
[272]177 Const Function Operator >= (y As String) As Boolean
178 Return String.Compare(This, y) >= 0
[246]179 End Function
[1]180
[272]181 Const Function Operator >= (y As *StrChar) As Boolean
182 Return String.Compare(This, y) >= 0
[246]183 End Function
[1]184
[246]185 Static Function Compare(x As String, y As String) As Long
186 Return CompareOrdinal(x, y)
187 End Function
[203]188
[272]189 Public
[246]190 Static Function Compare(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
[272]191 Return String.CompareOrdinal(x, indexX, y, indexY, length)
[246]192 End Function
[203]193
[246]194 Static Function CompareOrdinal(x As String, y As String) As Long
[272]195 Return String.CompareOrdinal(x.Chars, y.Chars)
[246]196 End Function
[203]197
[246]198 Static Function CompareOrdinal(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
[272]199 Return String.CompareOrdinal(x.Chars, indexX, y.Chars, indexY, length)
200 End Function
201 Private
202 Static Function Compare(x As String, y As *StrChar) As Long
203 Return String.CompareOrdinal(x, y)
204 End Function
205
206 Static Function CompareOrdinal(x As String, y As *StrChar) As Long
207 Return String.CompareOrdinal(x.Chars, y)
208 End Function
209
210 Static Function CompareOrdinal(x As *StrChar, y As *StrChar) As Long
211 If x = 0 Then
212 If y = 0 Then
[246]213 Return 0
214 Else
215 Return -1
216 End If
[272]217 ElseIf y = 0 Then
[246]218 Return 1
[203]219 End If
[272]220 Return ActiveBasic.Strings.StrCmp(x, y)
[246]221 End Function
[203]222
[272]223 Static Function CompareOrdinal(x As *StrChar, indexX As Long, y As *StrChar, indexY As Long, length As Long) As Long
224 If x = 0 Then
225 If y = 0 Then
226 Return 0
227 Else
228 Return -1
229 End If
230 ElseIf y = 0 Then
231 Return 1
232 End If
233 Return ActiveBasic.Strings.ChrCmp(VarPtr(x[indexX]), VarPtr(y[indexY]), length As SIZE_T)
234 End Function
235 Public
[246]236 Function CompareTo(y As String) As Long
237 Return String.Compare(This, y)
238 End Function
[203]239
[246]240 Function CompareTo(y As Object) As Long
241 Dim s = y As String
242 ' If y is not String Then
243 ' Throw New ArgumentException
244 ' End If
[272]245 Return CompareTo(y As String)
[246]246 End Function
[203]247
[246]248 Const Function StrPtr() As *StrChar
249 Return Chars
250 End Function
[272]251Private
[1]252
[246]253 Sub Assign(text As PCSTR, textLengthA As Long)
[175]254#ifdef __STRING_IS_NOT_UNICODE
[246]255 AssignFromStrChar(text, textLengthA)
[139]256#else
[246]257 Dim textLengthW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, textLengthA, 0, 0)
258 If AllocStringBuffer(textLengthW) <> 0 Then
259 MultiByteToWideChar(CP_THREAD_ACP, 0, text, textLengthA, Chars, textLengthW)
260 Chars[textLengthW] = 0
261 End If
[139]262#endif
[246]263 End Sub
[1]264
[246]265 Sub Assign(text As PCWSTR, textLengthW As Long)
[139]266#ifdef __STRING_IS_NOT_UNICODE
[246]267 Dim textLengthA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, 0, 0, 0, 0)
268 If AllocStringBuffer(textLengthA) <> 0 Then
269 WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, Chars, textLengthA, 0, 0)
270 Chars[textLengthA] = 0
271 End If
[139]272#else
[246]273 AssignFromStrChar(text, textLengthW)
[139]274#endif
[246]275 End Sub
[139]276
[246]277 Private
278 Static Function ConcatStrChar(text1 As *StrChar, text1Length As Long, text2 As *StrChar, text2Length As Long) As String
279 ConcatStrChar = New String()
280 With ConcatStrChar
281 .AllocStringBuffer(text1Length + text2Length)
[272]282 ActiveBasic.Strings.ChrCopy(.Chars, text1, text1Length As SIZE_T)
283 ActiveBasic.Strings.ChrCopy(VarPtr(.Chars[text1Length]), text2, text2Length As SIZE_T)
[246]284 .Chars[text1Length + text2Length] = 0
285 End With
286 End Function
287 Public
288 Const Function Concat(text As PCSTR, len As Long) As String
[139]289#ifdef __STRING_IS_NOT_UNICODE
[246]290 Return ConcatStrChar(This.Chars, m_Length, text, len)
[139]291#else
[246]292 With Concat
293 Dim lenW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, 0, 0)
[272]294 Concat = New String
[246]295 .AllocStringBuffer(m_Length + lenW)
[272]296 ActiveBasic.Strings.ChrCopy(.Chars, This.Chars, m_Length)
[246]297 MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenW)
298 .Chars[m_Length + lenW] = 0
299 End With
[139]300#endif
[246]301 End Function
[132]302
[246]303 Const Function Concat(text As PCWSTR, len As Long) As String
[139]304#ifdef __STRING_IS_NOT_UNICODE
[246]305 With Concat
[272]306 Concat = New String
[246]307 Dim lenA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, len, 0, 0, 0, 0)
308 .AllocStringBuffer(m_Length + lenA)
[272]309 ActiveBasic.Strings.ChrCopy(.Chars, This.Chars, m_Length As SIZE_T)
[246]310 WideCharToMultiByte(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenA, 0, 0)
311 .Chars[m_Length + lenA] = 0
312 End With
[139]313#else
[246]314 Return ConcatStrChar(This.Chars, m_Length, text, len)
[139]315#endif
[246]316 End Function
[203]317
[246]318 Static Function Concat(x As String, y As String) As String
319 If String.IsNullOrEmpty(x) Then
320 Return y
321 Else
322 Return x.Concat(y.Chars, y.m_Length)
323 End If
324 End Function
[203]325
[246]326 Static Function Concat(x As Object, y As Object) As String
327 Return String.Concat(x.ToString, y.ToString)
328 End Function
[203]329
[272]330 Const Function Contains(s As String) As Boolean
331 If Object.ReferenceEquals(s, Nothing) Then
332 'Throw New ArgumentNullException
333 End If
334 Return IndexOf(s, 0, m_Length) >= 0
[246]335 End Function
[1]336
[272]337 Const Function IndexOf(c As StrChar) As Long
338 Return indexOfCore(c, 0, m_Length)
[246]339 End Function
[1]340
[272]341 Const Function IndexOf(c As StrChar, start As Long) As Long
342 rangeCheck(start)
343 Return indexOfCore(c, start, m_Length - start)
[246]344 End Function
[1]345
[272]346 Const Function IndexOf(c As StrChar, start As Long, count As Long) As Long
347 rangeCheck(start, count)
348 Return indexOfCore(c, start, count)
[246]349 End Function
[272]350 Private
351 Const Function indexOfCore(c As StrChar, start As Long, count As Long) As Long
352 indexOfCore = ActiveBasic.Strings.ChrFind(VarPtr(Chars[start]), count, c)
353 If indexOfCore <> -1 Then
354 indexOfCore += start
355 End If
356 End Function
357 Public
358 Const Function IndexOf(s As String) As Long
359 Return IndexOf(s, 0, m_Length)
360 End Function
[1]361
[272]362 Const Function IndexOf(s As String, startIndex As Long) As Long
363 Return IndexOf(s, startIndex, m_Length - startIndex)
364 End Function
[1]365
[272]366 Const Function IndexOf(s As String, startIndex As Long, count As Long) As Long
367 rangeCheck(startIndex, count)
368 If Object.ReferenceEquals(s, Nothing) Then
369 'Throw New ArgumentNullException
370 Debug
371 End If
[1]372
[272]373 Dim length = s.Length
[246]374 If length = 0 Then Return startIndex
[1]375
[246]376 Dim i As Long, j As Long
377 For i = startIndex To startIndex + count - 1
378 For j = 0 To length - 1
[272]379 If Chars[i + j] = s[j] Then
[246]380 If j = length - 1 Then Return i
381 Else
382 Exit For
383 End If
384 Next
[1]385 Next
[246]386 Return -1
387 End Function
[1]388
[272]389 Const Function LastIndexOf(s As String) As Long
390 Return LastIndexOf(s, m_Length - 1, m_Length)
[246]391 End Function
[1]392
[272]393 Const Function LastIndexOf(s As String, startIndex As Long) As Long
394 Return LastIndexOf(s, startIndex, startIndex + 1)
[246]395 End Function
[1]396
[272]397 Const Function LastIndexOf(s As String, startIndex As Long, count As Long) As Long
398 If Object.ReferenceEquals(s, Nothing) Then
399 'Throw New ArgumentNullException
400 Debug
401 End If
[1]402
[272]403 If startIndex < 0 Or startIndex > m_Length - 1 Or _
404 count < 0 Or count > startIndex + 2 Then
405 'Throw New ArgumentOutOfRangeException
406 Debug
407 End If
408 Dim length = s.Length
[246]409 If length > m_Length Then Return -1
410 If length = 0 Then Return startIndex
[1]411
[246]412 Dim i As Long, j As Long
413 For i = startIndex To startIndex - count + 1 Step -1
414 For j = length - 1 To 0 Step -1
[272]415 If Chars[i + j] = s[j] Then
[246]416 If j = 0 Then Return i
417 Else
418 Exit For
419 End If
420 Next
[1]421 Next
[246]422 Return -1
423 End Function
[1]424
[272]425 Const Function StartsWith(s As String) As Boolean
426 Return IndexOf(s) = 0
[246]427 End Function
[1]428
[272]429 Const Function EndsWith(s As String) As Boolean
430 Return LastIndexOf(s) = m_Length - s.Length
[246]431 End Function
[1]432
[246]433 Const Function Insert(startIndex As Long, text As String) As String
[272]434 Dim sb = New System.Text.StringBuilder(This)
435 sb.Insert(startIndex, text)
436 Return sb.ToString
[246]437 End Function
[1]438
[272]439 Const Function Substring(startIndex As Long) As String
440 rangeCheck(startIndex)
441 Return Substring(startIndex, m_Length - startIndex)
[246]442 End Function
[1]443
[272]444 Const Function Substring(startIndex As Long, length As Long) As String
445 rangeCheck(startIndex, length)
446 Return New String(Chars, startIndex, length)
[246]447 End Function
[1]448
[246]449 Const Function Remove(startIndex As Long) As String
[272]450 rangeCheck(startIndex)
451 Remove = Substring(0, startIndex)
[246]452 End Function
[1]453
[246]454 Const Function Remove(startIndex As Long, count As Long) As String
[272]455 Dim sb = New System.Text.StringBuilder(This)
456 sb.Remove(startIndex, count)
457 Remove = sb.ToString
[246]458 End Function
[192]459
[246]460 Static Function IsNullOrEmpty(s As String) As Boolean
461 If Not Object.ReferenceEquals(s, Nothing) Then
462 If s.m_Length > 0 Then
463 Return False
464 End If
[132]465 End If
[246]466 Return True
467 End Function
[192]468
[246]469 Const Function Replace(oldChar As StrChar, newChar As StrChar) As String
[272]470 Dim sb = New System.Text.StringBuilder(This)
471 sb.Replace(oldChar, newChar)
472 Replace = sb.ToString
[246]473 End Function
[1]474
[272]475 Const Function Replace(oldStr As String, newStr As String) As String
476 Dim sb = New System.Text.StringBuilder(This)
477 sb.Replace(oldStr, newStr)
478 Return sb.ToString
[246]479 End Function
[1]480
[246]481 Const Function ToLower() As String
[272]482 Dim sb = New System.Text.StringBuilder(m_Length)
483 sb.Length = m_Length
[246]484 Dim i As Long
485 For i = 0 To ELM(m_Length)
[272]486 sb[i] = _System_ASCII_ToLower(Chars[i])
[246]487 Next
[272]488 Return sb.ToString
[246]489 End Function
[1]490
[246]491 Const Function ToUpper() As String
[272]492 Dim sb = New System.Text.StringBuilder(m_Length)
493 sb.Length = m_Length
[246]494 Dim i As Long
495 For i = 0 To ELM(m_Length)
[272]496 sb[i] = _System_ASCII_ToUpper(Chars[i])
[246]497 Next
[272]498 Return sb.ToString
[246]499 End Function
[272]500
[246]501 Override Function ToString() As String
[272]502 ToString = This
[246]503 End Function
[119]504
[272]505 Const Function Clone() As String
506 Clone = This
507 End Function
[285]508
[246]509 Static Function Copy(s As String) As String
[272]510 Copy = New String(s.Chars, s.m_Length)
[246]511 End Function
[132]512
[272]513 Sub CopyTo(sourceIndex As Long, destination As *StrChar, destinationIndex As Long, count As Long)
514 ActiveBasic.Strings.ChrCopy(VarPtr(destination[destinationIndex]), VarPtr(Chars[sourceIndex]), count As SIZE_T)
515 End Sub
516
[246]517 Override Function GetHashCode() As Long
[143]518#ifdef __STRING_IS_NOT_UNICODE
[246]519 Dim size = (m_Length + 1) >> 1
[143]520#else
[246]521 Dim size = m_Length
[143]522#endif
[285]523 Return _System_GetHashFromWordArray(Chars As *Word, size) Xor size
[246]524 End Function
[272]525
526 Function PadLeft(total As Long) As String
527 PadLeft(total, &h30 As StrChar)
528 End Function
529
530 Function PadLeft(total As Long, c As StrChar) As String
531 If total < 0 Then
532 'Throw New ArgumentException
533 End If
534 If total >= m_Length Then
535 Return This
536 End If
537 Dim sb = New System.Text.StringBuilder(total)
538 sb.Append(c, total - m_Length)
539 sb.Append(This)
540 Return sb.ToString
541 End Function
542
543 Function PadRight(total As Long) As String
[285]544 PadRight(total, &h30 As StrChar)
[272]545 End Function
546
547 Function PadRight(total As Long, c As StrChar) As String
548 If total < 0 Then
549 'Throw New ArgumentException
550 End If
551 If total >= m_Length Then
552 Return This
553 End If
554 Dim sb = New System.Text.StringBuilder(total)
555 sb.Append(This)
556 sb.Append(c, total - m_Length)
557 Return sb.ToString
558 End Function
[246]559 Private
560 Function AllocStringBuffer(textLength As Long) As *StrChar
561 If textLength < 0 Then
562 Return 0
[1]563 End If
[272]564 AllocStringBuffer = GC_malloc_atomic(SizeOf(StrChar) * (textLength + 1))
565 If AllocStringBuffer = 0 Then
566 'Throw New OutOfMemoryException
[246]567 End If
[272]568 m_Length = textLength
569 Chars = AllocStringBuffer
[246]570 End Function
[132]571
[246]572 Sub AssignFromStrChar(text As *StrChar, textLength As Long)
[272]573 AllocStringBuffer(textLength)
574 ActiveBasic.Strings.ChrCopy(Chars, text, textLength As SIZE_T)
575 Chars[m_Length] = 0
576 End Sub
577
578 Const Sub rangeCheck(index As Long)
579 If index < 0 Or index > m_Length Then
580 Debug 'ArgumentOutOfRangeException
[246]581 End If
582 End Sub
[272]583
584 Const Sub rangeCheck(start As Long, length As Long)
585 If start < 0 Or start > This.m_Length Or length < 0 Then
586 Debug 'ArgumentOutOfRangeException
587 End If
588 End Sub
[246]589 End Class
590
591End Namespace
Note: See TracBrowser for help on using the repository browser.