143de9eb80
Review URL: https://chromiumcodereview.appspot.com//9235067 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@3812 260f80e4-7a28-3924-810f-c04153c831b5
149 lines
4.1 KiB
Dart
149 lines
4.1 KiB
Dart
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
/**
|
|
* Utility class that holds a number of byte buffers and can deliver
|
|
* the bytes either one by one or in chunks.
|
|
*/
|
|
class _BufferList {
|
|
_BufferList() {
|
|
clear();
|
|
}
|
|
|
|
/**
|
|
* Adds a new buffer to the list possibly with an offset of the
|
|
* first byte of interest. The offset can only be specified if the
|
|
* buffer list is empty.
|
|
*/
|
|
void add(List<int> buffer, [int offset = 0]) {
|
|
assert(offset == 0 || _buffers.isEmpty());
|
|
_buffers.addLast(buffer);
|
|
_length += buffer.length;
|
|
if (offset != 0) _index = offset;
|
|
}
|
|
|
|
/**
|
|
* Returns the first buffer from the list. This returns the whole
|
|
* buffer and does not remove the buffer from the list. Use
|
|
* [index] to determine the index of the first byte in the buffer.
|
|
*/
|
|
List<int> get first() => _buffers.first();
|
|
|
|
/**
|
|
* Returns the current index of the next byte. This will always be
|
|
* an index into the first buffer as when the index is advanced past
|
|
* the end of a buffer it is removed from the list.
|
|
*/
|
|
int get index() => _index;
|
|
|
|
/**
|
|
* Peek at the next available byte.
|
|
*/
|
|
int peek() => _buffers.first()[_index];
|
|
|
|
/**
|
|
* Returns the next available byte removing it from the buffers.
|
|
*/
|
|
int next() {
|
|
int value = _buffers.first()[_index++];
|
|
_length--;
|
|
if (_index == _buffers.first().length) {
|
|
_buffers.removeFirst();
|
|
_index = 0;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Read [count] bytes from the buffer list. If the number of bytes
|
|
* requested is not available null will be returned.
|
|
*/
|
|
List<int> readBytes(int count) {
|
|
List<int> result;
|
|
if (_length == 0 || _length < count) return null;
|
|
if (_index == 0 && _buffers.first().length == count) {
|
|
result = _buffers.first();
|
|
_buffers.removeFirst();
|
|
_index = 0;
|
|
_length -= count;
|
|
return result;
|
|
} else {
|
|
int firstRemaining = _buffers.first().length - _index;
|
|
if (firstRemaining >= count) {
|
|
result = _buffers.first().getRange(_index, count);
|
|
_index += count;
|
|
_length -= count;
|
|
return result;
|
|
} else {
|
|
result = new ByteArray(count);
|
|
int remaining = count;
|
|
while (remaining > 0) {
|
|
int bytesInFirst = _buffers.first().length - _index;
|
|
if (bytesInFirst <= remaining) {
|
|
result.setRange(count - remaining,
|
|
bytesInFirst,
|
|
_buffers.first(),
|
|
_index);
|
|
_buffers.removeFirst();
|
|
_index = 0;
|
|
_length -= bytesInFirst;
|
|
remaining -= bytesInFirst;
|
|
} else {
|
|
result.setRange(count - remaining,
|
|
remaining,
|
|
_buffers.first(),
|
|
_index);
|
|
_index = remaining;
|
|
_length -= remaining;
|
|
remaining = 0;
|
|
assert(_index < _buffers.first().length);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove a number of bytes from the buffer list. Currently the
|
|
* number of bytes to remove must be confined to the first buffer.
|
|
*/
|
|
void removeBytes(int count) {
|
|
int firstRemaining = first.length - _index;
|
|
assert(count <= firstRemaining);
|
|
if (count == firstRemaining) {
|
|
_buffers.removeFirst();
|
|
_index = 0;
|
|
} else {
|
|
_index += count;
|
|
}
|
|
_length -= count;
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the total number of bytes remaining in the buffers.
|
|
*/
|
|
int get length() => _length;
|
|
|
|
/**
|
|
* Returns whether the buffer list is empty that is has no bytes
|
|
* available.
|
|
*/
|
|
bool isEmpty() => _buffers.isEmpty();
|
|
|
|
/**
|
|
* Clears the content of the buffer list.
|
|
*/
|
|
void clear() {
|
|
_index = 0;
|
|
_length = 0;
|
|
_buffers = new Queue();
|
|
}
|
|
|
|
int _length; // Total number of bytes remaining in the buffers.
|
|
Queue<List<int>> _buffers; // List of data buffers.
|
|
int _index; // Index of the next byte in the first buffer.
|
|
}
|