Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1232)

Unified Diff: sdk/lib/io/bytes_builder.dart

Issue 218493012: Make non-copying version of BytesBuidler and make file-reads faster. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/builtin.dart ('k') | sdk/lib/io/data_transformer.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/io/bytes_builder.dart
diff --git a/sdk/lib/io/bytes_builder.dart b/sdk/lib/io/bytes_builder.dart
index e26ae89cb9b158b71f8d7e50fecd62707120e225..610c50a74638e5c8d1ab3844f8522c16814ae9a3 100644
--- a/sdk/lib/io/bytes_builder.dart
+++ b/sdk/lib/io/bytes_builder.dart
@@ -8,20 +8,24 @@ part of dart.io;
* Builds a list of bytes, allowing bytes and lists of bytes to be added at the
* end.
*
- * Used to efficiently collect bytes and lists of bytes, using an internal
- * buffer. Note that it's optimized for IO, using an initial buffer of 1K bytes.
+ * Used to efficiently collect bytes and lists of bytes.
*/
-class BytesBuilder {
- // Start with 1024 bytes.
- static const int _INIT_SIZE = 1024;
-
- int _length = 0;
- Uint8List _buffer;
-
+abstract class BytesBuilder {
/**
* Construct a new empty [BytesBuilder].
+ *
+ * If [copy] is true, the data is always copied when added to the list. If
+ * it [copy] is false, the data is only copied if needed. That means that if
+ * the lists are changed after added to the [BytesBuilder], it may effect the
+ * output. Default is `true`.
*/
- BytesBuilder();
+ factory BytesBuilder({bool copy: true}) {
+ if (copy) {
+ return new _CopyingBytesBuilder();
+ } else {
+ return new _BytesBuilder();
+ }
+ }
/**
* Appends [bytes] to the current contents of the builder.
@@ -29,6 +33,59 @@ class BytesBuilder {
* Each value of [bytes] will be bit-representation truncated to the range
* 0 .. 255.
*/
+ void add(List<int> bytes);
+
+ /**
+ * Append [byte] to the current contents of the builder.
+ *
+ * The [byte] will be bit-representation truncated to the range 0 .. 255.
+ */
+ void addByte(int byte);
+
+ /**
+ * Returns the contents of `this` and clears `this`.
+ *
+ * The list returned is a view of the the internal buffer, limited to the
+ * [length].
+ */
+ List<int> takeBytes();
+
+ /**
+ * Returns a copy of the current contents of the builder.
+ *
+ * Leaves the contents of the builder intact.
+ */
+ List<int> toBytes();
+
+ /**
+ * The number of bytes in the builder.
+ */
+ int get length;
+
+ /**
+ * Returns `true` if the buffer is empty.
+ */
+ bool get isEmpty;
+
+ /**
+ * Returns `true` if the buffer is not empty.
+ */
+ bool get isNotEmpty;
+
+ /**
+ * Clear the contents of the builder.
+ */
+ void clear();
+}
+
+
+class _CopyingBytesBuilder implements BytesBuilder {
+ // Start with 1024 bytes.
+ static const int _INIT_SIZE = 1024;
+
+ int _length = 0;
+ Uint8List _buffer;
+
void add(List<int> bytes) {
int bytesLength = bytes.length;
if (bytesLength == 0) return;
@@ -56,19 +113,8 @@ class BytesBuilder {
_length = required;
}
- /**
- * Append [byte] to the current contents of the builder.
- *
- * The [byte] will be bit-representation truncated to the range 0 .. 255.
- */
void addByte(int byte) => add([byte]);
- /**
- * Returns the contents of `this` and clears `this`.
- *
- * The list returned is a view of the the internal buffer, limited to the
- * [length].
- */
List<int> takeBytes() {
if (_buffer == null) return new Uint8List(0);
var buffer = new Uint8List.view(_buffer.buffer, 0, _length);
@@ -76,35 +122,18 @@ class BytesBuilder {
return buffer;
}
- /**
- * Returns a copy of the current contents of the builder.
- *
- * Leaves the contents of the builder intact.
- */
List<int> toBytes() {
if (_buffer == null) return new Uint8List(0);
return new Uint8List.fromList(
new Uint8List.view(_buffer.buffer, 0, _length));
}
- /**
- * The number of bytes in the builder.
- */
int get length => _length;
- /**
- * Returns `true` if the buffer is empty.
- */
bool get isEmpty => _length == 0;
- /**
- * Returns `true` if the buffer is not empty.
- */
bool get isNotEmpty => _length != 0;
- /**
- * Clear the contents of the builder.
- */
void clear() {
_length = 0;
_buffer = null;
@@ -120,3 +149,58 @@ class BytesBuilder {
return x + 1;
}
}
+
+
+class _BytesBuilder implements BytesBuilder {
+ int _length = 0;
+ final List _chunks = [];
+
+ void add(List<int> bytes) {
+ if (bytes is! Uint8List) {
+ bytes = new Uint8List.fromList(bytes);
+ }
+ _chunks.add(bytes);
+ _length += bytes.length;
+ }
+
+ void addByte(int byte) => add([byte]);
+
+ List<int> takeBytes() {
+ if (_chunks.length == 0) return new Uint8List(0);
+ if (_chunks.length == 1) {
+ var buffer = _chunks.single;
+ clear();
+ return buffer;
+ }
+ var buffer = new Uint8List(_length);
+ int offset = 0;
+ for (var chunk in _chunks) {
+ buffer.setRange(offset, offset + chunk.length, chunk);
+ offset += chunk.length;
+ }
+ clear();
+ return buffer;
+ }
+
+ List<int> toBytes() {
+ if (_chunks.length == 0) return new Uint8List(0);
+ var buffer = new Uint8List(_length);
+ int offset = 0;
+ for (var chunk in _chunks) {
+ buffer.setRange(offset, offset + chunk.length, chunk);
+ offset += chunk.length;
+ }
+ return buffer;
+ }
+
+ int get length => _length;
+
+ bool get isEmpty => _length == 0;
+
+ bool get isNotEmpty => _length != 0;
+
+ void clear() {
+ _length = 0;
+ _chunks.clear();
+ }
+}
« no previous file with comments | « runtime/bin/builtin.dart ('k') | sdk/lib/io/data_transformer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698