blob: 4d50e08a7be5df400344dfb784860516f15c4564 [file] [log] [blame]
import 'dart:typed_data';
import 'input_buffer.dart';
class OutputBuffer {
int length;
final bool bigEndian;
/// Create a byte buffer for writing.
OutputBuffer({int size = _BLOCK_SIZE, this.bigEndian = false})
: _buffer = Uint8List(size == null ? _BLOCK_SIZE : size),
length = 0;
void rewind() {
length = 0;
}
/// Get the resulting bytes from the buffer.
List<int> getBytes() {
return new Uint8List.view(_buffer.buffer, 0, length);
}
/// Clear the buffer.
void clear() {
_buffer = Uint8List(_BLOCK_SIZE);
length = 0;
}
/// Write a byte to the end of the buffer.
void writeByte(int value) {
if (length == _buffer.length) {
_expandBuffer();
}
_buffer[length++] = value & 0xff;
}
/// Write a set of bytes to the end of the buffer.
void writeBytes(List<int> bytes, [int len]) {
if (len == null) {
len = bytes.length;
}
while (length + len > _buffer.length) {
_expandBuffer((length + len) - _buffer.length);
}
_buffer.setRange(length, length + len, bytes);
length += len;
}
void writeBuffer(InputBuffer bytes) {
while (length + bytes.length > _buffer.length) {
_expandBuffer((length + bytes.length) - _buffer.length);
}
_buffer.setRange(length, length + bytes.length, bytes.buffer, bytes.offset);
length += bytes.length;
}
/// Write a 16-bit word to the end of the buffer.
void writeUint16(int value) {
if (bigEndian) {
writeByte((value >> 8) & 0xff);
writeByte(value & 0xff);
return;
}
writeByte(value & 0xff);
writeByte((value >> 8) & 0xff);
}
/// Write a 32-bit word to the end of the buffer.
void writeUint32(int value) {
if (bigEndian) {
writeByte((value >> 24) & 0xff);
writeByte((value >> 16) & 0xff);
writeByte((value >> 8) & 0xff);
writeByte((value) & 0xff);
return;
}
writeByte((value) & 0xff);
writeByte((value >> 8) & 0xff);
writeByte((value >> 16) & 0xff);
writeByte((value >> 24) & 0xff);
}
/// Return the subset of the buffer in the range [start:end].
/// If [start] or [end] are < 0 then it is relative to the end of the buffer.
/// If [end] is not specified (or null), then it is the end of the buffer.
/// This is equivalent to the python list range operator.
List<int> subset(int start, [int end]) {
if (start < 0) {
start = (length) + start;
}
if (end == null) {
end = length;
} else if (end < 0) {
end = length + end;
}
return new Uint8List.view(_buffer.buffer, start, end - start);
}
/// Grow the buffer to accommodate additional data.
void _expandBuffer([int required]) {
int blockSize = (required != null)
? required
: (_buffer.isEmpty) ? _BLOCK_SIZE : (_buffer.length * 2);
Uint8List newBuffer = Uint8List(_buffer.length + blockSize);
newBuffer.setRange(0, _buffer.length, _buffer);
_buffer = newBuffer;
}
static const int _BLOCK_SIZE = 0x2000; // 8k block-size
Uint8List _buffer;
}