source: trunk/Include/Classes/System/String.ab@ 328

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

Equalsの一部を実装

File size: 16.6 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
[308]248 Function Equals(s As String) As Boolean
249 Return This = s
250 End Function
251
252 Override Function Equals(s As Object) As Boolean
253 If This.GetType = s.GetType Then
254 Return This.Equals(s As String)
255 End If
256 Return False
257 End Function
258
[246]259 Const Function StrPtr() As *StrChar
260 Return Chars
261 End Function
[272]262Private
[1]263
[246]264 Sub Assign(text As PCSTR, textLengthA As Long)
[175]265#ifdef __STRING_IS_NOT_UNICODE
[246]266 AssignFromStrChar(text, textLengthA)
[139]267#else
[246]268 Dim textLengthW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, textLengthA, 0, 0)
269 If AllocStringBuffer(textLengthW) <> 0 Then
270 MultiByteToWideChar(CP_THREAD_ACP, 0, text, textLengthA, Chars, textLengthW)
271 Chars[textLengthW] = 0
272 End If
[139]273#endif
[246]274 End Sub
[1]275
[246]276 Sub Assign(text As PCWSTR, textLengthW As Long)
[139]277#ifdef __STRING_IS_NOT_UNICODE
[246]278 Dim textLengthA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, 0, 0, 0, 0)
279 If AllocStringBuffer(textLengthA) <> 0 Then
280 WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, Chars, textLengthA, 0, 0)
281 Chars[textLengthA] = 0
282 End If
[139]283#else
[246]284 AssignFromStrChar(text, textLengthW)
[139]285#endif
[246]286 End Sub
[139]287
[246]288 Private
289 Static Function ConcatStrChar(text1 As *StrChar, text1Length As Long, text2 As *StrChar, text2Length As Long) As String
290 ConcatStrChar = New String()
291 With ConcatStrChar
292 .AllocStringBuffer(text1Length + text2Length)
[272]293 ActiveBasic.Strings.ChrCopy(.Chars, text1, text1Length As SIZE_T)
294 ActiveBasic.Strings.ChrCopy(VarPtr(.Chars[text1Length]), text2, text2Length As SIZE_T)
[246]295 .Chars[text1Length + text2Length] = 0
296 End With
297 End Function
298 Public
299 Const Function Concat(text As PCSTR, len As Long) As String
[139]300#ifdef __STRING_IS_NOT_UNICODE
[246]301 Return ConcatStrChar(This.Chars, m_Length, text, len)
[139]302#else
[246]303 With Concat
304 Dim lenW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, 0, 0)
[272]305 Concat = New String
[246]306 .AllocStringBuffer(m_Length + lenW)
[272]307 ActiveBasic.Strings.ChrCopy(.Chars, This.Chars, m_Length)
[246]308 MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenW)
309 .Chars[m_Length + lenW] = 0
310 End With
[139]311#endif
[246]312 End Function
[132]313
[246]314 Const Function Concat(text As PCWSTR, len As Long) As String
[139]315#ifdef __STRING_IS_NOT_UNICODE
[246]316 With Concat
[272]317 Concat = New String
[246]318 Dim lenA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, len, 0, 0, 0, 0)
319 .AllocStringBuffer(m_Length + lenA)
[272]320 ActiveBasic.Strings.ChrCopy(.Chars, This.Chars, m_Length As SIZE_T)
[246]321 WideCharToMultiByte(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenA, 0, 0)
322 .Chars[m_Length + lenA] = 0
323 End With
[139]324#else
[246]325 Return ConcatStrChar(This.Chars, m_Length, text, len)
[139]326#endif
[246]327 End Function
[203]328
[246]329 Static Function Concat(x As String, y As String) As String
330 If String.IsNullOrEmpty(x) Then
331 Return y
332 Else
333 Return x.Concat(y.Chars, y.m_Length)
334 End If
335 End Function
[203]336
[246]337 Static Function Concat(x As Object, y As Object) As String
338 Return String.Concat(x.ToString, y.ToString)
339 End Function
[203]340
[272]341 Const Function Contains(s As String) As Boolean
342 If Object.ReferenceEquals(s, Nothing) Then
343 'Throw New ArgumentNullException
344 End If
345 Return IndexOf(s, 0, m_Length) >= 0
[246]346 End Function
[1]347
[272]348 Const Function IndexOf(c As StrChar) As Long
349 Return indexOfCore(c, 0, m_Length)
[246]350 End Function
[1]351
[272]352 Const Function IndexOf(c As StrChar, start As Long) As Long
353 rangeCheck(start)
354 Return indexOfCore(c, start, m_Length - start)
[246]355 End Function
[1]356
[272]357 Const Function IndexOf(c As StrChar, start As Long, count As Long) As Long
358 rangeCheck(start, count)
359 Return indexOfCore(c, start, count)
[246]360 End Function
[272]361 Private
362 Const Function indexOfCore(c As StrChar, start As Long, count As Long) As Long
363 indexOfCore = ActiveBasic.Strings.ChrFind(VarPtr(Chars[start]), count, c)
364 If indexOfCore <> -1 Then
365 indexOfCore += start
366 End If
367 End Function
368 Public
369 Const Function IndexOf(s As String) As Long
370 Return IndexOf(s, 0, m_Length)
371 End Function
[1]372
[272]373 Const Function IndexOf(s As String, startIndex As Long) As Long
374 Return IndexOf(s, startIndex, m_Length - startIndex)
375 End Function
[1]376
[272]377 Const Function IndexOf(s As String, startIndex As Long, count As Long) As Long
378 rangeCheck(startIndex, count)
379 If Object.ReferenceEquals(s, Nothing) Then
380 'Throw New ArgumentNullException
381 Debug
382 End If
[1]383
[272]384 Dim length = s.Length
[246]385 If length = 0 Then Return startIndex
[1]386
[246]387 Dim i As Long, j As Long
388 For i = startIndex To startIndex + count - 1
389 For j = 0 To length - 1
[272]390 If Chars[i + j] = s[j] Then
[246]391 If j = length - 1 Then Return i
392 Else
393 Exit For
394 End If
395 Next
[1]396 Next
[246]397 Return -1
398 End Function
[1]399
[272]400 Const Function LastIndexOf(s As String) As Long
401 Return LastIndexOf(s, m_Length - 1, m_Length)
[246]402 End Function
[1]403
[272]404 Const Function LastIndexOf(s As String, startIndex As Long) As Long
405 Return LastIndexOf(s, startIndex, startIndex + 1)
[246]406 End Function
[1]407
[272]408 Const Function LastIndexOf(s As String, startIndex As Long, count As Long) As Long
409 If Object.ReferenceEquals(s, Nothing) Then
410 'Throw New ArgumentNullException
411 Debug
412 End If
[1]413
[272]414 If startIndex < 0 Or startIndex > m_Length - 1 Or _
415 count < 0 Or count > startIndex + 2 Then
416 'Throw New ArgumentOutOfRangeException
417 Debug
418 End If
419 Dim length = s.Length
[246]420 If length > m_Length Then Return -1
421 If length = 0 Then Return startIndex
[1]422
[246]423 Dim i As Long, j As Long
424 For i = startIndex To startIndex - count + 1 Step -1
425 For j = length - 1 To 0 Step -1
[272]426 If Chars[i + j] = s[j] Then
[246]427 If j = 0 Then Return i
428 Else
429 Exit For
430 End If
431 Next
[1]432 Next
[246]433 Return -1
434 End Function
[1]435
[272]436 Const Function StartsWith(s As String) As Boolean
437 Return IndexOf(s) = 0
[246]438 End Function
[1]439
[272]440 Const Function EndsWith(s As String) As Boolean
441 Return LastIndexOf(s) = m_Length - s.Length
[246]442 End Function
[1]443
[246]444 Const Function Insert(startIndex As Long, text As String) As String
[272]445 Dim sb = New System.Text.StringBuilder(This)
446 sb.Insert(startIndex, text)
447 Return sb.ToString
[246]448 End Function
[1]449
[272]450 Const Function Substring(startIndex As Long) As String
451 rangeCheck(startIndex)
452 Return Substring(startIndex, m_Length - startIndex)
[246]453 End Function
[1]454
[272]455 Const Function Substring(startIndex As Long, length As Long) As String
456 rangeCheck(startIndex, length)
457 Return New String(Chars, startIndex, length)
[246]458 End Function
[1]459
[246]460 Const Function Remove(startIndex As Long) As String
[272]461 rangeCheck(startIndex)
462 Remove = Substring(0, startIndex)
[246]463 End Function
[1]464
[246]465 Const Function Remove(startIndex As Long, count As Long) As String
[272]466 Dim sb = New System.Text.StringBuilder(This)
467 sb.Remove(startIndex, count)
468 Remove = sb.ToString
[246]469 End Function
[192]470
[246]471 Static Function IsNullOrEmpty(s As String) As Boolean
472 If Not Object.ReferenceEquals(s, Nothing) Then
473 If s.m_Length > 0 Then
474 Return False
475 End If
[132]476 End If
[246]477 Return True
478 End Function
[192]479
[246]480 Const Function Replace(oldChar As StrChar, newChar As StrChar) As String
[272]481 Dim sb = New System.Text.StringBuilder(This)
482 sb.Replace(oldChar, newChar)
483 Replace = sb.ToString
[246]484 End Function
[1]485
[272]486 Const Function Replace(oldStr As String, newStr As String) As String
487 Dim sb = New System.Text.StringBuilder(This)
488 sb.Replace(oldStr, newStr)
489 Return sb.ToString
[246]490 End Function
[1]491
[246]492 Const Function ToLower() As String
[272]493 Dim sb = New System.Text.StringBuilder(m_Length)
494 sb.Length = m_Length
[246]495 Dim i As Long
496 For i = 0 To ELM(m_Length)
[272]497 sb[i] = _System_ASCII_ToLower(Chars[i])
[246]498 Next
[272]499 Return sb.ToString
[246]500 End Function
[1]501
[246]502 Const Function ToUpper() As String
[272]503 Dim sb = New System.Text.StringBuilder(m_Length)
504 sb.Length = m_Length
[246]505 Dim i As Long
506 For i = 0 To ELM(m_Length)
[272]507 sb[i] = _System_ASCII_ToUpper(Chars[i])
[246]508 Next
[272]509 Return sb.ToString
[246]510 End Function
[272]511
[246]512 Override Function ToString() As String
[272]513 ToString = This
[246]514 End Function
[119]515
[272]516 Const Function Clone() As String
517 Clone = This
518 End Function
[285]519
[246]520 Static Function Copy(s As String) As String
[272]521 Copy = New String(s.Chars, s.m_Length)
[246]522 End Function
[132]523
[272]524 Sub CopyTo(sourceIndex As Long, destination As *StrChar, destinationIndex As Long, count As Long)
525 ActiveBasic.Strings.ChrCopy(VarPtr(destination[destinationIndex]), VarPtr(Chars[sourceIndex]), count As SIZE_T)
526 End Sub
527
[246]528 Override Function GetHashCode() As Long
[143]529#ifdef __STRING_IS_NOT_UNICODE
[246]530 Dim size = (m_Length + 1) >> 1
[143]531#else
[246]532 Dim size = m_Length
[143]533#endif
[285]534 Return _System_GetHashFromWordArray(Chars As *Word, size) Xor size
[246]535 End Function
[272]536
537 Function PadLeft(total As Long) As String
538 PadLeft(total, &h30 As StrChar)
539 End Function
540
541 Function PadLeft(total As Long, c As StrChar) As String
542 If total < 0 Then
543 'Throw New ArgumentException
544 End If
545 If total >= m_Length Then
546 Return This
547 End If
548 Dim sb = New System.Text.StringBuilder(total)
549 sb.Append(c, total - m_Length)
550 sb.Append(This)
551 Return sb.ToString
552 End Function
553
554 Function PadRight(total As Long) As String
[285]555 PadRight(total, &h30 As StrChar)
[272]556 End Function
557
558 Function PadRight(total As Long, c As StrChar) As String
559 If total < 0 Then
560 'Throw New ArgumentException
561 End If
562 If total >= m_Length Then
563 Return This
564 End If
565 Dim sb = New System.Text.StringBuilder(total)
566 sb.Append(This)
567 sb.Append(c, total - m_Length)
568 Return sb.ToString
569 End Function
[246]570 Private
571 Function AllocStringBuffer(textLength As Long) As *StrChar
572 If textLength < 0 Then
573 Return 0
[1]574 End If
[272]575 AllocStringBuffer = GC_malloc_atomic(SizeOf(StrChar) * (textLength + 1))
576 If AllocStringBuffer = 0 Then
577 'Throw New OutOfMemoryException
[246]578 End If
[272]579 m_Length = textLength
580 Chars = AllocStringBuffer
[246]581 End Function
[132]582
[246]583 Sub AssignFromStrChar(text As *StrChar, textLength As Long)
[272]584 AllocStringBuffer(textLength)
585 ActiveBasic.Strings.ChrCopy(Chars, text, textLength As SIZE_T)
586 Chars[m_Length] = 0
587 End Sub
588
589 Const Sub rangeCheck(index As Long)
590 If index < 0 Or index > m_Length Then
591 Debug 'ArgumentOutOfRangeException
[246]592 End If
593 End Sub
[272]594
595 Const Sub rangeCheck(start As Long, length As Long)
596 If start < 0 Or start > This.m_Length Or length < 0 Then
597 Debug 'ArgumentOutOfRangeException
598 End If
599 End Sub
[246]600 End Class
601
602End Namespace
Note: See TracBrowser for help on using the repository browser.