UNPKG

recoder-code

Version:

🚀 AI-powered development platform - Chat with 32+ models, build projects, automate workflows. Free models included!

72 lines (71 loc) • 2.54 kB
import { EndOfStreamError, AbortError } from "./Errors.js"; export class AbstractStreamReader { constructor() { this.endOfStream = false; this.interrupted = false; /** * Store peeked data * @type {Array} */ this.peekQueue = []; } async peek(uint8Array, mayBeLess = false) { const bytesRead = await this.read(uint8Array, mayBeLess); this.peekQueue.push(uint8Array.subarray(0, bytesRead)); // Put read data back to peek buffer return bytesRead; } async read(buffer, mayBeLess = false) { if (buffer.length === 0) { return 0; } let bytesRead = this.readFromPeekBuffer(buffer); if (!this.endOfStream) { bytesRead += await this.readRemainderFromStream(buffer.subarray(bytesRead), mayBeLess); } if (bytesRead === 0 && !mayBeLess) { throw new EndOfStreamError(); } return bytesRead; } /** * Read chunk from stream * @param buffer - Target Uint8Array (or Buffer) to store data read from stream in * @returns Number of bytes read */ readFromPeekBuffer(buffer) { let remaining = buffer.length; let bytesRead = 0; // consume peeked data first while (this.peekQueue.length > 0 && remaining > 0) { const peekData = this.peekQueue.pop(); // Front of queue if (!peekData) throw new Error('peekData should be defined'); const lenCopy = Math.min(peekData.length, remaining); buffer.set(peekData.subarray(0, lenCopy), bytesRead); bytesRead += lenCopy; remaining -= lenCopy; if (lenCopy < peekData.length) { // remainder back to queue this.peekQueue.push(peekData.subarray(lenCopy)); } } return bytesRead; } async readRemainderFromStream(buffer, mayBeLess) { let bytesRead = 0; // Continue reading from stream if required while (bytesRead < buffer.length && !this.endOfStream) { if (this.interrupted) { throw new AbortError(); } const chunkLen = await this.readFromStream(buffer.subarray(bytesRead), mayBeLess); if (chunkLen === 0) break; bytesRead += chunkLen; } if (!mayBeLess && bytesRead < buffer.length) { throw new EndOfStreamError(); } return bytesRead; } }