| Index: lib/protobuf/runtime/PbByteBuffer.dart
|
| diff --git a/lib/protobuf/runtime/PbByteBuffer.dart b/lib/protobuf/runtime/PbByteBuffer.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..867b50aa9d60cadca9ad6afb3912f72f67871514
|
| --- /dev/null
|
| +++ b/lib/protobuf/runtime/PbByteBuffer.dart
|
| @@ -0,0 +1,147 @@
|
| +// Copyright (c) 2011, 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.
|
| +
|
| +/**
|
| + * A dynamic byte buffer that acts as a buffering pipe/queue for data.
|
| + */
|
| +class PbByteBuffer {
|
| + /**
|
| + * Build empty buffer
|
| + */
|
| + PbByteBuffer() : _buffer = new Queue<List<int>>();
|
| +
|
| + /**
|
| + * Build with an optional queue of lists (the initial buffer).
|
| + */
|
| + PbByteBuffer.fromQueueOfLists([Queue<List<int>> this._buffer]) {
|
| + if (null !== _buffer) {
|
| + for (List<int> l in _buffer) {
|
| + _length += l.length;
|
| + }
|
| + } else {
|
| + _buffer = new Queue<List<int>>();
|
| + }
|
| + _updateBuffers();
|
| + }
|
| +
|
| + /**
|
| + * Build buffer from a single list.
|
| + */
|
| + PbByteBuffer.fromList(List<int> buffer) {
|
| + _buffer = new Queue<List<int>>();
|
| + _buffer.add(buffer);
|
| + _length = buffer.length;
|
| + _updateBuffers();
|
| + }
|
| +
|
| + /**
|
| + * Add a list of bytes to the internal buffer queue.
|
| + */
|
| + void add(List<int> more) {
|
| + _length += more.length;
|
| + _buffer.add(more);
|
| + }
|
| +
|
| + /**
|
| + * Read a single byte.
|
| + */
|
| + int readByte() {
|
| + if(isEmpty) {
|
| + return null;
|
| + } else {
|
| + int value = _buffer.first()[_index++];
|
| + _length--;
|
| + _updateBuffers();
|
| + return value;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Read the specified bytes (or as many as are available) and
|
| + * return these as a list of int.
|
| + */
|
| + List<int> readBytes([int count = -1]) {
|
| + List<int> result;
|
| +
|
| + // USe temporary variables to work around
|
| + // http://code.google.com/p/dart/issues/detail?id=3806
|
| + int c = count;
|
| + int l = _length;
|
| + if (l == 0) return [];
|
| + int remaining = (c < 0 || l < c) ? l : c;
|
| +
|
| + // optimization -- perhaps you can just pass back the top list.
|
| + if (_index == 0 && _buffer.first().length == remaining) {
|
| + _length -= remaining;
|
| + return _buffer.removeFirst();
|
| + }
|
| +
|
| + result = createIntArray(remaining);
|
| + int cursor = 0;
|
| + while (remaining > 0) {
|
| + int bytesInFirst = _buffer.first().length - _index;
|
| + if (bytesInFirst <= remaining) {
|
| + result.setRange(cursor,
|
| + bytesInFirst,
|
| + _buffer.first(),
|
| + _index);
|
| + _buffer.removeFirst();
|
| + _index = 0;
|
| + _length -= bytesInFirst;
|
| + cursor += bytesInFirst;
|
| + remaining -= bytesInFirst;
|
| + } else {
|
| + result.setRange(cursor,
|
| + remaining,
|
| + _buffer.first(),
|
| + _index);
|
| + _index += remaining;
|
| + _length -= remaining;
|
| + remaining = 0;
|
| + _updateBuffers();
|
| + assert(_index < _buffer.first().length);
|
| + }
|
| + }
|
| + return result;
|
| + }
|
| +
|
| + /**
|
| + * Return the length (remaining bytes available).
|
| + */
|
| + int get length() => _length;
|
| +
|
| + /**
|
| + * Return true if no more data is available in the buffer.
|
| + */
|
| + bool get isEmpty() {
|
| + return _buffer.isEmpty();
|
| + }
|
| +
|
| + /**
|
| + * Provide the remainder of the byte buffer as a list.
|
| + */
|
| + List<int> toList() => readBytes(length);
|
| +
|
| + void _updateBuffers() {
|
| + while (!_buffer.isEmpty() && _index == _buffer.first().length) {
|
| + _buffer.removeFirst();
|
| + _index = 0;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Data structure for buffered bytes.
|
| + */
|
| + Queue<List<int>> _buffer;
|
| +
|
| + /**
|
| + * Index within the current buffer ([List<int>]).
|
| + */
|
| + int _index = 0;
|
| +
|
| + /**
|
| + * Total number of bytes remaining in buffers.
|
| + */
|
| + int _length = 0;
|
| +}
|
|
|