| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * Utility class that holds a number of byte buffers and can deliver | |
| 7 * the bytes either one by one or in chunks. | |
| 8 */ | |
| 9 class _BufferList { | |
| 10 _BufferList() { | |
| 11 clear(); | |
| 12 } | |
| 13 | |
| 14 /** | |
| 15 * Adds a new buffer to the list possibly with an offset of the | |
| 16 * first byte of interest. The offset can only be specified if the | |
| 17 * buffer list is empty. | |
| 18 */ | |
| 19 void add(List<int> buffer, [int offset = 0]) { | |
| 20 assert(offset == 0 || _buffers.isEmpty); | |
| 21 _buffers.addLast(buffer); | |
| 22 _length += buffer.length; | |
| 23 if (offset != 0) _index = offset; | |
| 24 } | |
| 25 | |
| 26 /** | |
| 27 * Returns the first buffer from the list. This returns the whole | |
| 28 * buffer and does not remove the buffer from the list. Use | |
| 29 * [index] to determine the index of the first byte in the buffer. | |
| 30 */ | |
| 31 List<int> get first => _buffers.first; | |
| 32 | |
| 33 /** | |
| 34 * Returns the current index of the next byte. This will always be | |
| 35 * an index into the first buffer as when the index is advanced past | |
| 36 * the end of a buffer it is removed from the list. | |
| 37 */ | |
| 38 int get index => _index; | |
| 39 | |
| 40 /** | |
| 41 * Peek at the next available byte. | |
| 42 */ | |
| 43 int peek() => _buffers.first[_index]; | |
| 44 | |
| 45 /** | |
| 46 * Returns the next available byte removing it from the buffers. | |
| 47 */ | |
| 48 int next() { | |
| 49 int value = _buffers.first[_index++]; | |
| 50 _length--; | |
| 51 if (_index == _buffers.first.length) { | |
| 52 _buffers.removeFirst(); | |
| 53 _index = 0; | |
| 54 } | |
| 55 return value; | |
| 56 } | |
| 57 | |
| 58 /** | |
| 59 * Read [count] bytes from the buffer list. If the number of bytes | |
| 60 * requested is not available null will be returned. | |
| 61 */ | |
| 62 List<int> readBytes(int count) { | |
| 63 List<int> result; | |
| 64 if (_length == 0 || _length < count) return null; | |
| 65 if (_index == 0 && _buffers.first.length == count) { | |
| 66 result = _buffers.first; | |
| 67 _buffers.removeFirst(); | |
| 68 _index = 0; | |
| 69 _length -= count; | |
| 70 return result; | |
| 71 } else { | |
| 72 int firstRemaining = _buffers.first.length - _index; | |
| 73 if (firstRemaining >= count) { | |
| 74 result = _buffers.first.getRange(_index, count); | |
| 75 _index += count; | |
| 76 _length -= count; | |
| 77 if (_index == _buffers.first.length) { | |
| 78 _buffers.removeFirst(); | |
| 79 _index = 0; | |
| 80 } | |
| 81 return result; | |
| 82 } else { | |
| 83 result = new Uint8List(count); | |
| 84 int remaining = count; | |
| 85 while (remaining > 0) { | |
| 86 int bytesInFirst = _buffers.first.length - _index; | |
| 87 if (bytesInFirst <= remaining) { | |
| 88 result.setRange(count - remaining, | |
| 89 bytesInFirst, | |
| 90 _buffers.first, | |
| 91 _index); | |
| 92 _buffers.removeFirst(); | |
| 93 _index = 0; | |
| 94 _length -= bytesInFirst; | |
| 95 remaining -= bytesInFirst; | |
| 96 } else { | |
| 97 result.setRange(count - remaining, | |
| 98 remaining, | |
| 99 _buffers.first, | |
| 100 _index); | |
| 101 _index = remaining; | |
| 102 _length -= remaining; | |
| 103 remaining = 0; | |
| 104 assert(_index < _buffers.first.length); | |
| 105 } | |
| 106 } | |
| 107 return result; | |
| 108 } | |
| 109 } | |
| 110 } | |
| 111 | |
| 112 /** | |
| 113 * Remove a number of bytes from the buffer list. Currently the | |
| 114 * number of bytes to remove must be confined to the first buffer. | |
| 115 */ | |
| 116 void removeBytes(int count) { | |
| 117 int firstRemaining = first.length - _index; | |
| 118 assert(count <= firstRemaining); | |
| 119 if (count == firstRemaining) { | |
| 120 _buffers.removeFirst(); | |
| 121 _index = 0; | |
| 122 } else { | |
| 123 _index += count; | |
| 124 } | |
| 125 _length -= count; | |
| 126 } | |
| 127 | |
| 128 | |
| 129 /** | |
| 130 * Returns the total number of bytes remaining in the buffers. | |
| 131 */ | |
| 132 int get length => _length; | |
| 133 | |
| 134 /** | |
| 135 * Returns whether the buffer list is empty that is has no bytes | |
| 136 * available. | |
| 137 */ | |
| 138 bool get isEmpty => _buffers.isEmpty; | |
| 139 | |
| 140 /** | |
| 141 * Clears the content of the buffer list. | |
| 142 */ | |
| 143 void clear() { | |
| 144 _index = 0; | |
| 145 _length = 0; | |
| 146 _buffers = new Queue(); | |
| 147 } | |
| 148 | |
| 149 int _length; // Total number of bytes remaining in the buffers. | |
| 150 Queue<List<int>> _buffers; // List of data buffers. | |
| 151 int _index; // Index of the next byte in the first buffer. | |
| 152 } | |
| OLD | NEW |