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

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

Equalsの一部を実装

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 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)
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.