@loaders.gl/zip
Version:
Zip Archive Loader
74 lines (73 loc) • 2.35 kB
JavaScript
import { concatenateArrayBuffers } from '@loaders.gl/loader-utils';
export const signature = new Uint8Array([0x01, 0x00]);
/**
* creates zip64 extra field
* @param options info that can be placed into zip64 field
* @returns buffer with field
*/
export function createZip64Info(options) {
const optionsToUse = {
...options,
zip64Length: (options.offset ? 1 : 0) * 8 + (options.size ? 1 : 0) * 16
};
const arraysToConcat = [];
for (const field of ZIP64_FIELDS) {
if (!optionsToUse[field.name ?? ''] && !field.default) {
continue; // eslint-disable-line no-continue
}
const newValue = new DataView(new ArrayBuffer(field.size));
NUMBER_SETTERS[field.size](newValue, 0, optionsToUse[field.name ?? ''] ?? field.default);
arraysToConcat.push(newValue.buffer);
}
return concatenateArrayBuffers(...arraysToConcat);
}
/**
* Writes values into buffer according to the bytes amount
* @param header header where to write the data
* @param fieldSize size of the field in bytes
* @param fieldOffset offset of the field
* @param value value to be written
*/
export function setFieldToNumber(header, fieldSize, fieldOffset, value) {
NUMBER_SETTERS[fieldSize](header, Number(fieldOffset), value);
}
/** functions to write values into buffer according to the bytes amount */
const NUMBER_SETTERS = {
2: (header, offset, value) => {
header.setUint16(offset, Number(value > 0xffff ? 0xffff : value), true);
},
4: (header, offset, value) => {
header.setUint32(offset, Number(value > 0xffffffff ? 0xffffffff : value), true);
},
8: (header, offset, value) => {
header.setBigUint64(offset, BigInt(value), true);
}
};
/** zip64 info fields description, we need it as a pattern to build a zip64 info */
const ZIP64_FIELDS = [
// Header ID 0x0001
{
size: 2,
default: new DataView(signature.buffer).getUint16(0, true)
},
// Size of the extra field chunk (8, 16, 24 or 28)
{
size: 2,
name: 'zip64Length'
},
// Original uncompressed file size
{
size: 8,
name: 'size'
},
// Size of compressed data
{
size: 8,
name: 'size'
},
// Offset of local header record
{
size: 8,
name: 'offset'
}
];