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

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

現在向けに修正(参照型のポインタの排除など)

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