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

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

Currencyを追加、その他修正

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