@loaders.gl/zip
Version:
Zip Archive Loader
111 lines • 3.54 kB
JavaScript
// loaders.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors
import { copyToArrayBuffer } from '@loaders.gl/loader-utils';
function toBigInt(value) {
return typeof value === 'bigint' ? value : BigInt(value);
}
function toNumber(value) {
const numberValue = Number(value);
if (!Number.isFinite(numberValue)) {
throw new Error('Offset is out of bounds');
}
return numberValue;
}
function normalizeOffset(offset, size) {
if (offset < 0) {
return Math.max(size + offset, 0);
}
return Math.min(offset, size);
}
/**
* Read a byte range from a readable file.
* @param file readable file handle
* @param start inclusive start offset
* @param end exclusive end offset
* @returns requested slice
*/
export async function readRange(file, start, end) {
const startOffset = toBigInt(start);
const endOffset = toBigInt(end);
const length = endOffset - startOffset;
if (length < 0) {
throw new Error('Invalid range requested');
}
return await file.read(startOffset, toNumber(length));
}
export async function readDataView(file, start, end) {
const arrayBuffer = await readRange(file, start, end);
return new DataView(arrayBuffer);
}
export async function readUint8(file, offset) {
const dataView = await readDataView(file, offset, toBigInt(offset) + 1n);
return dataView.getUint8(0);
}
export async function readUint16(file, offset) {
const dataView = await readDataView(file, offset, toBigInt(offset) + 2n);
return dataView.getUint16(0, true);
}
export async function readUint32(file, offset) {
const dataView = await readDataView(file, offset, toBigInt(offset) + 4n);
return dataView.getUint32(0, true);
}
export async function readBigUint64(file, offset) {
const dataView = await readDataView(file, offset, toBigInt(offset) + 8n);
return dataView.getBigUint64(0, true);
}
/**
* Resolve the size of a readable file.
* @param file readable file handle
* @returns file size as bigint
*/
export async function getReadableFileSize(file) {
if (file.bigsize > 0n) {
return file.bigsize;
}
if (file.size > 0) {
return BigInt(file.size);
}
if (file.stat) {
const stats = await file.stat();
if (stats?.bigsize !== undefined) {
return stats.bigsize;
}
if (stats?.size !== undefined) {
return BigInt(stats.size);
}
}
return 0n;
}
/**
* Minimal readable file backed by a DataView.
*/
export class DataViewReadableFile {
handle;
size;
bigsize;
url;
constructor(dataView, url = '') {
this.handle = dataView;
this.size = dataView.byteLength;
this.bigsize = BigInt(dataView.byteLength);
this.url = url;
}
async close() { }
async stat() {
return { size: this.size, bigsize: this.bigsize, isDirectory: false };
}
async read(start = 0, length) {
const offset = toNumber(start);
const end = length ? offset + length : this.size;
const normalizedStart = normalizeOffset(offset, this.size);
const normalizedEnd = normalizeOffset(end, this.size);
const clampedEnd = Math.max(normalizedEnd, normalizedStart);
const lengthToRead = clampedEnd - normalizedStart;
if (lengthToRead <= 0) {
return new ArrayBuffer(0);
}
return copyToArrayBuffer(this.handle.buffer, normalizedStart, lengthToRead);
}
}
//# sourceMappingURL=readable-file-utils.js.map