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

Last change on this file since 183 was 183, checked in by dai, 17 years ago

*Byteをパラメータに持つメソッドをコメントアウト(弊害がなければ削除する方向でいきましょう)。
Operator=の定義をコメントアウト。

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)
242 End If
243#endif
244 End Sub
[1]245
[175]246 Sub Assign(text As PCWSTR, textLengthW As Long)
[139]247#ifdef __STRING_IS_NOT_UNICODE
[175]248 Dim textLengthA = WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, 0, 0, 0, 0)
249 If AllocStringBuffer(textLengthA) <> 0 Then
250 WideCharToMultiByte(CP_THREAD_ACP, 0, text, textLengthW, Chars, textLengthA, 0, 0)
251 End If
[139]252#else
[175]253 AssignFromStrChar(text, textLengthW)
[139]254#endif
255 End Sub
256
[1]257 Sub Assign(ByRef objString As String)
[31]258 Assign(objString.Chars, objString.m_Length)
[1]259 End Sub
260
[139]261 Sub Assign(text As PCSTR)
[121]262 If text Then
[139]263 Assign(text, lstrlenA(text))
[1]264 Else
[139]265 If Chars <> 0 Then
266 Chars[0] = 0
267 End If
[30]268 m_Length = 0
[1]269 End If
270 End Sub
271
[139]272 Sub Assign(text As PCWSTR)
273 If text Then
274 Assign(text, lstrlenW(text))
275 Else
276 If Chars <> 0 Then
277 Chars[0] = 0
278 End If
279 m_Length = 0
280 End If
281 End Sub
282
283 Sub Append(text As *StrChar, textLength As Long)
[1]284 Dim prevLen As Long
[30]285 prevLen = m_Length
286 If AllocStringBuffer(m_Length + textLength) <> 0 Then
[139]287 memcpy(VarPtr(Chars[prevLen]), text, SizeOf (StrChar) * textLength)
[31]288 Chars[m_Length] = 0
[1]289 End If
290 End Sub
291
[139]292 Sub Append(text As *StrChar)
[1]293 Append(text, lstrlen(text))
294 End Sub
295
296 Sub Append(ByRef str As String)
[31]297 Append(str.Chars, str.m_Length)
[1]298 End Sub
299
[132]300 Const Function Clone() As String
301 Return This
302 End Function
[139]303Private
304 Static Const Function ConcatStrChar(text1 As *StrChar, text1Length As Long, text2 As *StrChar, text2Length As Long) As String
305 With ConcatStrChar
306 .AllocStringBuffer(text1Length + text2Length)
307 memcpy(.Chars, text1, SizeOf (StrChar) * text1Length)
308 memcpy(VarPtr(.Chars[text1Length]), text2, SizeOf (StrChar) * text2Length)
309 .Chars[text1Length + text2Length] = 0
310 End With
311 End Function
312Public
313 Const Function Concat(text As PCSTR, len As Long) As String
314#ifdef __STRING_IS_NOT_UNICODE
315 Return ConcatStrChar(This.Chars, m_Length, text, len)
316#else
317 With Concat
318 Dim lenW = MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, 0, 0)
319 .AllocStringBuffer(m_Length + lenW)
320 memcpy(.Chars, This.Chars, m_Length)
321 MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenW)
322 .Chars[m_Length + lenW] = 0
323 End With
324#endif
325 End Function
[132]326
[139]327 Const Function Concat(text As PCWSTR, len As Long) As String
328#ifdef __STRING_IS_NOT_UNICODE
329 With Concat
330 Dim lenA = MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, 0, 0, 0, 0)
331 .AllocStringBuffer(m_Length + lenA)
332 memcpy(.Chars, This.Chars, m_Length)
333 MultiByteToWideChar(CP_THREAD_ACP, 0, text, len, VarPtr(.Chars[m_Length]), lenA, 0, 0)
334 .Chars[m_Length + lenA] = 0
[1]335 End With
[139]336#else
337 Return ConcatStrChar(This.Chars, m_Length, text, len)
338#endif
[1]339 End Function
[132]340 Const Function Contains(ByRef objString As String) As Boolean
341 Return IndexOf(objString, 0, m_Length) >= 0
[1]342 End Function
343
[139]344 Const Function Contains(lpszText As *StrChar) As Boolean
[132]345 Return IndexOf(lpszText, 0, m_Length) >= 0
[1]346 End Function
347
[139]348 Const Function IndexOf(lpszText As *StrChar) As Long
[30]349 Return IndexOf(lpszText, 0, m_Length)
[1]350 End Function
351
[139]352 Const Function IndexOf(lpszText As *StrChar, startIndex As Long) As Long
[30]353 Return IndexOf(lpszText, startIndex, m_Length - startIndex)
[1]354 End Function
355
[139]356 Const Function IndexOf(lpszText As *StrChar, startIndex As Long, count As Long) As Long
[132]357 Dim length = lstrlen(lpszText)
[1]358
359 If startIndex < 0 Then Return -1
[30]360 If count < 1 Or count + startIndex > m_Length Then Return -1
361 If length > m_Length Then Return -1
[1]362
363 If length = 0 Then Return startIndex
364
365 Dim i As Long, j As Long
366 For i = startIndex To startIndex + count - 1
367 For j = 0 To length - 1
[31]368 If Chars[i + j] = lpszText[j] Then
[1]369 If j = length - 1 Then Return i
370 Else
371 Exit For
372 End If
373 Next
374 Next
375 Return -1
376 End Function
377
[139]378 Const Function LastIndexOf(lpszText As *StrChar) As Long
[30]379 Return LastIndexOf(lpszText, m_Length - 1, m_Length)
[1]380 End Function
381
[139]382 Const Function LastIndexOf(lpszText As *StrChar, startIndex As Long) As Long
383 Return LastIndexOf(lpszText As *StrChar, startIndex, startIndex + 1)
[1]384 End Function
385
[139]386 Const Function LastIndexOf(lpszText As *StrChar, startIndex As Long, count As Long) As Long
[132]387 Dim length = lstrlen(lpszText)
[1]388
[30]389 If startIndex < 0 Or startIndex > m_Length - 1 Then Return -1
[1]390 If count < 1 Or count > startIndex + 2 Then Return -1
[30]391 If length > m_Length Then Return -1
[1]392
393 If length = 0 Then Return startIndex
394
395 Dim i As Long, j As Long
396 For i = startIndex To startIndex - count + 1 Step -1
397 For j = length - 1 To 0 Step -1
[31]398 If Chars[i + j] = lpszText[j] Then
[1]399 If j = 0 Then Return i
400 Else
401 Exit For
402 End If
403 Next
404 Next
405 Return -1
406 End Function
407
[139]408 Const Function StartsWith(lpszText As *StrChar) As Boolean
[132]409 Return IndexOf(lpszText) = 0
[1]410 End Function
411
[139]412 Const Function EndsWith(lpszText As *StrChar) As Boolean
[132]413 Return LastIndexOf(lpszText) = m_Length - lstrlen(lpszText)
[1]414 End Function
415
[132]416 Const Function Insert(startIndex As Long, text As String) As String
417 Return Insert(startIndex, text.Chars, text.Length)
418 End Function
[1]419
[139]420 Const Function Insert(startIndex As Long, text As *StrChar) As String
[132]421 Return Insert(startIndex, text, lstrlen(text))
422 End Function
[1]423
[139]424 Const Function Insert(startIndex As Long, text As *StrChar, length As Long) As String
[132]425 If startIndex < 0 Or startIndex > m_Length Or length < 0 Then
426 Debug 'ArgumentOutOfRangeException
[1]427
[132]428 End If
429 Insert.ReSize(m_Length + length)
[139]430 memcpy(Insert.Chars, Chars, SizeOf (StrChar) * startIndex)
431 memcpy(VarPtr(Insert.Chars[startIndex]), text, SizeOf (StrChar) * length)
432 memcpy(VarPtr(Insert.Chars[startIndex + length]), VarPtr(Chars[startIndex]), SizeOf (StrChar) * (m_Length - startIndex + 1))
[1]433 End Function
434
[132]435 Const Function SubString(startIndex As Long) As String
[30]436 Return SubString(startIndex, m_Length - startIndex)
[1]437 End Function
438
[132]439 Const Function SubString(startIndex As Long, length As Long) As String
[1]440 If startIndex < 0 Or length <= 0 Then Return ""
[30]441 If startIndex + length > m_Length Then Return ""
[1]442
443 Dim temp As String
444 temp.AllocStringBuffer(length)
[139]445 memcpy(temp.Chars, VarPtr(Chars[startIndex]), SizeOf (StrChar) * length)
[31]446 Chars[m_Length] = 0
[1]447 Return temp
448 End Function
449
[132]450 Const Function Remove(startIndex As Long) As String
[135]451 If startIndex < 0 Or startIndex > m_Length Then
452 Debug 'ArgumentOutOfRangeException
453 End If
454
[132]455 Remove.ReSize(startIndex)
[139]456 memcpy(Remove.Chars, This.Chars, SizeOf (StrChar) * startIndex)
[1]457 End Function
458
[132]459 Const Function Remove(startIndex As Long, count As Long) As String
[135]460 If startIndex < 0 Or count < 0 Or startIndex + count > m_Length Then
461 Debug 'ArgumentOutOfRangeException
462 End If
463
[132]464 Remove.ReSize(m_Length - count)
[139]465 memcpy(Remove.Chars, This.Chars, SizeOf (StrChar) * startIndex)
466 memcpy(VarPtr(Remove.Chars[startIndex]), VarPtr(This.Chars[startIndex + count]), SizeOf (StrChar) * (m_Length - startIndex - count))
[132]467 End Function
468/*
469 Static Function IsNullOrEmpty(s As String) As Boolean
470 If s <> Nothing Then
471 If s.m_Length > 0 Then
472 Return True
473 End If
474 End If
475 Return False
476 End Function
477*/
[139]478 Const Function Replace(oldChar As StrChar, newChar As StrChar) As String
[132]479 Replace = Copy(This)
480 With Replace
481 Dim i As Long
482 For i = 0 To ELM(.m_Length)
[142]483 If .Chars[i] = oldChar Then
484 .Chars[i] = newChar
[132]485 End If
486 Next
487 End With
488 End Function
[1]489
[132]490 Const Function Replace(ByRef oldStr As String, ByRef newStr As String) As String
491' If oldStr = Nothing Then Throw ArgumentNullException
492'
493' If newStr = Nothing Then
494' Return ReplaceCore(oldStr, oldStr.m_Length, "", 0)
495' Else
496 Return ReplaceCore(oldStr, oldStr.m_Length, newStr, newStr.m_Length)
497' End If
498 End Function
[1]499
[139]500 Const Function Replace(oldStr As *StrChar, newStr As *StrChar)
[132]501 If oldStr = 0 Then Debug 'Throw ArgumentNullException
502 If newStr = 0 Then newStr = ""
503 Return ReplaceCore(oldStr, lstrlen(oldStr), newStr, lstrlen(newStr)) As String
[1]504 End Function
505
[139]506 Const Function Replace(oldStr As *StrChar, oldLen As Long, newStr As *StrChar, newLen As Long) As String
[132]507 If oldStr = 0 Then Debug 'Throw ArgumentNullException
508 If newStr = 0 Then
509 newStr = ""
510 newLen = 0
[1]511 End If
[132]512 Return ReplaceCore(oldStr, oldLen, newStr, newLen)
[1]513 End Function
514
[134]515 Const Function ToLower() As String
516 ToLower.ReSize(m_Length)
[125]517 Dim i As Long
[134]518 For i = 0 To ELM(m_Length)
519 ToLower.Chars[i] = _System_ASCII_ToLower(Chars[i])
[125]520 Next
[134]521 End Function
[1]522
[134]523 Const Function ToUpper() As String
524 ToUpper.ReSize(m_Length)
[125]525 Dim i As Long
[134]526 For i = 0 To ELM(m_Length)
527 ToUpper.Chars[i] = _System_ASCII_ToUpper(Chars[i])
[125]528 Next
[134]529 End Function
[1]530
531 Sub Swap(ByRef x As String)
532 Dim tempLen As Long
[139]533 Dim tempChars As *StrChar
[30]534 tempLen = x.m_Length
[31]535 tempChars = x.Chars
[30]536 x.m_Length = This.m_Length
[31]537 x.Chars = This.Chars
[30]538 This.m_Length = tempLen
[31]539 This.Chars = tempChars
[1]540 End Sub
541
[119]542 Override Function ToString() As String
543 Return This
544 End Function
545
[132]546 Static Function Copy(s As String) As String
[142]547 Copy.ReSize(s.m_Length)
[139]548 memcpy(Copy.Chars, This.Chars, SizeOf (StrChar) * m_Length)
[132]549 End Function
550
[143]551 Override Function GetHashCode() As Long
552#ifdef __STRING_IS_NOT_UNICODE
553 Dim size = (m_Length + 1) >> 1
554#else
555 Dim size = m_Length
556#endif
[175]557 Return _System_GetHashFromWordArray(Chars As *Word, size)
[143]558 End Function
[1]559Private
560 ' メモリ確保に失敗すると元の文字列は失われない。(例外安全でいう強い保障)
[139]561 Function AllocStringBuffer(textLength As Long) As *StrChar
[1]562 If textLength < 0 Then
563 Return 0
[30]564 ElseIf textLength > m_Length Then
[139]565 AllocStringBuffer = _System_realloc(Chars, SizeOf(StrChar) * (textLength + 1))
[1]566 If AllocStringBuffer <> 0 Then
[30]567 m_Length = textLength
[31]568 Chars = AllocStringBuffer
[1]569 End If
570 Else
[30]571 m_Length = textLength
[31]572 AllocStringBuffer = Chars
[1]573 End If
574 End Function
575
[139]576 Function ReplaceCore(oldStr As *StrChar, oldLen As Long, newStr As *StrChar, newLen As Long) As String
[132]577 If oldLen = 0 Then
578 Debug 'Throw ArgumentException
579 End If
580 Dim tmp As String
581 With tmp
582 Dim current = 0 As Long
583 Do
584 Dim pos = IndexOf(oldStr, current)
585 If pos = -1 Then
586 Exit Do
587 End If
588 .Append(VarPtr(Chars[current]), pos - current)
589 .Append(newStr, newLen)
590 current = pos + oldLen
591 Loop
592 .Append(VarPtr(Chars[current]), m_Length - current)
593 End With
594 Return tmp
595 End Function
596
[175]597 Sub AssignFromStrChar(text As *StrChar, textLength As Long)
598 If text = Chars Then Exit Sub
599 If AllocStringBuffer(textLength) <> 0 Then
600 memcpy(Chars, text, SizeOf (StrChar) * textLength)
601 Chars[m_Length] = 0
602 End If
603 End Sub
[1]604End Class
Note: See TracBrowser for help on using the repository browser.