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
RevLine 
[132]1' Classes/System/String.ab
2
3#require <basic/function.sbp>
4
[139]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
[142]12#ifndef UNICODE
13#define __STRING_UNICODE_WINDOWS_ANSI
[139]14#endif
[142]15#endif
[139]16
[1]17Class String
[30]18 m_Length As Long
[1]19Public
[139]20 Chars As *StrChar
[1]21
22 Sub String()
[139]23 Chars = 0
[30]24 m_Length = 0
[1]25 End Sub
26
[183]27/* Sub String(initStr As *Byte)
[1]28 String()
[139]29 Assign(initStr As PCTSTR)
[183]30 End Sub*/
[139]31
32 Sub String(initStr As PCSTR)
33 String()
[1]34 Assign(initStr)
35 End Sub
[30]36
[139]37 Sub String(initStr As PCSTR, length As Long)
[125]38 String()
39 Assign(initStr, length)
40 End Sub
41
[139]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
[49]52 Sub String(ByRef initStr As String)
[1]53 String()
54 Assign(initStr)
55 End Sub
[49]56
[1]57 Sub String(length As Long)
[121]58 String()
[1]59 ReSize(length)
60 End Sub
[121]61
[139]62 Sub String(initChar As StrChar, length As Long)
[1]63 ReSize(length, initChar)
64 End Sub
65
66 Sub ~String()
[123]67 _System_free(Chars)
[31]68 Chars = 0
[1]69#ifdef _DEBUG
[30]70 m_Length = 0
[1]71#endif
72 End Sub
73
[121]74 Const Function Length() As Long
[30]75 Return m_Length
76 End Function
77
[139]78 Function Operator() As *StrChar
[31]79 Return Chars
[1]80 End Function
81
[183]82/* Sub Operator = (ByRef objString As String)
[31]83 Assign(objString.Chars, objString.m_Length)
[1]84 End Sub
85
[139]86 Sub Operator = (text As *Byte)
87 Assign(text As PCTSTR)
88 End Sub
89
90 Sub Operator = (text As PCSTR)
[1]91 Assign(text)
92 End Sub
93
[139]94 Sub Operator = (text As PCWSTR)
95 Assign(text)
[183]96 End Sub*/
[139]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
[31]105 Return Chars[n]
[1]106 End Function
107
[139]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
[31]115 Chars[n] = c
[1]116 End Sub
117
[183]118/* Const Function Operator + (text As *Byte) As String
[139]119 Return Concat(text As PCTSTR, lstrlen(text))
[183]120 End Function*/
[1]121
[139]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
[121]130 Const Function Operator + (ByRef objString As String) As String
[139]131 Return Concat(objString.Chars, objString.m_Length)
[1]132 End Function
133
[139]134 Const Function Operator & (text As PCSTR) As String
135 Dim tempString = This + text
[1]136 Return tempString
137 End Function
138
[139]139 Const Function Operator & (text As PCWSTR) As String
140 Dim tempString = This + text
141 Return tempString
142 End Function
143
[121]144 Const Function Operator & (ByRef objString As String) As String
145 Dim tempString = This + objString
[1]146 Return tempString
147 End Function
148
[132]149 Const Function Operator == (ByRef objString As String) As Boolean
[182]150 Return _System_StrCmp(This.Chars, objString.Chars) = 0
[1]151 End Function
152
[139]153 Const Function Operator == (text As *StrChar) As Long
[182]154 Return _System_StrCmp(This.Chars, text) = 0
[1]155 End Function
156
[132]157 Const Function Operator <> (ByRef objString As String) As Boolean
[182]158 Return _System_StrCmp(This.Chars, objString.Chars) <> 0
[1]159 End Function
160
[139]161 Const Function Operator <> (text As *StrChar) As Boolean
[182]162 Return _System_StrCmp(This.Chars, text) <> 0
[1]163 End Function
164
[132]165 Const Function Operator < (ByRef objString As String) As Boolean
[182]166 Return _System_StrCmp(This.Chars, objString.Chars) < 0
[1]167 End Function
168
[139]169 Const Function Operator < (text As *StrChar) As Boolean
[182]170 Return _System_StrCmp(This.Chars, text) < 0
[1]171 End Function
172
[132]173 Const Function Operator > (ByRef objString As String) As Boolean
[182]174 Return _System_StrCmp(This.Chars, objString.Chars) > 0
[1]175 End Function
176
[139]177 Const Function Operator > (text As *StrChar) As Boolean
[182]178 Return _System_StrCmp(This.Chars, text) > 0
[1]179 End Function
180
[132]181 Const Function Operator <= (ByRef objString As String) As Boolean
[182]182 Return _System_StrCmp(This.Chars, objString.Chars) <= 0
[1]183 End Function
184
[139]185 Const Function Operator <= (text As *StrChar) As Boolean
[182]186 Return _System_StrCmp(This.Chars, text) <= 0
[1]187 End Function
188
[132]189 Const Function Operator >= (ByRef objString As String) As Boolean
[182]190 Return _System_StrCmp(This.Chars, objString.Chars) >= 0
[1]191 End Function
192
[139]193 Const Function Operator >= (text As *StrChar) As Boolean
[182]194 Return _System_StrCmp(This.Chars, text) >= 0
[1]195 End Function
196
[139]197 Const Function StrPtr() As *StrChar
[31]198 Return Chars
[1]199 End Function
200
201 Sub ReSize(allocLength As Long)
202 If allocLength < 0 Then Exit Sub
[30]203 If allocLength > m_Length Then
[1]204 Dim oldLength As Long
[30]205 oldLength = m_Length
[1]206 If AllocStringBuffer(allocLength) <> 0 Then
[139]207 ZeroMemory(VarPtr(Chars[oldLength]), SizeOf (StrChar) * (m_Length - oldLength + 1))
[1]208 End If
209 Else
[30]210 m_Length = allocLength
[31]211 Chars[m_Length] = 0
[1]212 End If
213 End Sub
214
[139]215 Sub ReSize(allocLength As Long, c As StrChar)
[1]216 If allocLength < 0 Then
217 Exit Sub
[30]218 ElseIf allocLength > m_Length Then
[1]219 Dim oldLength As Long
[30]220 oldLength = m_Length
[1]221 If AllocStringBuffer(allocLength) <> 0 Then
[139]222 Dim p = VarPtr(Chars[oldLength]) As *StrChar
[121]223 Dim fillLen = m_Length - oldLength
224 Dim i As Long
225 For i = 0 To ELM(fillLen)
226 p[i] = c
227 Next
[1]228 End If
229 Else
[30]230 m_Length = allocLength
[1]231 End If
[31]232 Chars[m_Length] = 0
[1]233 End Sub
234
[175]235 Sub Assign(text As PCSTR, textLengthA As Long)
236#ifdef __STRING_IS_NOT_UNICODE
237 AssignFromStrChar(text, textLengthA)
[139]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)
[192]242 Chars[textLengthW] = 0
[139]243 End If
244#endif
245 End Sub
[1]246
[175]247 Sub Assign(text As PCWSTR, textLengthW As Long)
[139]248#ifdef __STRING_IS_NOT_UNICODE
[175]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)
[192]252 Chars[textLengthA] = 0
[175]253 End If
[139]254#else
[175]255 AssignFromStrChar(text, textLengthW)
[139]256#endif
257 End Sub
258
[1]259 Sub Assign(ByRef objString As String)
[31]260 Assign(objString.Chars, objString.m_Length)
[1]261 End Sub
262
[139]263 Sub Assign(text As PCSTR)
[121]264 If text Then
[139]265 Assign(text, lstrlenA(text))
[1]266 Else
[139]267 If Chars <> 0 Then
268 Chars[0] = 0
269 End If
[30]270 m_Length = 0
[1]271 End If
272 End Sub
273
[139]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)
[1]286 Dim prevLen As Long
[30]287 prevLen = m_Length
288 If AllocStringBuffer(m_Length + textLength) <> 0 Then
[139]289 memcpy(VarPtr(Chars[prevLen]), text, SizeOf (StrChar) * textLength)
[31]290 Chars[m_Length] = 0
[1]291 End If
292 End Sub
293
[139]294 Sub Append(text As *StrChar)
[1]295 Append(text, lstrlen(text))
296 End Sub
297
298 Sub Append(ByRef str As String)
[31]299 Append(str.Chars, str.m_Length)
[1]300 End Sub
301
[132]302 Const Function Clone() As String
303 Return This
304 End Function
[139]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
[132]328
[139]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
[1]337 End With
[139]338#else
339 Return ConcatStrChar(This.Chars, m_Length, text, len)
340#endif
[1]341 End Function
[132]342 Const Function Contains(ByRef objString As String) As Boolean
343 Return IndexOf(objString, 0, m_Length) >= 0
[1]344 End Function
345
[139]346 Const Function Contains(lpszText As *StrChar) As Boolean
[132]347 Return IndexOf(lpszText, 0, m_Length) >= 0
[1]348 End Function
349
[139]350 Const Function IndexOf(lpszText As *StrChar) As Long
[30]351 Return IndexOf(lpszText, 0, m_Length)
[1]352 End Function
353
[139]354 Const Function IndexOf(lpszText As *StrChar, startIndex As Long) As Long
[30]355 Return IndexOf(lpszText, startIndex, m_Length - startIndex)
[1]356 End Function
357
[139]358 Const Function IndexOf(lpszText As *StrChar, startIndex As Long, count As Long) As Long
[132]359 Dim length = lstrlen(lpszText)
[1]360
361 If startIndex < 0 Then Return -1
[30]362 If count < 1 Or count + startIndex > m_Length Then Return -1
363 If length > m_Length Then Return -1
[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
[31]370 If Chars[i + j] = lpszText[j] Then
[1]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
[139]380 Const Function LastIndexOf(lpszText As *StrChar) As Long
[30]381 Return LastIndexOf(lpszText, m_Length - 1, m_Length)
[1]382 End Function
383
[139]384 Const Function LastIndexOf(lpszText As *StrChar, startIndex As Long) As Long
385 Return LastIndexOf(lpszText As *StrChar, startIndex, startIndex + 1)
[1]386 End Function
387
[139]388 Const Function LastIndexOf(lpszText As *StrChar, startIndex As Long, count As Long) As Long
[132]389 Dim length = lstrlen(lpszText)
[1]390
[30]391 If startIndex < 0 Or startIndex > m_Length - 1 Then Return -1
[1]392 If count < 1 Or count > startIndex + 2 Then Return -1
[30]393 If length > m_Length Then Return -1
[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
[31]400 If Chars[i + j] = lpszText[j] Then
[1]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
[139]410 Const Function StartsWith(lpszText As *StrChar) As Boolean
[132]411 Return IndexOf(lpszText) = 0
[1]412 End Function
413
[139]414 Const Function EndsWith(lpszText As *StrChar) As Boolean
[132]415 Return LastIndexOf(lpszText) = m_Length - lstrlen(lpszText)
[1]416 End Function
417
[132]418 Const Function Insert(startIndex As Long, text As String) As String
419 Return Insert(startIndex, text.Chars, text.Length)
420 End Function
[1]421
[139]422 Const Function Insert(startIndex As Long, text As *StrChar) As String
[132]423 Return Insert(startIndex, text, lstrlen(text))
424 End Function
[1]425
[139]426 Const Function Insert(startIndex As Long, text As *StrChar, length As Long) As String
[132]427 If startIndex < 0 Or startIndex > m_Length Or length < 0 Then
428 Debug 'ArgumentOutOfRangeException
[1]429
[132]430 End If
431 Insert.ReSize(m_Length + length)
[139]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))
[1]435 End Function
436
[132]437 Const Function SubString(startIndex As Long) As String
[30]438 Return SubString(startIndex, m_Length - startIndex)
[1]439 End Function
440
[132]441 Const Function SubString(startIndex As Long, length As Long) As String
[1]442 If startIndex < 0 Or length <= 0 Then Return ""
[30]443 If startIndex + length > m_Length Then Return ""
[1]444
445 Dim temp As String
446 temp.AllocStringBuffer(length)
[139]447 memcpy(temp.Chars, VarPtr(Chars[startIndex]), SizeOf (StrChar) * length)
[31]448 Chars[m_Length] = 0
[1]449 Return temp
450 End Function
451
[132]452 Const Function Remove(startIndex As Long) As String
[135]453 If startIndex < 0 Or startIndex > m_Length Then
454 Debug 'ArgumentOutOfRangeException
455 End If
456
[132]457 Remove.ReSize(startIndex)
[139]458 memcpy(Remove.Chars, This.Chars, SizeOf (StrChar) * startIndex)
[1]459 End Function
460
[132]461 Const Function Remove(startIndex As Long, count As Long) As String
[135]462 If startIndex < 0 Or count < 0 Or startIndex + count > m_Length Then
463 Debug 'ArgumentOutOfRangeException
464 End If
465
[132]466 Remove.ReSize(m_Length - count)
[139]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))
[132]469 End Function
[192]470
[132]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
[192]479
[139]480 Const Function Replace(oldChar As StrChar, newChar As StrChar) As String
[132]481 Replace = Copy(This)
482 With Replace
483 Dim i As Long
484 For i = 0 To ELM(.m_Length)
[142]485 If .Chars[i] = oldChar Then
486 .Chars[i] = newChar
[132]487 End If
488 Next
489 End With
490 End Function
[1]491
[132]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
[1]501
[139]502 Const Function Replace(oldStr As *StrChar, newStr As *StrChar)
[132]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
[1]506 End Function
507
[139]508 Const Function Replace(oldStr As *StrChar, oldLen As Long, newStr As *StrChar, newLen As Long) As String
[132]509 If oldStr = 0 Then Debug 'Throw ArgumentNullException
510 If newStr = 0 Then
511 newStr = ""
512 newLen = 0
[1]513 End If
[132]514 Return ReplaceCore(oldStr, oldLen, newStr, newLen)
[1]515 End Function
516
[134]517 Const Function ToLower() As String
518 ToLower.ReSize(m_Length)
[125]519 Dim i As Long
[134]520 For i = 0 To ELM(m_Length)
521 ToLower.Chars[i] = _System_ASCII_ToLower(Chars[i])
[125]522 Next
[134]523 End Function
[1]524
[134]525 Const Function ToUpper() As String
526 ToUpper.ReSize(m_Length)
[125]527 Dim i As Long
[134]528 For i = 0 To ELM(m_Length)
529 ToUpper.Chars[i] = _System_ASCII_ToUpper(Chars[i])
[125]530 Next
[134]531 End Function
[1]532
533 Sub Swap(ByRef x As String)
534 Dim tempLen As Long
[139]535 Dim tempChars As *StrChar
[30]536 tempLen = x.m_Length
[31]537 tempChars = x.Chars
[30]538 x.m_Length = This.m_Length
[31]539 x.Chars = This.Chars
[30]540 This.m_Length = tempLen
[31]541 This.Chars = tempChars
[1]542 End Sub
543
[119]544 Override Function ToString() As String
545 Return This
546 End Function
547
[132]548 Static Function Copy(s As String) As String
[142]549 Copy.ReSize(s.m_Length)
[139]550 memcpy(Copy.Chars, This.Chars, SizeOf (StrChar) * m_Length)
[132]551 End Function
552
[143]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
[175]559 Return _System_GetHashFromWordArray(Chars As *Word, size)
[143]560 End Function
[1]561Private
562 ' メモリ確保に失敗すると元の文字列は失われない。(例外安全でいう強い保障)
[139]563 Function AllocStringBuffer(textLength As Long) As *StrChar
[1]564 If textLength < 0 Then
565 Return 0
[30]566 ElseIf textLength > m_Length Then
[139]567 AllocStringBuffer = _System_realloc(Chars, SizeOf(StrChar) * (textLength + 1))
[1]568 If AllocStringBuffer <> 0 Then
[30]569 m_Length = textLength
[31]570 Chars = AllocStringBuffer
[1]571 End If
572 Else
[30]573 m_Length = textLength
[31]574 AllocStringBuffer = Chars
[1]575 End If
576 End Function
577
[139]578 Function ReplaceCore(oldStr As *StrChar, oldLen As Long, newStr As *StrChar, newLen As Long) As String
[132]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
[175]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
[1]606End Class
Note: See TracBrowser for help on using the repository browser.