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

Last change on this file since 497 was 497, checked in by イグトランス (egtra), 15 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.