"use strict";
/**
 * ZIP record builders (PKWARE APPNOTE)
 *
 * Shared by streaming zip writer and buffer zip builder.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ZIP_END_OF_CENTRAL_DIR_FIXED_SIZE = exports.ZIP_CENTRAL_DIR_HEADER_FIXED_SIZE = exports.ZIP_LOCAL_FILE_HEADER_FIXED_SIZE = exports.UINT32_MAX = exports.UINT16_MAX = exports.FLAG_DATA_DESCRIPTOR = exports.FLAG_UTF8 = exports.COMPRESSION_DEFLATE = exports.COMPRESSION_STORE = exports.VERSION_MADE_BY = exports.VERSION_NEEDED = exports.ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = exports.ZIP64_END_OF_CENTRAL_DIR_SIG = exports.DATA_DESCRIPTOR_SIG = exports.END_OF_CENTRAL_DIR_SIG = exports.CENTRAL_DIR_HEADER_SIG = exports.LOCAL_FILE_HEADER_SIG = void 0;
exports.writeLocalFileHeaderInto = writeLocalFileHeaderInto;
exports.buildLocalFileHeader = buildLocalFileHeader;
exports.writeCentralDirectoryHeaderInto = writeCentralDirectoryHeaderInto;
exports.buildCentralDirectoryHeader = buildCentralDirectoryHeader;
exports.writeEndOfCentralDirectoryInto = writeEndOfCentralDirectoryInto;
exports.buildEndOfCentralDirectory = buildEndOfCentralDirectory;
exports.buildDataDescriptor = buildDataDescriptor;
// =============================================================================
// ZIP format constants (PKWARE APPNOTE)
// =============================================================================
// Signatures
exports.LOCAL_FILE_HEADER_SIG = 0x04034b50;
exports.CENTRAL_DIR_HEADER_SIG = 0x02014b50;
exports.END_OF_CENTRAL_DIR_SIG = 0x06054b50;
exports.DATA_DESCRIPTOR_SIG = 0x08074b50;
exports.ZIP64_END_OF_CENTRAL_DIR_SIG = 0x06064b50;
exports.ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = 0x07064b50;
// Versions
exports.VERSION_NEEDED = 20; // 2.0 - supports DEFLATE
exports.VERSION_MADE_BY = 20; // 2.0
// Compression methods
exports.COMPRESSION_STORE = 0;
exports.COMPRESSION_DEFLATE = 8;
// General purpose bit flags
exports.FLAG_UTF8 = 0x0800;
exports.FLAG_DATA_DESCRIPTOR = 0x0008;
// ZIP64 / sentinel sizes
exports.UINT16_MAX = 0xffff;
exports.UINT32_MAX = 0xffffffff;
exports.ZIP_LOCAL_FILE_HEADER_FIXED_SIZE = 30;
exports.ZIP_CENTRAL_DIR_HEADER_FIXED_SIZE = 46;
exports.ZIP_END_OF_CENTRAL_DIR_FIXED_SIZE = 22;
function writeLocalFileHeaderInto(out, view, offset, input) {
    const versionNeeded = input.versionNeeded ?? exports.VERSION_NEEDED;
    view.setUint32(offset + 0, exports.LOCAL_FILE_HEADER_SIG, true);
    view.setUint16(offset + 4, versionNeeded, true);
    view.setUint16(offset + 6, input.flags, true);
    view.setUint16(offset + 8, input.compressionMethod, true);
    view.setUint16(offset + 10, input.dosTime, true);
    view.setUint16(offset + 12, input.dosDate, true);
    view.setUint32(offset + 14, input.crc32, true);
    view.setUint32(offset + 18, input.compressedSize, true);
    view.setUint32(offset + 22, input.uncompressedSize, true);
    view.setUint16(offset + 26, input.fileName.length, true);
    view.setUint16(offset + 28, input.extraField.length, true);
    out.set(input.fileName, offset + exports.ZIP_LOCAL_FILE_HEADER_FIXED_SIZE);
    if (input.extraField.length > 0) {
        out.set(input.extraField, offset + exports.ZIP_LOCAL_FILE_HEADER_FIXED_SIZE + input.fileName.length);
    }
    return exports.ZIP_LOCAL_FILE_HEADER_FIXED_SIZE + input.fileName.length + input.extraField.length;
}
function buildLocalFileHeader(input) {
    const header = new Uint8Array(exports.ZIP_LOCAL_FILE_HEADER_FIXED_SIZE + input.fileName.length + input.extraField.length);
    const view = new DataView(header.buffer, header.byteOffset, header.byteLength);
    writeLocalFileHeaderInto(header, view, 0, input);
    return header;
}
function writeCentralDirectoryHeaderInto(out, view, offset, input) {
    const versionMadeBy = input.versionMadeBy ?? exports.VERSION_MADE_BY;
    const versionNeeded = input.versionNeeded ?? exports.VERSION_NEEDED;
    const externalAttributes = input.externalAttributes ?? 0;
    view.setUint32(offset + 0, exports.CENTRAL_DIR_HEADER_SIG, true);
    view.setUint16(offset + 4, versionMadeBy, true);
    view.setUint16(offset + 6, versionNeeded, true);
    view.setUint16(offset + 8, input.flags, true);
    view.setUint16(offset + 10, input.compressionMethod, true);
    view.setUint16(offset + 12, input.dosTime, true);
    view.setUint16(offset + 14, input.dosDate, true);
    view.setUint32(offset + 16, input.crc32, true);
    view.setUint32(offset + 20, input.compressedSize, true);
    view.setUint32(offset + 24, input.uncompressedSize, true);
    view.setUint16(offset + 28, input.fileName.length, true);
    view.setUint16(offset + 30, input.extraField.length, true);
    view.setUint16(offset + 32, input.comment.length, true);
    view.setUint16(offset + 34, 0, true); // disk number start
    view.setUint16(offset + 36, 0, true); // internal file attributes
    view.setUint32(offset + 38, externalAttributes, true);
    view.setUint32(offset + 42, input.localHeaderOffset, true);
    out.set(input.fileName, offset + exports.ZIP_CENTRAL_DIR_HEADER_FIXED_SIZE);
    if (input.extraField.length > 0) {
        out.set(input.extraField, offset + exports.ZIP_CENTRAL_DIR_HEADER_FIXED_SIZE + input.fileName.length);
    }
    if (input.comment.length > 0) {
        out.set(input.comment, offset + exports.ZIP_CENTRAL_DIR_HEADER_FIXED_SIZE + input.fileName.length + input.extraField.length);
    }
    return (exports.ZIP_CENTRAL_DIR_HEADER_FIXED_SIZE +
        input.fileName.length +
        input.extraField.length +
        input.comment.length);
}
function buildCentralDirectoryHeader(input) {
    const header = new Uint8Array(exports.ZIP_CENTRAL_DIR_HEADER_FIXED_SIZE +
        input.fileName.length +
        input.extraField.length +
        input.comment.length);
    const view = new DataView(header.buffer, header.byteOffset, header.byteLength);
    writeCentralDirectoryHeaderInto(header, view, 0, input);
    return header;
}
function writeEndOfCentralDirectoryInto(out, view, offset, input) {
    view.setUint32(offset + 0, exports.END_OF_CENTRAL_DIR_SIG, true);
    view.setUint16(offset + 4, 0, true);
    view.setUint16(offset + 6, 0, true);
    view.setUint16(offset + 8, input.entryCount, true);
    view.setUint16(offset + 10, input.entryCount, true);
    view.setUint32(offset + 12, input.centralDirSize, true);
    view.setUint32(offset + 16, input.centralDirOffset, true);
    view.setUint16(offset + 20, input.comment.length, true);
    if (input.comment.length > 0) {
        out.set(input.comment, offset + exports.ZIP_END_OF_CENTRAL_DIR_FIXED_SIZE);
    }
    return exports.ZIP_END_OF_CENTRAL_DIR_FIXED_SIZE + input.comment.length;
}
function buildEndOfCentralDirectory(input) {
    const record = new Uint8Array(exports.ZIP_END_OF_CENTRAL_DIR_FIXED_SIZE + input.comment.length);
    const view = new DataView(record.buffer, record.byteOffset, record.byteLength);
    writeEndOfCentralDirectoryInto(record, view, 0, input);
    return record;
}
function buildDataDescriptor(crc32, compressedSize, uncompressedSize) {
    const descriptor = new Uint8Array(16);
    const view = new DataView(descriptor.buffer);
    view.setUint32(0, exports.DATA_DESCRIPTOR_SIG, true);
    view.setUint32(4, crc32, true);
    view.setUint32(8, compressedSize, true);
    view.setUint32(12, uncompressedSize, true);
    return descriptor;
}
