source: Include/Classes/System/String.ab@ 272

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

StringBuilderを追加。String不変へ。共通の文字列操作関数をActiveBasic.Strings内に配置(設計に検討の余地あり)。

File size: 16.3 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 Const Function StrPtr() As *StrChar
249 Return Chars
250 End Function
251Private
252
253 Sub Assign(text As PCSTR, textLengthA As Long)
254#ifdef __STRING_IS_NOT_UNICODE
255 AssignFromStrChar(text, textLengthA)
256#else
257 Dim textLengthW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, textLengthA, 0, 0)
258 If AllocStringBuffer(textLengthW) <> 0 Then
259 MultiByteToWideChar(CP_THREAD_ACP, 0, text, textLengthA, Chars, textLengthW)
260 Chars[textLengthW] = 0
261 End If
262#endif
263 End Sub
264
265 Sub Assign(text As PCWSTR, textLengthW As Long)
266#ifdef __STRING_IS_NOT_UNICODE
267 Dim textLengthA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, 0, 0, 0, 0)
268 If AllocStringBuffer(textLengthA) <> 0 Then
269 WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, Chars, textLengthA, 0, 0)
270 Chars[textLengthA] = 0
271 End If
272#else
273 AssignFromStrChar(text, textLengthW)
274#endif
275 End Sub
276
277 Private
278 Static Function ConcatStrChar(text1 As *StrChar, text1Length As Long, text2 As *StrChar, text2Length As Long) As String
279 ConcatStrChar = New String()
280 With ConcatStrChar
281 .AllocStringBuffer(text1Length + text2Length)
282 ActiveBasic.Strings.ChrCopy(.Chars, text1, text1Length As SIZE_T)
283 ActiveBasic.Strings.ChrCopy(VarPtr(.Chars[text1Length]), text2, text2Length As SIZE_T)
284 .Chars[text1Length + text2Length] = 0
285 End With
286 End Function
287 Public
288 Const Function Concat(text As PCSTR, len As Long) As String
289#ifdef __STRING_IS_NOT_UNICODE
290 Return ConcatStrChar(This.Chars, m_Length, text, len)
291#else
292 With Concat
293 Dim lenW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, 0, 0)
294 Concat = New String
295 .AllocStringBuffer(m_Length + lenW)
296 ActiveBasic.Strings.ChrCopy(.Chars, This.Chars, m_Length)
297 MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenW)
298 .Chars[m_Length + lenW] = 0
299 End With
300#endif
301 End Function
302
303 Const Function Concat(text As PCWSTR, len As Long) As String
304#ifdef __STRING_IS_NOT_UNICODE
305 With Concat
306 Concat = New String
307 Dim lenA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, len, 0, 0, 0, 0)
308 .AllocStringBuffer(m_Length + lenA)
309 ActiveBasic.Strings.ChrCopy(.Chars, This.Chars, m_Length As SIZE_T)
310 WideCharToMultiByte(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenA, 0, 0)
311 .Chars[m_Length + lenA] = 0
312 End With
313#else
314 Return ConcatStrChar(This.Chars, m_Length, text, len)
315#endif
316 End Function
317
318 Static Function Concat(x As String, y As String) As String
319 If String.IsNullOrEmpty(x) Then
320 Return y
321 Else
322 Return x.Concat(y.Chars, y.m_Length)
323 End If
324 End Function
325
326 Static Function Concat(x As Object, y As Object) As String
327 Return String.Concat(x.ToString, y.ToString)
328 End Function
329
330 Const Function Contains(s As String) As Boolean
331 If Object.ReferenceEquals(s, Nothing) Then
332 'Throw New ArgumentNullException
333 End If
334 Return IndexOf(s, 0, m_Length) >= 0
335 End Function
336
337 Const Function IndexOf(c As StrChar) As Long
338 Return indexOfCore(c, 0, m_Length)
339 End Function
340
341 Const Function IndexOf(c As StrChar, start As Long) As Long
342 rangeCheck(start)
343 Return indexOfCore(c, start, m_Length - start)
344 End Function
345
346 Const Function IndexOf(c As StrChar, start As Long, count As Long) As Long
347 rangeCheck(start, count)
348 Return indexOfCore(c, start, count)
349 End Function
350 Private
351 Const Function indexOfCore(c As StrChar, start As Long, count As Long) As Long
352 indexOfCore = ActiveBasic.Strings.ChrFind(VarPtr(Chars[start]), count, c)
353 If indexOfCore <> -1 Then
354 indexOfCore += start
355 End If
356 End Function
357 Public
358 Const Function IndexOf(s As String) As Long
359 Return IndexOf(s, 0, m_Length)
360 End Function
361
362 Const Function IndexOf(s As String, startIndex As Long) As Long
363 Return IndexOf(s, startIndex, m_Length - startIndex)
364 End Function
365
366 Const Function IndexOf(s As String, startIndex As Long, count As Long) As Long
367 rangeCheck(startIndex, count)
368 If Object.ReferenceEquals(s, Nothing) Then
369 'Throw New ArgumentNullException
370 Debug
371 End If
372
373 Dim length = s.Length
374 If length = 0 Then Return startIndex
375
376 Dim i As Long, j As Long
377 For i = startIndex To startIndex + count - 1
378 For j = 0 To length - 1
379 If Chars[i + j] = s[j] Then
380 If j = length - 1 Then Return i
381 Else
382 Exit For
383 End If
384 Next
385 Next
386 Return -1
387 End Function
388
389 Const Function LastIndexOf(s As String) As Long
390 Return LastIndexOf(s, m_Length - 1, m_Length)
391 End Function
392
393 Const Function LastIndexOf(s As String, startIndex As Long) As Long
394 Return LastIndexOf(s, startIndex, startIndex + 1)
395 End Function
396
397 Const Function LastIndexOf(s As String, startIndex As Long, count As Long) As Long
398 If Object.ReferenceEquals(s, Nothing) Then
399 'Throw New ArgumentNullException
400 Debug
401 End If
402
403 If startIndex < 0 Or startIndex > m_Length - 1 Or _
404 count < 0 Or count > startIndex + 2 Then
405 'Throw New ArgumentOutOfRangeException
406 Debug
407 End If
408 Dim length = s.Length
409 If length > m_Length Then Return -1
410 If length = 0 Then Return startIndex
411
412 Dim i As Long, j As Long
413 For i = startIndex To startIndex - count + 1 Step -1
414 For j = length - 1 To 0 Step -1
415 If Chars[i + j] = s[j] Then
416 If j = 0 Then Return i
417 Else
418 Exit For
419 End If
420 Next
421 Next
422 Return -1
423 End Function
424
425 Const Function StartsWith(s As String) As Boolean
426 Return IndexOf(s) = 0
427 End Function
428
429 Const Function EndsWith(s As String) As Boolean
430 Return LastIndexOf(s) = m_Length - s.Length
431 End Function
432
433 Const Function Insert(startIndex As Long, text As String) As String
434 Dim sb = New System.Text.StringBuilder(This)
435 sb.Insert(startIndex, text)
436 Return sb.ToString
437 End Function
438
439 Const Function Substring(startIndex As Long) As String
440 rangeCheck(startIndex)
441 Return Substring(startIndex, m_Length - startIndex)
442 End Function
443
444 Const Function Substring(startIndex As Long, length As Long) As String
445 rangeCheck(startIndex, length)
446 Return New String(Chars, startIndex, length)
447 End Function
448
449 Const Function Remove(startIndex As Long) As String
450 rangeCheck(startIndex)
451 Remove = Substring(0, startIndex)
452 End Function
453
454 Const Function Remove(startIndex As Long, count As Long) As String
455 Dim sb = New System.Text.StringBuilder(This)
456 sb.Remove(startIndex, count)
457 Remove = sb.ToString
458 End Function
459
460 Static Function IsNullOrEmpty(s As String) As Boolean
461 If Not Object.ReferenceEquals(s, Nothing) Then
462 If s.m_Length > 0 Then
463 Return False
464 End If
465 End If
466 Return True
467 End Function
468
469 Const Function Replace(oldChar As StrChar, newChar As StrChar) As String
470 Dim sb = New System.Text.StringBuilder(This)
471 sb.Replace(oldChar, newChar)
472 Replace = sb.ToString
473 End Function
474
475 Const Function Replace(oldStr As String, newStr As String) As String
476 Dim sb = New System.Text.StringBuilder(This)
477 sb.Replace(oldStr, newStr)
478 Return sb.ToString
479 End Function
480
481 Const Function ToLower() As String
482 Dim sb = New System.Text.StringBuilder(m_Length)
483 sb.Length = m_Length
484 Dim i As Long
485 For i = 0 To ELM(m_Length)
486 sb[i] = _System_ASCII_ToLower(Chars[i])
487 Next
488 Return sb.ToString
489 End Function
490
491 Const Function ToUpper() As String
492 Dim sb = New System.Text.StringBuilder(m_Length)
493 sb.Length = m_Length
494 Dim i As Long
495 For i = 0 To ELM(m_Length)
496 sb[i] = _System_ASCII_ToUpper(Chars[i])
497 Next
498 Return sb.ToString
499 End Function
500
501 Override Function ToString() As String
502 ToString = This
503 End Function
504
505 Const Function Clone() As String
506 Clone = This
507 End Function
508 Static Function Copy(s As String) As String
509 Copy = New String(s.Chars, s.m_Length)
510 End Function
511
512 Sub CopyTo(sourceIndex As Long, destination As *StrChar, destinationIndex As Long, count As Long)
513 ActiveBasic.Strings.ChrCopy(VarPtr(destination[destinationIndex]), VarPtr(Chars[sourceIndex]), count As SIZE_T)
514 End Sub
515
516 Override Function GetHashCode() As Long
517#ifdef __STRING_IS_NOT_UNICODE
518 Dim size = (m_Length + 1) >> 1
519#else
520 Dim size = m_Length
521#endif
522 Return _System_GetHashFromWordArray(Chars As *Word, size)
523 End Function
524
525 Function PadLeft(total As Long) As String
526 PadLeft(total, &h30 As StrChar)
527 End Function
528
529 Function PadLeft(total As Long, c As StrChar) As String
530 If total < 0 Then
531 'Throw New ArgumentException
532 End If
533 If total >= m_Length Then
534 Return This
535 End If
536 Dim sb = New System.Text.StringBuilder(total)
537 sb.Append(c, total - m_Length)
538 sb.Append(This)
539 Return sb.ToString
540 End Function
541
542 Function PadRight(total As Long) As String
543 PadLeft(total, &h30 As StrChar)
544 End Function
545
546 Function PadRight(total As Long, c As StrChar) As String
547 If total < 0 Then
548 'Throw New ArgumentException
549 End If
550 If total >= m_Length Then
551 Return This
552 End If
553 Dim sb = New System.Text.StringBuilder(total)
554 sb.Append(This)
555 sb.Append(c, total - m_Length)
556 Return sb.ToString
557 End Function
558 Private
559 Function AllocStringBuffer(textLength As Long) As *StrChar
560 If textLength < 0 Then
561 Return 0
562 End If
563 AllocStringBuffer = GC_malloc_atomic(SizeOf(StrChar) * (textLength + 1))
564 If AllocStringBuffer = 0 Then
565 'Throw New OutOfMemoryException
566 End If
567 m_Length = textLength
568 Chars = AllocStringBuffer
569 End Function
570
571 Sub AssignFromStrChar(text As *StrChar, textLength As Long)
572 AllocStringBuffer(textLength)
573 ActiveBasic.Strings.ChrCopy(Chars, text, textLength As SIZE_T)
574 Chars[m_Length] = 0
575 End Sub
576
577 Const Sub rangeCheck(index As Long)
578 If index < 0 Or index > m_Length Then
579 Debug 'ArgumentOutOfRangeException
580 End If
581 End Sub
582
583 Const Sub rangeCheck(start As Long, length As Long)
584 If start < 0 Or start > This.m_Length Or length < 0 Then
585 Debug 'ArgumentOutOfRangeException
586 End If
587 End Sub
588 End Class
589
590End Namespace
Note: See TracBrowser for help on using the repository browser.