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

Last change on this file since 370 was 370, checked in by dai, 16 years ago

System.GCクラスを追加。
64ビットコンパイラで生じる警告を改修した。

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