source: trunk/Include/Classes/System/Text/StringBuilder.ab@ 383

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

SPrintf関数の実装

File size: 13.8 KB
RevLine 
[272]1'Classes/System/Text/StringBuilder.ab
2
3#require <Classes/ActiveBasic/Strings/Strings.ab>
4
5Namespace System
6Namespace Text
7
8Class StringBuilder
9 'Inherits ISerializable
10Public
11 Sub StringBuilder()
12 initialize(1024)
13 End Sub
14
15 Sub StringBuilder(capacity As Long)
16 initialize(capacity)
17 End Sub
18
19 Sub StringBuilder(s As String)
20 initialize(s, 0, s.Length, s.Length * 2)
21 End Sub
22
23 Sub StringBuilder(capacity As Long, maxCapacity As Long)
24 initialize(capacity, maxCapacity)
25 End Sub
26
27 Sub StringBuilder(s As String, capacity As Long)
28 initialize(s, 0, s.Length, capacity)
29 End Sub
30
31 Sub StringBuilder(s As String, startIndex As Long, length As Long, capacity As Long)
32 initialize(s, startIndex, length, capacity)
33 End Sub
34
35 'Methods
36
37 Function Append(x As Boolean) As StringBuilder
38 Append(Str$(x))
39 Return This
40 End Function
41
42 Function Append(x As StrChar) As StringBuilder
43 EnsureCapacity(size + 1)
44 separateBuffer()
45 chars[size] = x
46 size++
47 Return This
48 End Function
49
50#ifdef __STRING_IS_NOT_UNICODE
51 Function Append(x As Word) As StringBuilder
52 Append(Str$(x As DWord))
53 Return This
54 End Function
55#else
56 Function Append(x As SByte) As StringBuilder
57 Append(Str$(x As Long))
58 Return This
59 End Function
60#endif
61
62 Function Append(x As Byte) As StringBuilder
63 Append(Str$(x As DWord))
64 Return This
65 End Function
66
67 Function Append(x As Integer) As StringBuilder
68 Append(Str$(x As Long))
69 Return This
70 End Function
71
72 Function Append(x As Long) As StringBuilder
73 Append(Str$(x))
74 Return This
75 End Function
76
77 Function Append(x As DWord) As StringBuilder
78 Append(Str$(x))
79 Return This
80 End Function
81
82 Function Append(x As Int64) As StringBuilder
83 Append(Str$(x))
84 Return This
85 End Function
86
87 Function Append(x As QWord) As StringBuilder
88 Append(Str$(x))
89 Return This
90 End Function
91
92 Function Append(x As Single) As StringBuilder
93 Append(Str$(x))
94 Return This
95 End Function
96
97 Function Append(x As Double) As StringBuilder
98 Append(Str$(x))
99 Return This
100 End Function
101
102 Function Append(x As Object) As StringBuilder
103 Append(x.ToString)
104 Return This
105 End Function
106
107 Function Append(c As StrChar, n As Long) As StringBuilder
108 EnsureCapacity(size + n)
109 ActiveBasic.Strings.ChrFill(VarPtr(chars[size]), n As SIZE_T, c)
110 size += n
111 Return This
112 End Function
113
114 Function Append(s As String) As StringBuilder
115 If Not String.IsNullOrEmpty(s) Then
116 appendCore(s, 0, s.Length)
117 End If
118 Return This
119 End Function
120
121 Function Append(s As String, startIndex As Long, count As Long) As StringBuilder
122 If s = 0 Then
123 If startIndex = 0 And count = 0 Then
124 Return This
125 Else
126 'Throw ArgumentNullException
127 End If
128 End If
129 StringBuilder.rangeCheck2(s.Length, startIndex, count)
130 appendCore(s, startIndex, count)
131 Return This
132 End Function
133
134 Function Append(s As *StrChar, startIndex As Long, count As Long) As StringBuilder
135 If s = 0 Then
136 If startIndex = 0 And count = 0 Then
137 Return This
138 Else
139 'Throw ArgumentNullException
140 End If
141 ElseIf startIndex < 0 Or count < 0 Then
142 'Throw ArgumentOutOfRangeException
143 End If
144 appendCore(s, startIndex, count)
145 Return This
146 End Function
147Private
148 Sub appendCore(s As *StrChar, start As Long, count As Long)
149 EnsureCapacity(size + count)
150 separateBuffer()
151 ActiveBasic.Strings.ChrCopy(VarPtr(chars[size]), VarPtr(s[start]), count As SIZE_T)
152 size += count
153 End Sub
154
155 Sub appendCore(s As String, start As Long, count As Long)
156 EnsureCapacity(size + count)
157 separateBuffer()
158 s.CopyTo(start, chars, size, count)
159 size += count
160 End Sub
161Public
162 'AppendFormat
163
164 Function AppendLine() As StringBuilder
165 separateBuffer()
166 Append(Environment.NewLine)
167 Return This
168 End Function
169
170 Function AppendLine(s As String) As StringBuilder
171 EnsureCapacity(Capacity + s.Length + Environment.NewLine.Length)
172 separateBuffer()
173 Append(s)
174 Append(Environment.NewLine)
175 Return This
176 End Function
177
178 Const Sub CopyTo(sourceIndex As Long, ByRef dest[] As StrChar, destIndex As Long, count As Long)
179 If dest = 0 Then
180 'Throw ArgumentNullException
181 ElseIf size < sourceIndex + count Or sourceIndex < 0 Or destIndex < 0 Or count < 0 Then
182 'Throw ArgumentOutOfRangeException
183 End If
184
185 memcpy(VarPtr(dest[destIndex]), VarPtr(chars[sourceIndex]), count * SizeOf (StrChar))
186 End Sub
187
188 Function EnsureCapacity(c As Long) As Long
189 If c < 0 Or c > MaxCapacity Then
190 'Throw ArgumentOutOfRangeException
191 ElseIf c > Capacity Then
192 Dim p = GC_malloc_atomic((c + 1) * SizeOf (StrChar)) As *StrChar
193 If p = 0 Then
194 'Throw OutOfMemoryException
195 Debug
196 End If
197 ActiveBasic.Strings.ChrCopy(p, chars, size As SIZE_T)
198 chars = p
199 capacity = c
200 stringized = False
201 End If
202 End Function
203
204 'Override Function Equals(o As Object) As Boolean
205
206 Const Function Equals(s As StringBuilder) As Boolean
207 Return ActiveBasic.Strings.StrCmp(chars, s.chars) = 0 _
208 And capacity = s.capacity _
209 And maxCapacity = s.maxCapacity
210 End Function
211
212 Override Function GetHashCode() As Long
213#ifdef __STRING_IS_NOT_UNICODE
214 Dim n = (size + 1) >> 1
215#else
216 Dim n = size
217#endif
218 Return _System_GetHashFromWordArray(chars As *Word, n As SIZE_T) Xor capacity Xor maxCapacity
219 End Function
220
221 Function Insert(i As Long, x As Boolean) As StringBuilder
222 rangeCheck(i)
223 insertCore(i, Str$(x))
224 Return This
225 End Function
226
227 Function Insert(i As Long, x As StrChar) As StringBuilder
228 Insert(i, VarPtr(x), 0, 1)
229 Return This
230 End Function
231#ifdef __STRING_IS_NOT_UNICODE
232 Function Insert(i As Long, x As Word) As StringBuilder
233 rangeCheck(i)
234 insertCore(i, Str$(x As DWord))
235 Return This
236 End Function
237#else
238 Function Insert(i As Long, x As SByte) As StringBuilder
239 rangeCheck(i)
240 insertCore(i, Str$(x As Long))
241 Return This
242 End Function
243#endif
244
245 Function Insert(i As Long, x As Byte) As StringBuilder
246 rangeCheck(i)
247 insertCore(i, Str$(x))
248 Return This
249 End Function
250
251 Function Insert(i As Long, x As Integer) As StringBuilder
252 rangeCheck(i)
253 insertCore(i, Str$(x))
254 Return This
255 End Function
256
257 Function Insert(i As Long, x As Long) As StringBuilder
258 rangeCheck(i)
259 insertCore(i, Str$(x))
260 Return This
261 End Function
262
263 Function Insert(i As Long, x As DWord) As StringBuilder
264 rangeCheck(i)
265 insertCore(i, Str$(x))
266 Return This
267 End Function
268
269 Function Insert(i As Long, x As Int64) As StringBuilder
270 rangeCheck(i)
271 insertCore(i, Str$(x))
272 Return This
273 End Function
274
275 Function Insert(i As Long, x As Single) As StringBuilder
276 rangeCheck(i)
277 insertCore(i, Str$(x))
278 Return This
279 End Function
280
281 Function Insert(i As Long, x As Double) As StringBuilder
282 rangeCheck(i)
283 insertCore(i, Str$(x))
284 Return This
285 End Function
286
287 Function Insert(i As Long, s As String) As StringBuilder
288 rangeCheck(i)
289 insertCore(i, s)
290 Return This
291 End Function
292
293 Function Insert(i As Long, o As Object) As StringBuilder
294 rangeCheck(i)
295 insertCore(i, o.ToString)
296 Return This
297 End Function
298
299 Function Insert(index As Long, x As String, n As Long) As StringBuilder
300 rangeCheck(index)
301 If n < 0 Then
302 'Throw New ArgumentOutOfRangeException
303 Debug
304 End If
305 Dim len = x.Length
306 Dim lenTotal = len * n
307 Dim newSize = size + lenTotal
308 EnsureCapacity(newSize)
309 separateBuffer()
[288]310
311 ' TODO: fix me!(定義されていない変数iが使われています)
312 'ActiveBasic.Strings.ChrMove(VarPtr(chars[i + lenTotal]), VarPtr(chars[i]), (size - index) As SIZE_T)
313
[272]314 Dim i As Long
315 For i = 0 To ELM(n)
316 x.CopyTo(0, chars, size + i * len, len)
317 Next
318 size = newSize
319 Return This
320 End Function
321
322
323 Function Insert(i As Long, x As *StrChar, index As Long, count As Long) As StringBuilder
324 rangeCheck(i)
325 If x = 0 Then
326 'Throw New ArgumentNullException
327 Debug
328 ElseIf index < 0 Or count < 0 Then
329 'Throw New ArgumentNullException
330 Debug
331 End If
332
333 Dim newSize = size + count
334 EnsureCapacity(newSize)
335 separateBuffer()
336 ActiveBasic.Strings.ChrMove(VarPtr(chars[i + count]), VarPtr(chars[i]), (size - i) As SIZE_T)
337 ActiveBasic.Strings.ChrCopy(VarPtr(chars[i]), VarPtr(x[index]), count As SIZE_T)
338 size = newSize
339 Return This
340 End Function
341
342Private
343 Sub insertCore(i As Long, s As String)
344 Dim newSize = size + s.Length
345 EnsureCapacity(newSize)
346 separateBuffer()
347 ActiveBasic.Strings.ChrMove(VarPtr(chars[i + s.Length]), VarPtr(chars[i]), (size - i) As SIZE_T)
348 s.CopyTo(0, chars, i, s.Length)
349 size = newSize
350 End Sub
351Public
352
353 Function Remove(startIndex As Long, length As Long) As StringBuilder
354 rangeCheck(startIndex, length)
355 separateBuffer()
356
357 Dim moveStart = startIndex + length
358 ActiveBasic.Strings.ChrMove(
359 VarPtr(chars[startIndex]), VarPtr(chars[moveStart]), (size - moveStart) As SIZE_T)
360 size -= length
361 Return This
362 End Function
363
364 Function Replace(oldChar As StrChar, newChar As StrChar) As StringBuilder
365 replaceCore(oldChar, newChar, 0, size)
366 Return This
367 End Function
368
369 Function Replace(oldStr As String, newStr As String) As StringBuilder
370 replaceCore(oldStr, newStr, 0, size)
371 Return This
372 End Function
373
374 Function Replace(oldChar As StrChar, newChar As StrChar, startIndex As Long, count As Long) As StringBuilder
375 rangeCheck(startIndex, count)
376 replaceCore(oldChar, newChar, startIndex, count)
377 Return This
378 End Function
379
380 Function Replace(oldStr As String, newStr As String, startIndex As Long, count As Long) As StringBuilder
381 rangeCheck(startIndex, count)
382 replaceCore(oldStr, newStr, startIndex, count)
383 Return This
384 End Function
385Private
386 Sub replaceCore(oldChar As StrChar, newChar As StrChar, start As Long, count As Long)
387 separateBuffer()
388 Dim i As Long
389 Dim last = ELM(start + count)
390 For i = start To last
391 If chars[i] = oldChar Then
392 chars[i] = newChar
393 End If
394 Next
395 End Sub
396
397 Sub replaceCore(oldStr As String, newStr As String, start As Long, count As Long)
398 If Object.ReferenceEquals(oldStr, Nothing) Then
399 'Throw ArgumentNullException
400 Debug
401 ElseIf oldStr.Length = 0 Then
402 'Throw ArgumentException
403 Debug
404 End If
405
406 Dim s = New StringBuilder(capacity, maxCapacity)
407 Dim curPos = 0 As Long
408 Do
[370]409 Dim nextPos = ActiveBasic.Strings.ChrFind(VarPtr(chars[curPos]) As *StrChar, size As SIZE_T, StrPtr(oldStr), oldStr.Length As SIZE_T) As Long
[272]410 If nextPos = -1 As SIZE_T Then
411 Exit Sub
412 End If
413
414 s.appendCore(chars, curPos, nextPos)
415 s.Append(newStr)
416 curPos += nextPos + oldStr.Length
417 Loop
418 chars = s.chars
419 size = s.size
420 End Sub
421
422Public
423 Override Function ToString() As String
424 chars[size] = 0
425 Return New String(This)
426 End Function
427
428 Const Function ToString(startIndex As Long, length As Long) As String
429 rangeCheck(startIndex, length)
430 Return New String(chars, startIndex, length)
431 End Function
432
433 Const Function Operator [](i As Long) As StrChar
434 Return Chars[i]
435 End Function
436
437 Sub Operator []=(i As Long, c As StrChar)
438 Chars[i] = c
439 End Sub
440
441 'Properties
442 Const Function Capacity() As Long
443 Return capacity
444 End Function
445
446 Sub Capacity(c As Long)
447 If c < size Or c > MaxCapacity Then 'sizeとの比較でcが負の場合も対応
448 'Throw ArgumentOutOfRangeException
449 End If
450 EnsureCapacity(c)
451 End Sub
452
453 Const Function Chars(i As Long) As StrChar
454 If i >= Length Or i < 0 Then
455 'Throw IndexOutOfRangeException
456 Debug
457 End If
458 Return chars[i]
459 End Function
460
461 Sub Chars(i As Long, c As StrChar)
462 If i >= Length Or i < 0 Then
463 'Throw ArgumentOutOfRangeException
464 Debug
465 End If
466 chars[i] = c
467 End Sub
468
469 Const Function Length() As Long
470 Return size
471 End Function
472
473 Sub Length(i As Long)
474 EnsureCapacity(i) 'iが適切な値かどうかの確認はこの中で行う
475 If size < i Then
476 ActiveBasic.Strings.ChrFill(VarPtr(chars[size]), (i - size + 1) As SIZE_T, 0 As StrChar)
477 End If
478 size = i
479 End Sub
480
481 Const Function MaxCapacity() As Long
482 Return maxCapacity
483 End Function
484
485 Function __Chars() As *StrChar
486 Return chars
487 End Function
488
489 Sub __Stringized()
490 stringized = True
491 End Sub
492
493Private
494 Sub initialize(capacity As Long, maxCapacity = LONG_MAX As Long)
495 If capacity < 0 Or maxCapacity < 1 Or maxCapacity < capacity Then
496 'Throw ArgumentOutOfRangeException
497 End If
498
499 If capacity = 0 Then
500 This.capacity = 1024
501 Else
502 This.capacity = capacity
503 End If
504
505 This.maxCapacity = maxCapacity
506 This.size = 0
507 This.chars = GC_malloc_atomic((This.capacity + 1) * SizeOf (StrChar))
508 If chars = 0 Then
509 'Throw OutOfMemoryException
510 Debug
511 End If
512
513 End Sub
514
515 Sub initialize(s As String, startIndex As Long, length As Long, capacity As Long, maxCapacity = LONG_MAX As Long)
516 StringBuilder.rangeCheck2(s.Length, startIndex, length)
517
518 initialize(Math.Max(capacity, length), maxCapacity)
519
520 If Not String.IsNullOrEmpty(s) Then
521 s.CopyTo(startIndex, chars, 0, length)
[383]522 size = length
[272]523 End If
524 End Sub
525
526 Sub rangeCheck(index As Long)
527 If index < 0 Or index > size Then
528 'Throw ArgumentOutOfRangeException
529 Debug
530 End If
531 End Sub
532
533 Sub rangeCheck(startIndex As Long, count As Long)
534 StringBuilder.rangeCheck2(size, startIndex, count)
535 End Sub
536
537 Static Sub rangeCheck2(length As Long, startIndex As Long, count As Long)
538 'length < 0は判定に入っていないことに注意
539 If startIndex < 0 Or count < 0 Or startIndex + count > length Then
540 'Throw ArgumentOutOfRangeException
541 Debug
542 End If
543 End Sub
544
545 Sub separateBuffer()
546 If stringized Then
547 Dim newChars = GC_malloc_atomic(SizeOf (StrChar) * capacity) As *StrChar
548 ActiveBasic.Strings.ChrCopy(newChars, chars, capacity As SIZE_T)
549 chars = newChars
550 stringized = False
551 End If
552 End Sub
553
554 chars As *StrChar
555 maxCapacity As Long
556 capacity As Long
557 size As Long
558 stringized As Boolean
559End Class
560
561End Namespace 'Text
562End Namespace 'System
563
564'暫定
565Function StrPtr(sb As System.Text.StringBuilder) As *StrChar
566 Return sb.__Chars
567End Function
Note: See TracBrowser for help on using the repository browser.