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

Last change on this file since 428 was 428, checked in by OverTaker, 16 years ago

いくつかのメソッドにオーバーロード追加

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