OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 patch class StringBuffer { | 5 patch class StringBuffer { |
6 List<String> _buffer; | 6 List<int> _buffer; |
7 int _length; | 7 int _length; |
8 | 8 |
9 /// Creates the string buffer with an initial content. | 9 /// Creates the string buffer with an initial content. |
10 /* patch */ StringBuffer([Object content = ""]) { | 10 /* patch */ StringBuffer([Object content = ""]) { |
11 _buffer = new List<String>(); | 11 _buffer = _newBuffer(16); |
12 _length = 0; | 12 _length = 0; |
13 write(content); | 13 write(content); |
14 } | 14 } |
15 | 15 |
16 /* patch */ int get length => _length; | 16 /* patch */ int get length => _length; |
17 | 17 |
18 /// Adds [obj] to the buffer. | 18 /// Adds [obj] to the buffer. |
19 /* patch */ void write(Object obj) { | 19 /* patch */ void write(Object obj) { |
20 // TODO(srdjan): The following four lines could be replaced by | |
21 // '$obj', but apparently this is too slow on the Dart VM. | |
22 String str; | 20 String str; |
23 if (obj is String) { | 21 if (obj is String) { |
24 str = obj; | 22 str = obj; |
25 } else { | 23 } else { |
24 // TODO(srdjan): The following four lines could be replaced by | |
25 // '$obj', but apparently this is too slow on the Dart VM. | |
26 str = obj.toString(); | 26 str = obj.toString(); |
27 if (str is! String) { | 27 if (str is! String) { |
28 throw new ArgumentError('toString() did not return a string'); | 28 throw new ArgumentError('toString() did not return a string'); |
29 } | 29 } |
30 } | 30 } |
31 if (str.isEmpty) return; | 31 if (str.isEmpty) return; |
32 _buffer.add(str); | 32 _ensureCapacity(str.length); |
33 for (int i = 0; i < str.length; i++) { | |
34 _buffer[_length + i] = str.codeUnitAt(i); | |
35 } | |
33 _length += str.length; | 36 _length += str.length; |
34 } | 37 } |
35 | 38 |
36 /// Clears the string buffer. | 39 /* patch */ writeCharCode(int charCode) { |
40 if (charCode < 0 || charCode > 0x10FFFF) { | |
41 throw new RangeError.range(charCode, 0, 0x10FFFF); | |
42 } | |
43 if (charCode <= 0xFFFF) { | |
44 _ensureCapacity(1); | |
45 _buffer[_length++] = charCode; | |
46 } else { | |
47 _ensureCapacity(2); | |
48 int bits = charCode - 0x10000; | |
49 _buffer[_length++] = 0xD800 | (bits >> 10); | |
50 _buffer[_length++] = 0xDC00 | (bits & 0x3FF); | |
51 } | |
52 } | |
53 | |
54 /** Makes the buffer empty. */ | |
37 /* patch */ void clear() { | 55 /* patch */ void clear() { |
38 _buffer = new List<String>(); | |
39 _length = 0; | 56 _length = 0; |
40 } | 57 } |
41 | 58 |
42 /// Returns the contents of buffer as a concatenated string. | 59 /** Returns the contents of buffer as a string. */ |
43 /* patch */ String toString() { | 60 /* patch */ String toString() { |
44 if (_buffer.length == 0) return ""; | 61 if (_length == 0) return ""; |
45 if (_buffer.length == 1) return _buffer[0]; | 62 return _create(_buffer, _length); |
46 String result = _StringBase.concatAll(_buffer); | |
47 _buffer.clear(); | |
48 _buffer.add(result); | |
49 // Since we track the length at each add operation, there is no | |
50 // need to update it in this function. | |
51 return result; | |
52 } | 63 } |
64 | |
65 /** Ensures that the buffer has enough capacity to contain n code units. */ | |
66 void _ensureCapacity(int n) { | |
67 int requiredCapacity = _length + n; | |
68 if (requiredCapacity <= _buffer.length) return; | |
69 int newCapacity = _buffer.length; | |
70 do { | |
71 newCapacity *= 2; | |
72 } while (newCapacity < requiredCapacity); | |
73 List<int> newBuffer = _newBuffer(newCapacity); | |
74 newBuffer.setRange(0, _length, _buffer); | |
75 _buffer = newBuffer; | |
76 } | |
77 | |
78 /** | |
79 * Create a [String] from the UFT-16 code units in buffer. | |
80 */ | |
81 static String _create(List<int> buffer, int length) | |
srdjan
2013/03/05 17:53:20
Also specify here Uint16List as well as the type o
| |
82 native "StringBuffer_createStringFromUint16Array"; | |
83 | |
84 /** | |
85 * Creates a Uint16Array, as the scalar list. | |
86 * | |
87 * Used as a native here to avoid importing scalar lists. | |
88 */ | |
89 static _Uint16Array _newBuffer(int length) native "Uint16Array_new"; | |
srdjan
2013/03/05 16:02:21
Why not use "new Uint16List" instead of _newBuffer
Lasse Reichstein Nielsen
2013/03/05 16:56:56
It would require dart:core to import dart:scalarli
Ivan Posva
2013/03/05 17:50:55
It would not increase the footprint of the VM as b
| |
53 } | 90 } |
OLD | NEW |