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

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

(SPrintF.ab) FormatIntegerExにStringBuilderを引数に取る版を追加。

File size: 19.8 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 Implements /*IComparable, ICloneable, IConvertible, IComparable<String>, IEnumerable, IEnumerable<StrChar>, IEquatable<String>*/
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 New ArgumentException
37 ElseIf IsBadReadPtr(p, size As ULONG_PTR) Then
38 Throw New ArgumentException
39 End If
40 End Sub
41 Public
42 Static Const Empty = New String
43
44 Sub String()
45' Chars = 0
46' m_Length = 0
47 End Sub
48
49 Sub String(initStr As PCWSTR)
50 validPointerCheck(initStr)
51 Assign(initStr, lstrlenW(initStr))
52 End Sub
53
54 Sub String(initStr As PCWSTR, length As Long)
55 validPointerCheck(initStr, length)
56 Assign(initStr, length)
57 End Sub
58
59 Sub String(initStr As PCWSTR, start As Long, length As Long)
60 If start < 0 Or length Or start + length < 0 Then
61 Throw New ArgumentOutOfRangeException("String constractor: One or more arguments are out of range value.", "start or length or both")
62 End If
63 validPointerCheck(initStr + start, length)
64 Assign(initStr + start, length)
65 End Sub
66
67 Sub String(initStr As PCSTR)
68 validPointerCheck(initStr)
69 Assign(initStr, lstrlenA(initStr))
70 End Sub
71
72 Sub String(initStr As PCSTR, length As Long)
73 validPointerCheck(initStr, length)
74 Assign(initStr, length)
75 End Sub
76
77 Sub String(initStr As PCSTR, start As Long, length As Long)
78 If start < 0 Or length < 0 Then
79 Throw New ArgumentOutOfRangeException("String constructor: One or more arguments are out of range value.", "start or length or both")
80 End If
81 validPointerCheck(initStr + start, length)
82 Assign(initStr + start, length)
83 End Sub
84
85 Sub String(initStr As String)
86 If Not String.IsNullOrEmpty(initStr) Then
87 Assign(initStr.Chars, initStr.m_Length)
88 End If
89 End Sub
90
91 Sub String(initChar As StrChar, length As Long)
92 AllocStringBuffer(length)
93 ActiveBasic.Strings.ChrFill(Chars, length, initChar)
94 Chars[length] = 0
95 End Sub
96
97 Sub String(sb As Text.StringBuilder)
98 Chars = StrPtr(sb)
99 m_Length = sb.Length
100 sb.__Stringized()
101 End Sub
102
103 Const Function Length() As Long
104 Return m_Length
105 End Function
106
107 Function Operator() As *StrChar
108 Return Chars
109 End Function
110
111 Const Function Operator [] (n As Long) As StrChar
112 rangeCheck(n)
113 Return Chars[n]
114 End Function
115
116 Const Function Operator + (y As PCSTR) As String
117 If y = 0 Then
118 Return This
119 Else
120 Return Concat(y, lstrlenA(y))
121 End If
122 End Function
123
124 Const Function Operator + (y As PCWSTR) As String
125 If y = 0 Then
126 Return This
127 Else
128 Return Concat(y, lstrlenW(y))
129 End If
130 End Function
131
132 Const Function Operator + (y As String) As String
133 If ActiveBasic.IsNothing(y) Then
134 Return This
135 Else
136 Return Concat(y.Chars, y.m_Length)
137 End If
138 End Function
139
140 Const Function Operator & (y As PCSTR) As String
141 Return This + y
142 End Function
143
144 Const Function Operator & (y As PCWSTR) As String
145 Return This + y
146 End Function
147
148 Const Function Operator & (y As String) As String
149 Return This + y
150 End Function
151
152 Const Function Operator == (y As String) As Boolean
153 Return Compare(This, y) = 0
154 End Function
155
156 Const Function Operator == (y As *StrChar) As Boolean
157 Return Compare(This, y) = 0
158 End Function
159
160 Const Function Operator <> (y As String) As Boolean
161 Return Compare(This, y) <> 0
162 End Function
163
164 Const Function Operator <> (y As *StrChar) As Boolean
165 Return Compare(This, y) <> 0
166 End Function
167
168 Const Function Operator < (y As String) As Boolean
169 Return Compare(This, y) < 0
170 End Function
171
172 Const Function Operator < (y As *StrChar) As Boolean
173 Return Compare(This, y) < 0
174 End Function
175
176 Const Function Operator > (y As String) As Boolean
177 Return Compare(This, y) > 0
178 End Function
179
180 Const Function Operator > (y As *StrChar) As Boolean
181 Return Compare(This, y) > 0
182 End Function
183
184 Const Function Operator <= (y As String) As Boolean
185 Return Compare(This, y) <= 0
186 End Function
187
188 Const Function Operator <= (y As *StrChar) As Boolean
189 Return Compare(This, y) <= 0
190 End Function
191
192 Const Function Operator >= (y As String) As Boolean
193 Return Compare(This, y) >= 0
194 End Function
195
196 Const Function Operator >= (y As *StrChar) As Boolean
197 Return Compare(This, y) >= 0
198 End Function
199
200 Static Function Compare(x As String, y As String) As Long
201 Return CompareOrdinal(x, y)
202 End Function
203
204 Public
205 'Compareなどで、x.Charsではなく、StrPtr(x)と書く理由は、xがNothingの場合のため。
206
207 Static Function Compare(x As String, indexX As Long, y As String, indexY As Long, length As Long) As Long
208 Return CompareOrdinal(x, indexX, y, indexY, length)
209 End Function
210
211 Static Function CompareOrdinal(x As String, y As String) As Long
212 Return CompareOrdinal(StrPtr(x), StrPtr(y))
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 CompareOrdinal(StrPtr(x), indexX, StrPtr(y), indexY, length)
217 End Function
218 Private
219 Static Function Compare(x As String, y As *StrChar) As Long
220 Return CompareOrdinal(x, y)
221 End Function
222
223 Static Function CompareOrdinal(x As String, y As *StrChar) As Long
224 Return CompareOrdinal(StrPtr(x), 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: The type of the argument y is not String.", "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 String, y As String, z As String) As String
354 Dim sb = New Text.StringBuilder(removeNull(x).Length + removeNull(y).Length + removeNull(z).Length)
355 sb.Append(x).Append(y).Append(z)
356 Concat = sb.ToString
357 End Function
358
359 Static Function Concat(x As String, y As String, z As String, w As String) As String
360 Dim sb = New Text.StringBuilder(removeNull(x).Length + removeNull(y).Length + removeNull(z).Length + removeNull(w).Length)
361 sb.Append(x).Append(y).Append(z).Append(w)
362 Concat = sb.ToString
363 End Function
364
365 Static Function Concat(x As Object, y As Object) As String
366 Return Concat(x.ToString, y.ToString)
367 End Function
368
369 Static Function Concat(x As Object, y As Object, z As Object) As String
370 Return Concat(x.ToString, y.ToString, z.ToString)
371 End Function
372
373 Static Function Concat(x As Object, y As Object, z As Object, w As Object) As String
374 Return Concat(x.ToString, y.ToString, z.ToString, w.ToString)
375 End Function
376
377 Const Function Contains(c As StrChar) As Boolean
378 Return IndexOf(c) >= 0
379 End Function
380
381 Const Function Contains(s As String) As Boolean
382 If Object.ReferenceEquals(s, Nothing) Then
383 Throw New ArgumentNullException("String.Contains: An argument is null value.", "s")
384 ElseIf s = "" Then
385 Return True
386 Else
387 Return IndexOf(s, 0, m_Length) >= 0
388 End If
389 End Function
390
391 Const Function IndexOf(c As StrChar) As Long
392 Return indexOfCore(c, 0, m_Length)
393 End Function
394
395 Const Function IndexOf(c As StrChar, start As Long) As Long
396 rangeCheck(start)
397 Return indexOfCore(c, start, m_Length - start)
398 End Function
399
400 Const Function IndexOf(c As StrChar, start As Long, count As Long) As Long
401 rangeCheck(start, count)
402 Return indexOfCore(c, start, count)
403 End Function
404 Private
405 Const Function indexOfCore(c As StrChar, start As Long, count As Long) As Long
406 indexOfCore = ActiveBasic.Strings.ChrFind(VarPtr(Chars[start]), count, c) As Long
407 If indexOfCore <> -1 Then
408 indexOfCore += start
409 End If
410 End Function
411 Public
412 Const Function IndexOf(s As String) As Long
413 Return IndexOf(s, 0, m_Length)
414 End Function
415
416 Const Function IndexOf(s As String, startIndex As Long) As Long
417 Return IndexOf(s, startIndex, m_Length - startIndex)
418 End Function
419
420 Const Function IndexOf(s As String, startIndex As Long, count As Long) As Long
421 rangeCheck(startIndex, count)
422 If Object.ReferenceEquals(s, Nothing) Then
423 Throw New ArgumentNullException("String.IndexOf: An argument is out of range value.", "s")
424 End If
425
426 Dim length = s.Length
427 If length = 0 Then Return startIndex
428
429 Dim i As Long, j As Long
430 For i = startIndex To startIndex + count - 1
431 For j = 0 To length - 1
432 If Chars[i + j] = s[j] Then
433 If j = length - 1 Then Return i
434 Else
435 Exit For
436 End If
437 Next
438 Next
439 Return -1
440 End Function
441
442 Const Function LastIndexOf(c As StrChar) As Long
443 Return lastIndexOf(c, m_Length - 1, m_Length)
444 End Function
445
446 Const Function LastIndexOf(c As StrChar, start As Long) As Long
447 rangeCheck(start)
448 Return lastIndexOf(c, start, start + 1)
449 End Function
450
451 Const Function LastIndexOf(c As StrChar, start As Long, count As Long) As Long
452 rangeCheck(start)
453 Dim lastFindPos = start - (count - 1)
454 If Not (m_Length > lastFindPos And lastFindPos >= 0) Then
455 Throw New ArgumentOutOfRangeException("String.LastIndexOf: An argument is out of range value.", "count")
456 End If
457 Return lastIndexOf(c, start, count)
458 End Function
459 Private
460 Const Function lastIndexOf(c As StrChar, start As Long, count As Long) As Long
461 Dim lastFindPos = start - (count - 1)
462 Dim i As Long
463 For i = start To lastFindPos Step -1
464 If Chars[i] = c Then
465 Return i
466 End If
467 Next
468 Return -1
469 End Function
470
471 Public
472 Const Function LastIndexOf(s As String) As Long
473 Return LastIndexOf(s, m_Length - 1, m_Length)
474 End Function
475
476 Const Function LastIndexOf(s As String, startIndex As Long) As Long
477 Return LastIndexOf(s, startIndex, startIndex + 1)
478 End Function
479
480 Const Function LastIndexOf(s As String, start As Long, count As Long) As Long
481 If Object.ReferenceEquals(s, Nothing) Then
482 Throw New ArgumentNullException("String.LastIndexOf: An argument is out of range value.", "s")
483 End If
484
485 If start < 0 Or start > m_Length - 1 Or _
486 count < 0 Or count > start + 2 Then
487 Throw New ArgumentOutOfRangeException("String.LastIndexOf: One or more arguments are out of range value.", "start or count or both")
488 End If
489 Dim length = s.m_Length
490 If length > m_Length Then Return -1
491 If length = 0 Then Return start
492
493 Dim i As Long, j As Long
494 For i = start To start - count + 1 Step -1
495 For j = length - 1 To 0 Step -1
496 If Chars[i + j] = s[j] Then
497 If j = 0 Then Return i
498 Else
499 Exit For
500 End If
501 Next
502 Next
503 Return -1
504 End Function
505
506 Const Function StartsWith(c As StrChar) As Boolean
507 Return IndexOf(c) = 0
508 End Function
509
510 Const Function StartsWith(s As String) As Boolean
511 Return IndexOf(s) = 0
512 End Function
513
514 Const Function EndsWith(c As StrChar) As Boolean
515 Return LastIndexOf(c) = m_Length - 1
516 End Function
517
518 Const Function EndsWith(s As String) As Boolean
519 Return LastIndexOf(s) = m_Length - s.Length
520 End Function
521
522 Const Function Insert(startIndex As Long, text As String) As String
523 Dim sb = New Text.StringBuilder(This)
524 sb.Insert(startIndex, text)
525 Return sb.ToString
526 End Function
527
528 Const Function Substring(startIndex As Long) As String
529 rangeCheck(startIndex)
530 Return Substring(startIndex, m_Length - startIndex)
531 End Function
532
533 Const Function Substring(startIndex As Long, length As Long) As String
534 rangeCheck(startIndex, length)
535 Return New String(Chars, startIndex, length)
536 End Function
537
538 Const Function Remove(startIndex As Long) As String
539 rangeCheck(startIndex)
540 Remove = Substring(0, startIndex)
541 End Function
542
543 Const Function Remove(startIndex As Long, count As Long) As String
544 Dim sb = New Text.StringBuilder(This)
545 sb.Remove(startIndex, count)
546 Remove = sb.ToString
547 End Function
548
549 Static Function IsNullOrEmpty(s As String) As Boolean
550 If Not Object.ReferenceEquals(s, Nothing) Then
551 If s.m_Length > 0 Then
552 Return False
553 End If
554 End If
555 Return True
556 End Function
557
558 Const Function Replace(oldChar As StrChar, newChar As StrChar) As String
559 Dim sb = New Text.StringBuilder(This)
560 sb.Replace(oldChar, newChar)
561 Replace = sb.ToString
562 End Function
563
564 Const Function Replace(oldStr As String, newStr As String) As String
565 Dim sb = New Text.StringBuilder(This)
566 sb.Replace(oldStr, newStr)
567 Return sb.ToString
568 End Function
569
570 Const Function ToLower() As String
571 Dim sb = New Text.StringBuilder(m_Length)
572 sb.Length = m_Length
573 Dim i As Long
574 For i = 0 To ELM(m_Length)
575 sb[i] = ActiveBasic.CType.ToLower(Chars[i])
576 Next
577 Return sb.ToString
578 End Function
579
580 Const Function ToUpper() As String
581 Dim sb = New Text.StringBuilder(m_Length)
582 sb.Length = m_Length
583 Dim i As Long
584 For i = 0 To ELM(m_Length)
585 sb[i] = ActiveBasic.CType.ToUpper(Chars[i])
586 Next
587 Return sb.ToString
588 End Function
589
590 Override Function ToString() As String
591 ToString = This
592 End Function
593
594 Const Function Clone() As String
595 Clone = This
596 End Function
597/*
598 Function Clone() As Object
599 Clone = This
600 End Function
601*/
602 Static Function Copy(s As String) As String
603 Copy = New String(s.Chars, s.m_Length)
604 End Function
605
606 Sub CopyTo(sourceIndex As Long, destination As *StrChar, destinationIndex As Long, count As Long)
607 ActiveBasic.Strings.ChrCopy(VarPtr(destination[destinationIndex]), VarPtr(Chars[sourceIndex]), count As SIZE_T)
608 End Sub
609
610 Override Function GetHashCode() As Long
611#ifdef __STRING_IS_NOT_UNICODE
612 Dim size = (m_Length + 1) >> 1
613#else
614 Dim size = m_Length
615#endif
616 Return _System_GetHashFromWordArray(Chars As *Word, size) Xor m_Length
617 End Function
618
619 Function PadLeft(total As Long) As String
620 PadLeft(total, &h30 As StrChar)
621 End Function
622
623 Function PadLeft(total As Long, c As StrChar) As String
624 If total < 0 Then
625 Throw New ArgumentOutOfRangeException("String.PadLeft: An arguments is out of range value.", "total")
626 End If
627 If total >= m_Length Then
628 Return This
629 End If
630 Dim sb = New Text.StringBuilder(total)
631 sb.Append(c, total - m_Length)
632 sb.Append(This)
633 Return sb.ToString
634 End Function
635
636 Function PadRight(total As Long) As String
637 PadRight(total, &h30 As StrChar)
638 End Function
639
640 Function PadRight(total As Long, c As StrChar) As String
641 If total < 0 Then
642 Throw New ArgumentOutOfRangeException("String.PadRight: An arguments is out of range value.", "total")
643 End If
644 If total >= m_Length Then
645 Return This
646 End If
647 Dim sb = New Text.StringBuilder(total)
648 sb.Append(This)
649 sb.Append(c, total - m_Length)
650 Return sb.ToString
651 End Function
652 Private
653 Function AllocStringBuffer(textLength As Long) As *StrChar
654 If textLength < 0 Then
655 Return 0
656 End If
657 AllocStringBuffer = GC_malloc_atomic(SizeOf(StrChar) * (textLength + 1))
658 If AllocStringBuffer = 0 Then
659 'Throw New OutOfMemoryException
660 End If
661 m_Length = textLength
662 Chars = AllocStringBuffer
663 End Function
664
665 Sub AssignFromStrChar(text As *StrChar, textLength As Long)
666 AllocStringBuffer(textLength)
667 ActiveBasic.Strings.ChrCopy(Chars, text, textLength As SIZE_T)
668 Chars[m_Length] = 0
669 End Sub
670
671 Const Sub rangeCheck(index As Long)
672 If index < 0 Or index > m_Length Then
673 Throw New ArgumentOutOfRangeException("String: An arguments is out of range value.", "index")
674 End If
675 End Sub
676
677 Const Sub rangeCheck(start As Long, length As Long)
678 If start < 0 Or start > This.m_Length Or length < 0 Then
679 Throw New ArgumentOutOfRangeException("String: One or more arguments are out of range value.", "start or length or both")
680 End If
681 End Sub
682
683 Static Function removeNull(s As String) As String
684 If ActiveBasic.IsNothing(s) Then
685 removeNull = Empty
686 Else
687 removeNull = s
688 End If
689 End Function
690 End Class
691
692End Namespace
Note: See TracBrowser for help on using the repository browser.