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

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

ToUpper, ToLowerを戻り値で書き換えた文字列を返すように変更

File size: 12.4 KB
RevLine 
[132]1' Classes/System/String.ab
2
3#require <basic/function.sbp>
4
[1]5Class String
[30]6 m_Length As Long
[1]7Public
[119]8 Chars As *Char
[1]9
10 Sub String()
[121]11 Chars = _System_calloc(SizeOf (Char) * 1)
[30]12 m_Length = 0
[1]13 End Sub
14
[119]15 Sub String(initStr As *Char)
[1]16 String()
17 Assign(initStr)
18 End Sub
[30]19
[125]20 Sub String(initStr As *Char, length As Long)
21 String()
22 Assign(initStr, length)
23 End Sub
24
[49]25 Sub String(ByRef initStr As String)
[1]26 String()
27 Assign(initStr)
28 End Sub
[49]29
[1]30 Sub String(length As Long)
[121]31 String()
[1]32 ReSize(length)
33 End Sub
[121]34
[119]35 Sub String(initChar As Char, length As Long)
[1]36 ReSize(length, initChar)
37 End Sub
38
39 Sub ~String()
[123]40 _System_free(Chars)
[31]41 Chars = 0
[1]42#ifdef _DEBUG
[30]43 m_Length = 0
[1]44#endif
45 End Sub
46
[121]47 Const Function Length() As Long
[30]48 Return m_Length
49 End Function
50
[119]51 Function Operator() As *Char
[31]52 Return Chars
[1]53 End Function
54
55 Sub Operator = (ByRef objString As String)
[31]56 Assign(objString.Chars, objString.m_Length)
[1]57 End Sub
58
[119]59 Sub Operator = (text As *Char)
[1]60 Assign(text)
61 End Sub
62
[132]63 Const Function Operator [] (n As Long) As Char
[31]64 Return Chars[n]
[1]65 End Function
66
[132]67 Sub Operator []= (n As Long, c As Char)
[31]68 Chars[n] = c
[1]69 End Sub
70
[132]71 Const Function Operator + (pszText As *Char) As String
72 Return Concat(pszText, lstrlen(pszText))
[1]73 End Function
74
[121]75 Const Function Operator + (ByRef objString As String) As String
[30]76 Return Concat(objString, objString.m_Length)
[1]77 End Function
78
[132]79 Const Function Operator & (pszText As *Char) As String
80 Dim tempString = This + pszText
[1]81 Return tempString
82 End Function
83
[121]84 Const Function Operator & (ByRef objString As String) As String
85 Dim tempString = This + objString
[1]86 Return tempString
87 End Function
88
[132]89 Const Function Operator == (ByRef objString As String) As Boolean
90 Return _System_StrCmp(This, objString) = 0
[1]91 End Function
92
[132]93 Const Function Operator == (text As *Char) As Long
94 Return _System_StrCmp(This, text) = 0
[1]95 End Function
96
[132]97 Const Function Operator <> (ByRef objString As String) As Boolean
98 Return _System_StrCmp(This, objString)
[1]99 End Function
100
[132]101 Const Function Operator <> (text As *Char) As Boolean
102 Return _System_StrCmp(This, text)
[1]103 End Function
104
[132]105 Const Function Operator < (ByRef objString As String) As Boolean
106 Return _System_StrCmp(This, objString) < 0
[1]107 End Function
108
[132]109 Const Function Operator < (text As *Char) As Boolean
110 Return _System_StrCmp(This, text) < 0
[1]111 End Function
112
[132]113 Const Function Operator > (ByRef objString As String) As Boolean
114 Return _System_StrCmp(This, objString) > 0
[1]115 End Function
116
[132]117 Const Function Operator > (text As *Char) As Boolean
118 Return _System_StrCmp(This, text) > 0
[1]119 End Function
120
[132]121 Const Function Operator <= (ByRef objString As String) As Boolean
122 Return _System_StrCmp(This, objString) <= 0
[1]123 End Function
124
[132]125 Const Function Operator <= (text As *Char) As Boolean
126 Return _System_StrCmp(This, text) <= 0
[1]127 End Function
128
[132]129 Const Function Operator >= (ByRef objString As String) As Boolean
130 Return _System_StrCmp(This, objString) => 0
[1]131 End Function
132
[132]133 Const Function Operator >= (text As *Char) As Boolean
134 Return _System_StrCmp(This, text) => 0
[1]135 End Function
136
[132]137 Const Function StrPtr() As *Char
[31]138 Return Chars
[1]139 End Function
140
141 Sub ReSize(allocLength As Long)
142 If allocLength < 0 Then Exit Sub
[30]143 If allocLength > m_Length Then
[1]144 Dim oldLength As Long
[30]145 oldLength = m_Length
[1]146 If AllocStringBuffer(allocLength) <> 0 Then
[121]147 ZeroMemory(VarPtr(Chars[oldLength]), SizeOf (Char) * (m_Length - oldLength + 1))
[1]148 End If
149 Else
[30]150 m_Length = allocLength
[31]151 Chars[m_Length] = 0
[1]152 End If
153 End Sub
154
[119]155 Sub ReSize(allocLength As Long, c As Char)
[1]156 If allocLength < 0 Then
157 Exit Sub
[30]158 ElseIf allocLength > m_Length Then
[1]159 Dim oldLength As Long
[30]160 oldLength = m_Length
[1]161 If AllocStringBuffer(allocLength) <> 0 Then
[121]162 Dim p = VarPtr(Chars[oldLength]) As *Char
163 Dim fillLen = m_Length - oldLength
164 Dim i As Long
165 For i = 0 To ELM(fillLen)
166 p[i] = c
167 Next
[1]168 End If
169 Else
[30]170 m_Length = allocLength
[1]171 End If
[31]172 Chars[m_Length] = 0
[1]173 End Sub
174
[121]175 Sub Assign(text As *Char, textLength As Long)
176 If text = Chars Then Exit Sub
[1]177 If AllocStringBuffer(textLength) <> 0 Then
[121]178 memcpy(Chars, text, SizeOf (Char) * textLength)
[31]179 Chars[m_Length] = 0
[1]180 End If
181 End Sub
182
183 Sub Assign(ByRef objString As String)
[31]184 Assign(objString.Chars, objString.m_Length)
[1]185 End Sub
186
[121]187 Sub Assign(text As *Char)
188 If text Then
189 Assign(text, lstrlen(text))
[1]190 Else
[31]191 'Chars=_System_realloc(Chars,1)
192 Chars[0] = 0
[30]193 m_Length = 0
[1]194 End If
195 End Sub
196
[121]197 Sub Append(text As *Char, textLength As Long)
[1]198 Dim prevLen As Long
[30]199 prevLen = m_Length
200 If AllocStringBuffer(m_Length + textLength) <> 0 Then
[121]201 memcpy(VarPtr(Chars[prevLen]), text, SizeOf (Char) * textLength)
[31]202 Chars[m_Length] = 0
[1]203 End If
204 End Sub
205
[119]206 Sub Append(text As *Char)
[1]207 Append(text, lstrlen(text))
208 End Sub
209
210 Sub Append(ByRef str As String)
[31]211 Append(str.Chars, str.m_Length)
[1]212 End Sub
213
[132]214 Const Function Clone() As String
215 Return This
216 End Function
217
218 Const Function Concat(lpszText As *Char, textLength As Long) As String
[1]219 Dim tempString As String
220 With tempString
[30]221 .AllocStringBuffer(This.m_Length + textLength)
[121]222 memcpy(.Chars, This.Chars, SizeOf (Char) * This.m_Length)
223 memcpy(VarPtr(.Chars[This.m_Length]), lpszText, SizeOf (Char) * textLength)
[31]224 .Chars[.m_Length] = 0
[1]225 End With
226 Return tempString
227 End Function
228
[132]229 Const Function Contains(ByRef objString As String) As Boolean
230 Return IndexOf(objString, 0, m_Length) >= 0
[1]231 End Function
232
[132]233 Const Function Contains(lpszText As *Char) As Boolean
234 Return IndexOf(lpszText, 0, m_Length) >= 0
[1]235 End Function
236
[132]237 Const Function IndexOf(lpszText As *Char) As Long
[30]238 Return IndexOf(lpszText, 0, m_Length)
[1]239 End Function
240
[132]241 Const Function IndexOf(lpszText As *Char, startIndex As Long) As Long
[30]242 Return IndexOf(lpszText, startIndex, m_Length - startIndex)
[1]243 End Function
244
[132]245 Const Function IndexOf(lpszText As *Char, startIndex As Long, count As Long) As Long
246 Dim length = lstrlen(lpszText)
[1]247
248 If startIndex < 0 Then Return -1
[30]249 If count < 1 Or count + startIndex > m_Length Then Return -1
250 If length > m_Length Then Return -1
[1]251
252 If length = 0 Then Return startIndex
253
254 Dim i As Long, j As Long
255 For i = startIndex To startIndex + count - 1
256 For j = 0 To length - 1
[31]257 If Chars[i + j] = lpszText[j] Then
[1]258 If j = length - 1 Then Return i
259 Else
260 Exit For
261 End If
262 Next
263 Next
264 Return -1
265 End Function
266
[132]267 Const Function LastIndexOf(lpszText As *Char) As Long
[30]268 Return LastIndexOf(lpszText, m_Length - 1, m_Length)
[1]269 End Function
270
[132]271 Const Function LastIndexOf(lpszText As *Char, startIndex As Long) As Long
[119]272 Return LastIndexOf(lpszText As *Char, startIndex, startIndex + 1)
[1]273 End Function
274
[132]275 Const Function LastIndexOf(lpszText As *Char, startIndex As Long, count As Long) As Long
276 Dim length = lstrlen(lpszText)
[1]277
[30]278 If startIndex < 0 Or startIndex > m_Length - 1 Then Return -1
[1]279 If count < 1 Or count > startIndex + 2 Then Return -1
[30]280 If length > m_Length Then Return -1
[1]281
282 If length = 0 Then Return startIndex
283
284 Dim i As Long, j As Long
285 For i = startIndex To startIndex - count + 1 Step -1
286 For j = length - 1 To 0 Step -1
[31]287 If Chars[i + j] = lpszText[j] Then
[1]288 If j = 0 Then Return i
289 Else
290 Exit For
291 End If
292 Next
293 Next
294 Return -1
295 End Function
296
[132]297 Const Function StartsWith(lpszText As *Char) As Boolean
298 Return IndexOf(lpszText) = 0
[1]299 End Function
300
[132]301 Const Function EndsWith(lpszText As *Char) As Boolean
302 Return LastIndexOf(lpszText) = m_Length - lstrlen(lpszText)
[1]303 End Function
304
[132]305 Const Function Insert(startIndex As Long, text As String) As String
306 Return Insert(startIndex, text.Chars, text.Length)
307 End Function
[1]308
[132]309 Const Function Insert(startIndex As Long, text As *Char) As String
310 Return Insert(startIndex, text, lstrlen(text))
311 End Function
[1]312
[132]313 Const Function Insert(startIndex As Long, text As *Char, length As Long) As String
314 If startIndex < 0 Or startIndex > m_Length Or length < 0 Then
315 Debug 'ArgumentOutOfRangeException
[1]316
[132]317 End If
318 Insert.ReSize(m_Length + length)
319 memcpy(Insert.Chars, Chars, SizeOf (Char) * startIndex)
320 memcpy(VarPtr(Insert.Chars[startIndex]), text, SizeOf (Char) * length)
321 memcpy(VarPtr(Insert.Chars[startIndex + length]), VarPtr(Chars[startIndex]), SizeOf (Char) * (m_Length - startIndex + 1))
[1]322 End Function
323
[132]324 Const Function SubString(startIndex As Long) As String
[30]325 Return SubString(startIndex, m_Length - startIndex)
[1]326 End Function
327
[132]328 Const Function SubString(startIndex As Long, length As Long) As String
[1]329 If startIndex < 0 Or length <= 0 Then Return ""
[30]330 If startIndex + length > m_Length Then Return ""
[1]331
332 Dim temp As String
333 temp.AllocStringBuffer(length)
[121]334 memcpy(temp.Chars, VarPtr(Chars[startIndex]), SizeOf (Char) * length)
[31]335 Chars[m_Length] = 0
[1]336 Return temp
337 End Function
338
[132]339 Const Function Remove(startIndex As Long) As String
340 Remove.ReSize(startIndex)
341 memcpy(Remove.Chars, This.Chars, SizeOf (Char) * startIndex)
[1]342 End Function
343
[132]344 Const Function Remove(startIndex As Long, count As Long) As String
345 Remove.ReSize(m_Length - count)
346 memcpy(Remove.Chars, This.Chars, SizeOf (Char) * startIndex)
347 memcpy(VarPtr(Remove.Chars[startIndex]), VarPtr(This.Chars[startIndex + count]), SizeOf (Char) * startIndex)
348 End Function
349/*
350 Static Function IsNullOrEmpty(s As String) As Boolean
351 If s <> Nothing Then
352 If s.m_Length > 0 Then
353 Return True
354 End If
355 End If
356 Return False
357 End Function
358*/
359 Const Function Replace(oldChar As Char, newChar As Char) As String
360 Replace = Copy(This)
361 With Replace
362 Dim i As Long
363 For i = 0 To ELM(.m_Length)
364 If .Chars[i] = .oldChar Then
365 .Chars[i] = .newChar
366 End If
367 Next
368 End With
369 End Function
[1]370
[132]371 Const Function Replace(ByRef oldStr As String, ByRef newStr As String) As String
372' If oldStr = Nothing Then Throw ArgumentNullException
373'
374' If newStr = Nothing Then
375' Return ReplaceCore(oldStr, oldStr.m_Length, "", 0)
376' Else
377 Return ReplaceCore(oldStr, oldStr.m_Length, newStr, newStr.m_Length)
378' End If
379 End Function
[1]380
[132]381 Const Function Replace(oldStr As *Char, newStr As *Char)
382 If oldStr = 0 Then Debug 'Throw ArgumentNullException
383 If newStr = 0 Then newStr = ""
384 Return ReplaceCore(oldStr, lstrlen(oldStr), newStr, lstrlen(newStr)) As String
[1]385 End Function
386
[132]387 Const Function Replace(oldStr As *Char, oldLen As Long, newStr As *Char, newLen As Long) As String
388 If oldStr = 0 Then Debug 'Throw ArgumentNullException
389 If newStr = 0 Then
390 newStr = ""
391 newLen = 0
[1]392 End If
[132]393 Return ReplaceCore(oldStr, oldLen, newStr, newLen)
[1]394 End Function
395
[134]396 Const Function ToLower() As String
397 ToLower.ReSize(m_Length)
[125]398 Dim i As Long
[134]399 For i = 0 To ELM(m_Length)
400 ToLower.Chars[i] = _System_ASCII_ToLower(Chars[i])
[125]401 Next
[134]402 End Function
[1]403
[134]404 Const Function ToUpper() As String
405 ToUpper.ReSize(m_Length)
[125]406 Dim i As Long
[134]407 For i = 0 To ELM(m_Length)
408 ToUpper.Chars[i] = _System_ASCII_ToUpper(Chars[i])
[125]409 Next
[134]410 End Function
[1]411
412 Sub Swap(ByRef x As String)
413 Dim tempLen As Long
[132]414 Dim tempChars As *Char
[30]415 tempLen = x.m_Length
[31]416 tempChars = x.Chars
[30]417 x.m_Length = This.m_Length
[31]418 x.Chars = This.Chars
[30]419 This.m_Length = tempLen
[31]420 This.Chars = tempChars
[1]421 End Sub
422
[119]423 Override Function ToString() As String
424 Return This
425 End Function
426
[132]427 Static Function Copy(s As String) As String
428 Copy.Resize(s.m_Length)
429 memcpy(Copy.Chars, This.Chars, SizeOf (Char) * m_Length)
430 End Function
431
[1]432Private
433 ' メモリ確保に失敗すると元の文字列は失われない。(例外安全でいう強い保障)
[119]434 Function AllocStringBuffer(textLength As Long) As *Char
[1]435 If textLength < 0 Then
436 Return 0
[30]437 ElseIf textLength > m_Length Then
[121]438 AllocStringBuffer = _System_realloc(Chars, SizeOf(Char) * (textLength + 1))
[1]439 If AllocStringBuffer <> 0 Then
[30]440 m_Length = textLength
[31]441 Chars = AllocStringBuffer
[1]442 End If
443 Else
[30]444 m_Length = textLength
[31]445 AllocStringBuffer = Chars
[1]446 End If
447 End Function
448
[132]449 Function ReplaceCore(oldStr As *Char, oldLen As Long, newStr As *Char, newLen As Long) As String
450 If oldLen = 0 Then
451 Debug 'Throw ArgumentException
452 End If
453 Dim tmp As String
454 With tmp
455 Dim current = 0 As Long
456 Do
457 Dim pos = IndexOf(oldStr, current)
458 If pos = -1 Then
459 Exit Do
460 End If
461 .Append(VarPtr(Chars[current]), pos - current)
462 .Append(newStr, newLen)
463 current = pos + oldLen
464 Loop
465 .Append(VarPtr(Chars[current]), m_Length - current)
466 End With
467 Return tmp
468 End Function
469
[1]470End Class
471
Note: See TracBrowser for help on using the repository browser.