UNPKG

@iotile/iotile-device

Version:

A typescript library for interfacing with IOTile BLE devices

106 lines 4.46 kB
"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