@iotile/iotile-device
Version:
A typescript library for interfacing with IOTile BLE devices
106 lines • 4.46 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const iotile_common_1 = require("@iotile/iotile-common");
const error_space_1 = require("./error-space");
class RingBuffer {
constructor(ringBufferSize, autoexpand = false) {
this.ringBuffer = new ArrayBuffer(ringBufferSize);
this._offset = 0;
this._count = 0;
this._initialSize = ringBufferSize;
this._autoexpand = autoexpand;
}
get offset() { return this._offset; }
get count() { return this._count; }
push(chunk) {
let chunkLength = chunk.byteLength;
if ((chunkLength + this._count) > this.ringBuffer.byteLength) {
if (this._autoexpand) {
let oldBuffer = this.ringBuffer;
let chunk1Length = oldBuffer.byteLength - this._offset;
let chunk2Length = this._count - chunk1Length;
let newSize = 2 * oldBuffer.byteLength;
while (newSize < (chunkLength + this._count)) {
newSize *= 2;
}
this.ringBuffer = new ArrayBuffer(newSize);
if (this._count == 0) {
}
else if (this._count <= chunk1Length) {
iotile_common_1.copyArrayBuffer(this.ringBuffer, oldBuffer, this._offset, 0, this._count);
}
else {
iotile_common_1.copyArrayBuffer(this.ringBuffer, oldBuffer, this._offset, 0, chunk1Length);
iotile_common_1.copyArrayBuffer(this.ringBuffer, oldBuffer, 0, chunk1Length, chunk2Length);
}
this._offset = 0;
}
else {
throw new iotile_common_1.InsufficientSpaceError("Ring buffer would overflow");
}
}
if ((this.endPointer + chunkLength) >= this.ringBuffer.byteLength) {
let chunk1Length = this.ringBuffer.byteLength - this.endPointer;
let chunk2Length = chunkLength - chunk1Length;
if (chunk1Length > 0) {
iotile_common_1.copyArrayBuffer(this.ringBuffer, chunk, 0, this.endPointer, chunk1Length);
}
iotile_common_1.copyArrayBuffer(this.ringBuffer, chunk, chunk1Length, 0, chunk2Length);
}
else {
iotile_common_1.copyArrayBuffer(this.ringBuffer, chunk, 0, this.endPointer, chunkLength);
}
this._count += chunkLength;
}
get endPointer() {
return (this._offset + this._count) % this.ringBuffer.byteLength;
}
reset() {
this._offset = 0;
this._count = 0;
if (this.ringBuffer.byteLength != this._initialSize) {
this.ringBuffer = new ArrayBuffer(this._initialSize);
}
}
peek(length) {
if (this._count < length) {
throw new error_space_1.RingBufferEmptyError('ring buffer did not have enough data for peek');
}
let oldCount = this._count;
let oldOffset = this._offset;
let data = this.pop(length);
this._count = oldCount;
this._offset = oldOffset;
return data;
}
peekAs(fmt) {
let length = iotile_common_1.expectedBufferSize(fmt);
let val = this.peek(length);
return iotile_common_1.unpackArrayBuffer(fmt, val);
}
pop(length) {
if (this._count < length) {
throw new error_space_1.RingBufferEmptyError('ring buffer did not have enough data for pop');
}
let data = new ArrayBuffer(length);
if (this._offset + length > this.ringBuffer.byteLength) {
let chunk1Length = this.ringBuffer.byteLength - this._offset;
let chunk2Length = length - chunk1Length;
iotile_common_1.copyArrayBuffer(data, this.ringBuffer, this._offset, 0, chunk1Length);
iotile_common_1.copyArrayBuffer(data, this.ringBuffer, 0, chunk1Length, chunk2Length);
}
else {
iotile_common_1.copyArrayBuffer(data, this.ringBuffer, this._offset, 0, length);
}
this._count -= length;
this._offset = (this._offset + length) % this.ringBuffer.byteLength;
return data;
}
popAs(fmt) {
let length = iotile_common_1.expectedBufferSize(fmt);
let val = this.pop(length);
return iotile_common_1.unpackArrayBuffer(fmt, val);
}
}
exports.RingBuffer = RingBuffer;
//# sourceMappingURL=ring-buffer.js.map