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) |
| 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"; |
53 } | 90 } |
OLD | NEW |