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

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

SPrintf関数の実装

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