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

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

FileStream非同期読み書きの修正、例外処理の追加。

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