@apr144/generic-filehandle
Version:
uniform interface for accessing binary data from local files, remote HTTP resources, and browser Blob data
94 lines • 3.17 kB
JavaScript
import { Buffer } from 'buffer';
// Using this you can "await" the file like a normal promise
// https://blog.shovonhasan.com/using-promises-with-filereader/
function readBlobAsArrayBuffer(blob) {
const fileReader = new FileReader();
return new Promise((resolve, reject) => {
fileReader.onerror = () => {
fileReader.abort();
reject(new Error('problem reading blob'));
};
fileReader.onabort = () => {
reject(new Error('blob reading was aborted'));
};
fileReader.onload = () => {
if (fileReader.result && typeof fileReader.result !== 'string') {
resolve(fileReader.result);
}
else {
reject(new Error('unknown error reading blob'));
}
};
fileReader.readAsArrayBuffer(blob);
});
}
function readBlobAsText(blob) {
const fileReader = new FileReader();
return new Promise((resolve, reject) => {
fileReader.onerror = () => {
fileReader.abort();
reject(new Error('problem reading blob'));
};
fileReader.onabort = () => {
reject(new Error('blob reading was aborted'));
};
fileReader.onload = () => {
if (fileReader.result && typeof fileReader.result === 'string') {
resolve(fileReader.result);
}
else {
reject(new Error('unknown error reading blob'));
}
};
fileReader.readAsText(blob);
});
}
/**
* Blob of binary data fetched from a local file (with FileReader).
*
* Adapted by Robert Buels and Garrett Stevens from the BlobFetchable object in
* the Dalliance Genome Explorer, which is copyright Thomas Down 2006-2011.
*/
export default class BlobFile {
constructor(blob) {
this.blob = blob;
this.size = blob.size;
}
async read(buffer, offset = 0, length, position = 0) {
// short-circuit a read of 0 bytes here, because browsers actually sometimes
// crash if you try to read 0 bytes from a local file!
if (!length) {
return { bytesRead: 0, buffer };
}
const start = position;
const end = start + length;
const result = await readBlobAsArrayBuffer(this.blob.slice(start, end));
const resultBuffer = Buffer.from(result);
const bytesCopied = resultBuffer.copy(buffer, offset);
return { bytesRead: bytesCopied, buffer: resultBuffer };
}
async readFile(options) {
let encoding;
if (typeof options === 'string') {
encoding = options;
}
else {
encoding = options && options.encoding;
}
if (encoding === 'utf8') {
return readBlobAsText(this.blob);
}
if (encoding) {
throw new Error(`unsupported encoding: ${encoding}`);
}
const result = await readBlobAsArrayBuffer(this.blob);
return Buffer.from(result);
}
async stat() {
return { size: this.size };
}
async close() {
return;
}
}
//# sourceMappingURL=blobFile.js.map