byte-rw
Version:
Byte reader/writer for buffers and streams in typescript/javascript
76 lines (75 loc) • 3.45 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { DataViewByteReaderAsyncChunked } from "../dataview/index.js";
import { copy } from "../utils/copy.js";
export class StreamByteReader extends DataViewByteReaderAsyncChunked {
constructor(stream, littleEndian = true, defaultChunkSize = 4096) {
super(littleEndian, defaultChunkSize);
this.stream = stream;
try {
this.reader = stream.getReader({ mode: "byob" });
this.isByob = true;
}
catch (_a) {
this.reader = stream.getReader();
this.isByob = false;
}
}
fill(minReadLength) {
return __awaiter(this, void 0, void 0, function* () {
if (minReadLength === 0)
return 0;
let chunk = this.currentChunk;
let i_chunk = 0;
while (chunk.view.byteLength - chunk.bytesWritten === 0)
chunk = this.pendingChunks[i_chunk++];
let filled = 0;
while (minReadLength > 0) {
const availableLength = chunk.view.byteLength - chunk.bytesWritten;
const toRead = Math.min(availableLength, minReadLength);
const view = this.isByob ? new DataView(chunk.view.buffer, chunk.view.byteOffset + chunk.bytesWritten, toRead) : undefined;
const read = yield this.reader.read(view);
if (read.done) {
this._isComplete = true;
break;
}
const readView = read.value;
filled += readView.byteLength;
const toCopy = Math.min(availableLength, readView.byteLength);
if (!this.isByob) {
copy({
buffer: readView.buffer,
byteOffset: readView.byteOffset,
byteLength: toCopy
}, {
buffer: chunk.view.buffer,
byteOffset: chunk.view.byteOffset + chunk.bytesWritten,
byteLength: toCopy
});
}
chunk.bytesWritten += toCopy;
const toSave = readView.byteLength - toCopy;
if (toSave > 0) {
console.assert(!this.isByob);
this.pendChunk({
view: {
buffer: readView.buffer,
byteOffset: readView.byteOffset + toCopy,
byteLength: readView.byteLength - toCopy
},
bytesWritten: toSave
});
}
minReadLength -= readView.byteLength;
}
return filled;
});
}
}