| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file |  | 
| 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. |  | 
| 4 |  | 
| 5 // This is a copy of "dart:io"'s BytesBuilder implementation, from |  | 
| 6 // sdk/lib/io/bytes_builder.dart. It's copied here to make it available to |  | 
| 7 // non-"dart:io" applications (issue 18348). |  | 
| 8 // |  | 
| 9 // Because it's copied directly, there are no modifications from the original. |  | 
| 10 library http_parser.bytes_builder; |  | 
| 11 |  | 
| 12 import 'dart:math'; |  | 
| 13 import 'dart:typed_data'; |  | 
| 14 |  | 
| 15 /** |  | 
| 16  * Builds a list of bytes, allowing bytes and lists of bytes to be added at the |  | 
| 17  * end. |  | 
| 18  * |  | 
| 19  * Used to efficiently collect bytes and lists of bytes. |  | 
| 20  */ |  | 
| 21 abstract class BytesBuilder { |  | 
| 22   /** |  | 
| 23    * Construct a new empty [BytesBuilder]. |  | 
| 24    * |  | 
| 25    * If [copy] is true, the data is always copied when added to the list. If |  | 
| 26    * it [copy] is false, the data is only copied if needed. That means that if |  | 
| 27    * the lists are changed after added to the [BytesBuilder], it may effect the |  | 
| 28    * output. Default is `true`. |  | 
| 29    */ |  | 
| 30   factory BytesBuilder({bool copy: true}) { |  | 
| 31     if (copy) { |  | 
| 32       return new _CopyingBytesBuilder(); |  | 
| 33     } else { |  | 
| 34       return new _BytesBuilder(); |  | 
| 35     } |  | 
| 36   } |  | 
| 37 |  | 
| 38   /** |  | 
| 39    * Appends [bytes] to the current contents of the builder. |  | 
| 40    * |  | 
| 41    * Each value of [bytes] will be bit-representation truncated to the range |  | 
| 42    * 0 .. 255. |  | 
| 43    */ |  | 
| 44   void add(List<int> bytes); |  | 
| 45 |  | 
| 46   /** |  | 
| 47    * Append [byte] to the current contents of the builder. |  | 
| 48    * |  | 
| 49    * The [byte] will be bit-representation truncated to the range 0 .. 255. |  | 
| 50    */ |  | 
| 51   void addByte(int byte); |  | 
| 52 |  | 
| 53   /** |  | 
| 54    * Returns the contents of `this` and clears `this`. |  | 
| 55    * |  | 
| 56    * The list returned is a view of the the internal buffer, limited to the |  | 
| 57    * [length]. |  | 
| 58    */ |  | 
| 59   List<int> takeBytes(); |  | 
| 60 |  | 
| 61   /** |  | 
| 62    * Returns a copy of the current contents of the builder. |  | 
| 63    * |  | 
| 64    * Leaves the contents of the builder intact. |  | 
| 65    */ |  | 
| 66   List<int> toBytes(); |  | 
| 67 |  | 
| 68   /** |  | 
| 69    * The number of bytes in the builder. |  | 
| 70    */ |  | 
| 71   int get length; |  | 
| 72 |  | 
| 73   /** |  | 
| 74    * Returns `true` if the buffer is empty. |  | 
| 75    */ |  | 
| 76   bool get isEmpty; |  | 
| 77 |  | 
| 78   /** |  | 
| 79    * Returns `true` if the buffer is not empty. |  | 
| 80    */ |  | 
| 81   bool get isNotEmpty; |  | 
| 82 |  | 
| 83   /** |  | 
| 84    * Clear the contents of the builder. |  | 
| 85    */ |  | 
| 86   void clear(); |  | 
| 87 } |  | 
| 88 |  | 
| 89 class _CopyingBytesBuilder implements BytesBuilder { |  | 
| 90   // Start with 1024 bytes. |  | 
| 91   static const int _INIT_SIZE = 1024; |  | 
| 92 |  | 
| 93   int _length = 0; |  | 
| 94   Uint8List _buffer; |  | 
| 95 |  | 
| 96   void add(List<int> bytes) { |  | 
| 97     int bytesLength = bytes.length; |  | 
| 98     if (bytesLength == 0) return; |  | 
| 99     int required = _length + bytesLength; |  | 
| 100     if (_buffer == null) { |  | 
| 101       int size = _pow2roundup(required); |  | 
| 102       size = max(size, _INIT_SIZE); |  | 
| 103       _buffer = new Uint8List(size); |  | 
| 104     } else if (_buffer.length < required) { |  | 
| 105       // We will create a list in the range of 2-4 times larger than |  | 
| 106       // required. |  | 
| 107       int size = _pow2roundup(required) * 2; |  | 
| 108       var newBuffer = new Uint8List(size); |  | 
| 109       newBuffer.setRange(0, _buffer.length, _buffer); |  | 
| 110       _buffer = newBuffer; |  | 
| 111     } |  | 
| 112     assert(_buffer.length >= required); |  | 
| 113     if (bytes is Uint8List) { |  | 
| 114       _buffer.setRange(_length, required, bytes); |  | 
| 115     } else { |  | 
| 116       for (int i = 0; i < bytesLength; i++) { |  | 
| 117         _buffer[_length + i] = bytes[i]; |  | 
| 118       } |  | 
| 119     } |  | 
| 120     _length = required; |  | 
| 121   } |  | 
| 122 |  | 
| 123   void addByte(int byte) => add([byte]); |  | 
| 124 |  | 
| 125   List<int> takeBytes() { |  | 
| 126     if (_buffer == null) return new Uint8List(0); |  | 
| 127     var buffer = new Uint8List.view(_buffer.buffer, 0, _length); |  | 
| 128     clear(); |  | 
| 129     return buffer; |  | 
| 130   } |  | 
| 131 |  | 
| 132   List<int> toBytes() { |  | 
| 133     if (_buffer == null) return new Uint8List(0); |  | 
| 134     return new Uint8List.fromList( |  | 
| 135         new Uint8List.view(_buffer.buffer, 0, _length)); |  | 
| 136   } |  | 
| 137 |  | 
| 138   int get length => _length; |  | 
| 139 |  | 
| 140   bool get isEmpty => _length == 0; |  | 
| 141 |  | 
| 142   bool get isNotEmpty => _length != 0; |  | 
| 143 |  | 
| 144   void clear() { |  | 
| 145     _length = 0; |  | 
| 146     _buffer = null; |  | 
| 147   } |  | 
| 148 |  | 
| 149   int _pow2roundup(int x) { |  | 
| 150     --x; |  | 
| 151     x |= x >> 1; |  | 
| 152     x |= x >> 2; |  | 
| 153     x |= x >> 4; |  | 
| 154     x |= x >> 8; |  | 
| 155     x |= x >> 16; |  | 
| 156     return x + 1; |  | 
| 157   } |  | 
| 158 } |  | 
| 159 |  | 
| 160 class _BytesBuilder implements BytesBuilder { |  | 
| 161   int _length = 0; |  | 
| 162   final List _chunks = []; |  | 
| 163 |  | 
| 164   void add(List<int> bytes) { |  | 
| 165     if (bytes is! Uint8List) { |  | 
| 166       bytes = new Uint8List.fromList(bytes); |  | 
| 167     } |  | 
| 168     _chunks.add(bytes); |  | 
| 169     _length += bytes.length; |  | 
| 170   } |  | 
| 171 |  | 
| 172   void addByte(int byte) => add([byte]); |  | 
| 173 |  | 
| 174   List<int> takeBytes() { |  | 
| 175     if (_chunks.length == 0) return new Uint8List(0); |  | 
| 176     if (_chunks.length == 1) { |  | 
| 177       var buffer = _chunks.single; |  | 
| 178       clear(); |  | 
| 179       return buffer; |  | 
| 180     } |  | 
| 181     var buffer = new Uint8List(_length); |  | 
| 182     int offset = 0; |  | 
| 183     for (var chunk in _chunks) { |  | 
| 184       buffer.setRange(offset, offset + chunk.length, chunk); |  | 
| 185       offset += chunk.length; |  | 
| 186     } |  | 
| 187     clear(); |  | 
| 188     return buffer; |  | 
| 189   } |  | 
| 190 |  | 
| 191   List<int> toBytes() { |  | 
| 192     if (_chunks.length == 0) return new Uint8List(0); |  | 
| 193     var buffer = new Uint8List(_length); |  | 
| 194     int offset = 0; |  | 
| 195     for (var chunk in _chunks) { |  | 
| 196       buffer.setRange(offset, offset + chunk.length, chunk); |  | 
| 197       offset += chunk.length; |  | 
| 198     } |  | 
| 199     return buffer; |  | 
| 200   } |  | 
| 201 |  | 
| 202   int get length => _length; |  | 
| 203 |  | 
| 204   bool get isEmpty => _length == 0; |  | 
| 205 |  | 
| 206   bool get isNotEmpty => _length != 0; |  | 
| 207 |  | 
| 208   void clear() { |  | 
| 209     _length = 0; |  | 
| 210     _chunks.clear(); |  | 
| 211   } |  | 
| 212 } |  | 
| OLD | NEW | 
|---|