source: trunk/ab5.0/ablib/src/Classes/System/String.ab@ 506

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

インクルードガードとその他不要な前処理定義などの削除

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