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

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

String型の自身を変更するメソッドを、戻り値で返すように変更。
併せて文字列比較を自前の関数で行うように変更。
プロンプトのキャレットの位置計算が正しくなかったバグを修正。

File size: 12.2 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
396 Sub ToLower()
[125]397 Dim i As Long
398 For i = 0 To m_Length
399 Chars[i] = _System_ASCII_ToLower(Chars[i])
400 Next
[1]401 End Sub
402
403 Sub ToUpper()
[125]404 Dim i As Long
405 For i = 0 To m_Length
406 Chars[i] = _System_ASCII_ToUpper(Chars[i])
407 Next
[1]408 End Sub
409
410 Sub Swap(ByRef x As String)
411 Dim tempLen As Long
[132]412 Dim tempChars As *Char
[30]413 tempLen = x.m_Length
[31]414 tempChars = x.Chars
[30]415 x.m_Length = This.m_Length
[31]416 x.Chars = This.Chars
[30]417 This.m_Length = tempLen
[31]418 This.Chars = tempChars
[1]419 End Sub
420
[119]421 Override Function ToString() As String
422 Return This
423 End Function
424
[132]425 Static Function Copy(s As String) As String
426 Copy.Resize(s.m_Length)
427 memcpy(Copy.Chars, This.Chars, SizeOf (Char) * m_Length)
428 End Function
429
[1]430Private
431 ' メモリ確保に失敗すると元の文字列は失われない。(例外安全でいう強い保障)
[119]432 Function AllocStringBuffer(textLength As Long) As *Char
[1]433 If textLength < 0 Then
434 Return 0
[30]435 ElseIf textLength > m_Length Then
[121]436 AllocStringBuffer = _System_realloc(Chars, SizeOf(Char) * (textLength + 1))
[1]437 If AllocStringBuffer <> 0 Then
[30]438 m_Length = textLength
[31]439 Chars = AllocStringBuffer
[1]440 End If
441 Else
[30]442 m_Length = textLength
[31]443 AllocStringBuffer = Chars
[1]444 End If
445 End Function
446
[132]447 Function ReplaceCore(oldStr As *Char, oldLen As Long, newStr As *Char, newLen As Long) As String
448 If oldLen = 0 Then
449 Debug 'Throw ArgumentException
450 End If
451 Dim tmp As String
452 With tmp
453 Dim current = 0 As Long
454 Do
455 Dim pos = IndexOf(oldStr, current)
456 If pos = -1 Then
457 Exit Do
458 End If
459 .Append(VarPtr(Chars[current]), pos - current)
460 .Append(newStr, newLen)
461 current = pos + oldLen
462 Loop
463 .Append(VarPtr(Chars[current]), m_Length - current)
464 End With
465 Return tmp
466 End Function
467
[1]468End Class
469
Note: See TracBrowser for help on using the repository browser.