mirror of
https://github.com/codedread/bitjs
synced 2025-10-03 17:49:16 +02:00
Move some common type definitions into archive/common.js and some comments.
This commit is contained in:
parent
4fc0c3da2b
commit
45fdedd663
11 changed files with 75 additions and 83 deletions
|
@ -1,14 +1,19 @@
|
||||||
/**
|
/**
|
||||||
* common.js
|
* common.js
|
||||||
*
|
*
|
||||||
* Provides common functionality for compressing and decompressing.
|
* Provides common definitions or functionality needed by multiple modules.
|
||||||
*
|
*
|
||||||
* Licensed under the MIT License
|
* Licensed under the MIT License
|
||||||
*
|
*
|
||||||
* Copyright(c) 2023 Google Inc.
|
* Copyright(c) 2023 Google Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Requires the following JavaScript features: MessageChannel, MessagePort, and dynamic imports.
|
/**
|
||||||
|
* @typedef FileInfo An object that is sent to the implementation representing a file to compress.
|
||||||
|
* @property {string} fileName The name of the file. TODO: Includes the path?
|
||||||
|
* @property {number} lastModTime The number of ms since the Unix epoch (1970-01-01 at midnight).
|
||||||
|
* @property {Uint8Array} fileData The bytes of the file.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef Implementation
|
* @typedef Implementation
|
||||||
|
@ -51,3 +56,23 @@ export async function getConnectedPort(implFilename) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Zip-specific things.
|
||||||
|
|
||||||
|
export const LOCAL_FILE_HEADER_SIG = 0x04034b50;
|
||||||
|
export const CENTRAL_FILE_HEADER_SIG = 0x02014b50;
|
||||||
|
export const END_OF_CENTRAL_DIR_SIG = 0x06054b50;
|
||||||
|
export const CRC32_MAGIC_NUMBER = 0xedb88320;
|
||||||
|
export const ARCHIVE_EXTRA_DATA_SIG = 0x08064b50;
|
||||||
|
export const DIGITAL_SIGNATURE_SIG = 0x05054b50;
|
||||||
|
export const END_OF_CENTRAL_DIR_LOCATOR_SIG = 0x07064b50;
|
||||||
|
export const DATA_DESCRIPTOR_SIG = 0x08074b50;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @readonly
|
||||||
|
* @enum {number}
|
||||||
|
*/
|
||||||
|
export const ZipCompressionMethod = {
|
||||||
|
STORE: 0, // Default.
|
||||||
|
DEFLATE: 8, // As per http://tools.ietf.org/html/rfc1951.
|
||||||
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* Copyright(c) 2023 Google Inc.
|
* Copyright(c) 2023 Google Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { getConnectedPort } from './common.js';
|
import { ZipCompressionMethod, getConnectedPort } from './common.js';
|
||||||
|
|
||||||
// NOTE: THIS IS A VERY HACKY WORK-IN-PROGRESS! THE API IS NOT FROZEN! USE AT YOUR OWN RISK!
|
// NOTE: THIS IS A VERY HACKY WORK-IN-PROGRESS! THE API IS NOT FROZEN! USE AT YOUR OWN RISK!
|
||||||
|
|
||||||
|
@ -19,15 +19,6 @@ import { getConnectedPort } from './common.js';
|
||||||
* @property {Uint8Array} fileData The bytes of the file.
|
* @property {Uint8Array} fileData The bytes of the file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @readonly
|
|
||||||
* @enum {number}
|
|
||||||
*/
|
|
||||||
export const ZipCompressionMethod = {
|
|
||||||
STORE: 0, // Default.
|
|
||||||
// DEFLATE: 8,
|
|
||||||
};
|
|
||||||
|
|
||||||
// export const DeflateCompressionMethod = {
|
// export const DeflateCompressionMethod = {
|
||||||
// NO_COMPRESSION: 0,
|
// NO_COMPRESSION: 0,
|
||||||
// COMPRESSION_FIXED_HUFFMAN: 1,
|
// COMPRESSION_FIXED_HUFFMAN: 1,
|
||||||
|
@ -36,17 +27,15 @@ export const ZipCompressionMethod = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data elements are packed into bytes in order of increasing bit number within the byte,
|
* Data elements are packed into bytes in order of increasing bit number within the byte,
|
||||||
i.e., starting with the least-significant bit of the byte.
|
* i.e., starting with the least-significant bit of the byte.
|
||||||
* Data elements other than Huffman codes are packed starting with the least-significant bit of the
|
* Data elements other than Huffman codes are packed starting with the least-significant bit of the
|
||||||
data element.
|
* data element.
|
||||||
* Huffman codes are packed starting with the most-significant bit of the code.
|
* Huffman codes are packed starting with the most-significant bit of the code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef CompressorOptions
|
* @typedef CompressorOptions
|
||||||
* @property {ZipCompressionMethod} zipCompressionMethod
|
* @property {ZipCompressionMethod} zipCompressionMethod
|
||||||
* @property {DeflateCompressionMethod=} deflateCompressionMethod Only present if
|
|
||||||
* zipCompressionMethod is set to DEFLATE.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,6 +80,7 @@ export class Zipper {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
this.zipCompressionMethod = options.zipCompressionMethod || ZipCompressionMethod.STORE;
|
this.zipCompressionMethod = options.zipCompressionMethod || ZipCompressionMethod.STORE;
|
||||||
|
if (this.zipCompressionMethod === ZipCompressionMethod.DEFLATE) throw `DEFLATE not supported.`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {CompressStatus}
|
* @type {CompressStatus}
|
||||||
|
|
|
@ -19,9 +19,9 @@ export const UnarchiveEventType = {
|
||||||
ERROR: 'error'
|
ERROR: 'error'
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
// TODO: Use CustomEvent and a @template and remove these boilerplate events.
|
||||||
* An unarchive event.
|
|
||||||
*/
|
/** An unarchive event. */
|
||||||
export class UnarchiveEvent extends Event {
|
export class UnarchiveEvent extends Event {
|
||||||
/**
|
/**
|
||||||
* @param {string} type The event type.
|
* @param {string} type The event type.
|
||||||
|
@ -31,9 +31,7 @@ export class UnarchiveEvent extends Event {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Updates all Unarchiver listeners that an append has occurred. */
|
||||||
* Updates all Archiver listeners that an append has occurred.
|
|
||||||
*/
|
|
||||||
export class UnarchiveAppendEvent extends UnarchiveEvent {
|
export class UnarchiveAppendEvent extends UnarchiveEvent {
|
||||||
/**
|
/**
|
||||||
* @param {number} numBytes The number of bytes appended.
|
* @param {number} numBytes The number of bytes appended.
|
||||||
|
@ -49,9 +47,7 @@ export class UnarchiveAppendEvent extends UnarchiveEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Useful for passing info up to the client (for debugging). */
|
||||||
* Useful for passing info up to the client (for debugging).
|
|
||||||
*/
|
|
||||||
export class UnarchiveInfoEvent extends UnarchiveEvent {
|
export class UnarchiveInfoEvent extends UnarchiveEvent {
|
||||||
/**
|
/**
|
||||||
* @param {string} msg The info message.
|
* @param {string} msg The info message.
|
||||||
|
@ -67,9 +63,7 @@ export class UnarchiveInfoEvent extends UnarchiveEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** An unrecoverable error has occured. */
|
||||||
* An unrecoverable error has occured.
|
|
||||||
*/
|
|
||||||
export class UnarchiveErrorEvent extends UnarchiveEvent {
|
export class UnarchiveErrorEvent extends UnarchiveEvent {
|
||||||
/**
|
/**
|
||||||
* @param {string} msg The error message.
|
* @param {string} msg The error message.
|
||||||
|
@ -85,18 +79,14 @@ export class UnarchiveErrorEvent extends UnarchiveEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Start event. */
|
||||||
* Start event.
|
|
||||||
*/
|
|
||||||
export class UnarchiveStartEvent extends UnarchiveEvent {
|
export class UnarchiveStartEvent extends UnarchiveEvent {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(UnarchiveEventType.START);
|
super(UnarchiveEventType.START);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Finish event. */
|
||||||
* Finish event.
|
|
||||||
*/
|
|
||||||
export class UnarchiveFinishEvent extends UnarchiveEvent {
|
export class UnarchiveFinishEvent extends UnarchiveEvent {
|
||||||
/**
|
/**
|
||||||
* @param {Object} metadata A collection fo metadata about the archive file.
|
* @param {Object} metadata A collection fo metadata about the archive file.
|
||||||
|
@ -108,9 +98,7 @@ export class UnarchiveFinishEvent extends UnarchiveEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bitjs): Fully document these. They are confusing.
|
// TODO(bitjs): Fully document these. They are confusing.
|
||||||
/**
|
/** Progress event. */
|
||||||
* Progress event.
|
|
||||||
*/
|
|
||||||
export class UnarchiveProgressEvent extends UnarchiveEvent {
|
export class UnarchiveProgressEvent extends UnarchiveEvent {
|
||||||
/**
|
/**
|
||||||
* @param {string} currentFilename
|
* @param {string} currentFilename
|
||||||
|
@ -136,9 +124,7 @@ export class UnarchiveProgressEvent extends UnarchiveEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Extract event. */
|
||||||
* Extract event.
|
|
||||||
*/
|
|
||||||
export class UnarchiveExtractEvent extends UnarchiveEvent {
|
export class UnarchiveExtractEvent extends UnarchiveEvent {
|
||||||
/**
|
/**
|
||||||
* @param {UnarchivedFile} unarchivedFile
|
* @param {UnarchivedFile} unarchivedFile
|
||||||
|
|
|
@ -28,6 +28,7 @@ let hostPort;
|
||||||
|
|
||||||
// State - consider putting these into a class.
|
// State - consider putting these into a class.
|
||||||
let unarchiveState = UnarchiveState.NOT_STARTED;
|
let unarchiveState = UnarchiveState.NOT_STARTED;
|
||||||
|
/** @type {ByteStream} */
|
||||||
let bytestream = null;
|
let bytestream = null;
|
||||||
let allLocalFiles = null;
|
let allLocalFiles = null;
|
||||||
let logToConsole = false;
|
let logToConsole = false;
|
||||||
|
|
|
@ -24,6 +24,7 @@ let hostPort;
|
||||||
|
|
||||||
// State - consider putting these into a class.
|
// State - consider putting these into a class.
|
||||||
let unarchiveState = UnarchiveState.NOT_STARTED;
|
let unarchiveState = UnarchiveState.NOT_STARTED;
|
||||||
|
/** @type {ByteStream} */
|
||||||
let bytestream = null;
|
let bytestream = null;
|
||||||
let allLocalFiles = null;
|
let allLocalFiles = null;
|
||||||
let logToConsole = false;
|
let logToConsole = false;
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
import { BitStream } from '../io/bitstream.js';
|
import { BitStream } from '../io/bitstream.js';
|
||||||
import { ByteBuffer } from '../io/bytebuffer.js';
|
import { ByteBuffer } from '../io/bytebuffer.js';
|
||||||
import { ByteStream } from '../io/bytestream.js';
|
import { ByteStream } from '../io/bytestream.js';
|
||||||
|
import { ARCHIVE_EXTRA_DATA_SIG, CENTRAL_FILE_HEADER_SIG, CRC32_MAGIC_NUMBER,
|
||||||
|
DATA_DESCRIPTOR_SIG, DIGITAL_SIGNATURE_SIG, END_OF_CENTRAL_DIR_SIG,
|
||||||
|
LOCAL_FILE_HEADER_SIG } from './common.js';
|
||||||
|
|
||||||
const UnarchiveState = {
|
const UnarchiveState = {
|
||||||
NOT_STARTED: 0,
|
NOT_STARTED: 0,
|
||||||
|
@ -28,6 +31,7 @@ let hostPort;
|
||||||
|
|
||||||
// State - consider putting these into a class.
|
// State - consider putting these into a class.
|
||||||
let unarchiveState = UnarchiveState.NOT_STARTED;
|
let unarchiveState = UnarchiveState.NOT_STARTED;
|
||||||
|
/** @type {ByteStream} */
|
||||||
let bytestream = null;
|
let bytestream = null;
|
||||||
let allLocalFiles = null;
|
let allLocalFiles = null;
|
||||||
let logToConsole = false;
|
let logToConsole = false;
|
||||||
|
@ -60,14 +64,6 @@ const postProgress = function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const zLocalFileHeaderSignature = 0x04034b50;
|
|
||||||
const zArchiveExtraDataSignature = 0x08064b50;
|
|
||||||
const zCentralFileHeaderSignature = 0x02014b50;
|
|
||||||
const zDigitalSignatureSignature = 0x05054b50;
|
|
||||||
const zEndOfCentralDirSignature = 0x06054b50;
|
|
||||||
const zEndOfCentralDirLocatorSignature = 0x07064b50;
|
|
||||||
const zDataDescriptorSignature = 0x08074b50;
|
|
||||||
|
|
||||||
// mask for getting the Nth bit (zero-based)
|
// mask for getting the Nth bit (zero-based)
|
||||||
const BIT = [0x01, 0x02, 0x04, 0x08,
|
const BIT = [0x01, 0x02, 0x04, 0x08,
|
||||||
0x10, 0x20, 0x40, 0x80,
|
0x10, 0x20, 0x40, 0x80,
|
||||||
|
@ -75,9 +71,7 @@ const BIT = [0x01, 0x02, 0x04, 0x08,
|
||||||
0x1000, 0x2000, 0x4000, 0x8000];
|
0x1000, 0x2000, 0x4000, 0x8000];
|
||||||
|
|
||||||
class ZipLocalFile {
|
class ZipLocalFile {
|
||||||
/**
|
/** @param {ByteStream} bstream */
|
||||||
* @param {ByteStream} bstream
|
|
||||||
*/
|
|
||||||
constructor(bstream) {
|
constructor(bstream) {
|
||||||
if (typeof bstream != typeof {} || !bstream.readNumber || typeof bstream.readNumber != typeof function () { }) {
|
if (typeof bstream != typeof {} || !bstream.readNumber || typeof bstream.readNumber != typeof function () { }) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -125,9 +119,9 @@ class ZipLocalFile {
|
||||||
let foundDataDescriptor = false;
|
let foundDataDescriptor = false;
|
||||||
let numBytesSeeked = 0;
|
let numBytesSeeked = 0;
|
||||||
while (!foundDataDescriptor) {
|
while (!foundDataDescriptor) {
|
||||||
while (bstream.peekNumber(4) !== zLocalFileHeaderSignature &&
|
while (bstream.peekNumber(4) !== LOCAL_FILE_HEADER_SIG &&
|
||||||
bstream.peekNumber(4) !== zArchiveExtraDataSignature &&
|
bstream.peekNumber(4) !== ARCHIVE_EXTRA_DATA_SIG &&
|
||||||
bstream.peekNumber(4) !== zCentralFileHeaderSignature) {
|
bstream.peekNumber(4) !== CENTRAL_FILE_HEADER_SIG) {
|
||||||
numBytesSeeked++;
|
numBytesSeeked++;
|
||||||
bstream.readBytes(1);
|
bstream.readBytes(1);
|
||||||
}
|
}
|
||||||
|
@ -143,7 +137,7 @@ class ZipLocalFile {
|
||||||
|
|
||||||
// From the PKZIP App Note: "The signature value 0x08074b50 is also used by some ZIP
|
// From the PKZIP App Note: "The signature value 0x08074b50 is also used by some ZIP
|
||||||
// implementations as a marker for the Data Descriptor record".
|
// implementations as a marker for the Data Descriptor record".
|
||||||
if (maybeDescriptorSig === zDataDescriptorSignature) {
|
if (maybeDescriptorSig === DATA_DESCRIPTOR_SIG) {
|
||||||
if (maybeCompressedSize === (numBytesSeeked - 16)) {
|
if (maybeCompressedSize === (numBytesSeeked - 16)) {
|
||||||
foundDataDescriptor = true;
|
foundDataDescriptor = true;
|
||||||
descriptorSize = 16;
|
descriptorSize = 16;
|
||||||
|
@ -606,7 +600,7 @@ function archiveUnzip() {
|
||||||
let bstream = bytestream.tee();
|
let bstream = bytestream.tee();
|
||||||
|
|
||||||
// loop until we don't see any more local files or we find a data descriptor.
|
// loop until we don't see any more local files or we find a data descriptor.
|
||||||
while (bstream.peekNumber(4) == zLocalFileHeaderSignature) {
|
while (bstream.peekNumber(4) == LOCAL_FILE_HEADER_SIG) {
|
||||||
// Note that this could throw an error if the bstream overflows, which is caught in the
|
// Note that this could throw an error if the bstream overflows, which is caught in the
|
||||||
// message handler.
|
// message handler.
|
||||||
const oneLocalFile = new ZipLocalFile(bstream);
|
const oneLocalFile = new ZipLocalFile(bstream);
|
||||||
|
@ -636,7 +630,7 @@ function archiveUnzip() {
|
||||||
totalFilesInArchive = allLocalFiles.length;
|
totalFilesInArchive = allLocalFiles.length;
|
||||||
|
|
||||||
// archive extra data record
|
// archive extra data record
|
||||||
if (bstream.peekNumber(4) == zArchiveExtraDataSignature) {
|
if (bstream.peekNumber(4) == ARCHIVE_EXTRA_DATA_SIG) {
|
||||||
if (logToConsole) {
|
if (logToConsole) {
|
||||||
info(' Found an Archive Extra Data Signature');
|
info(' Found an Archive Extra Data Signature');
|
||||||
}
|
}
|
||||||
|
@ -649,13 +643,13 @@ function archiveUnzip() {
|
||||||
|
|
||||||
// central directory structure
|
// central directory structure
|
||||||
// TODO: handle the rest of the structures (Zip64 stuff)
|
// TODO: handle the rest of the structures (Zip64 stuff)
|
||||||
if (bstream.peekNumber(4) == zCentralFileHeaderSignature) {
|
if (bstream.peekNumber(4) == CENTRAL_FILE_HEADER_SIG) {
|
||||||
if (logToConsole) {
|
if (logToConsole) {
|
||||||
info(' Found a Central File Header');
|
info(' Found a Central File Header');
|
||||||
}
|
}
|
||||||
|
|
||||||
// read all file headers
|
// read all file headers
|
||||||
while (bstream.peekNumber(4) == zCentralFileHeaderSignature) {
|
while (bstream.peekNumber(4) == CENTRAL_FILE_HEADER_SIG) {
|
||||||
bstream.readNumber(4); // signature
|
bstream.readNumber(4); // signature
|
||||||
const cdfh = {
|
const cdfh = {
|
||||||
versionMadeBy: bstream.readNumber(2),
|
versionMadeBy: bstream.readNumber(2),
|
||||||
|
@ -688,7 +682,7 @@ function archiveUnzip() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// digital signature
|
// digital signature
|
||||||
if (bstream.peekNumber(4) == zDigitalSignatureSignature) {
|
if (bstream.peekNumber(4) == DIGITAL_SIGNATURE_SIG) {
|
||||||
if (logToConsole) {
|
if (logToConsole) {
|
||||||
info(' Found a Digital Signature');
|
info(' Found a Digital Signature');
|
||||||
}
|
}
|
||||||
|
@ -699,7 +693,7 @@ function archiveUnzip() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let metadata = {};
|
let metadata = {};
|
||||||
if (bstream.peekNumber(4) == zEndOfCentralDirSignature) {
|
if (bstream.peekNumber(4) == END_OF_CENTRAL_DIR_SIG) {
|
||||||
bstream.readNumber(4); // signature
|
bstream.readNumber(4); // signature
|
||||||
const eocds = {
|
const eocds = {
|
||||||
numberOfThisDisk: bstream.readNumber(2),
|
numberOfThisDisk: bstream.readNumber(2),
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ByteBuffer } from '../io/bytebuffer.js';
|
import { ByteBuffer } from '../io/bytebuffer.js';
|
||||||
|
import { CENTRAL_FILE_HEADER_SIG, CRC32_MAGIC_NUMBER, END_OF_CENTRAL_DIR_SIG,
|
||||||
|
LOCAL_FILE_HEADER_SIG } from './common.js';
|
||||||
|
|
||||||
|
/** @typedef {import('./common.js').FileInfo} FileInfo */
|
||||||
|
|
||||||
/** @type {MessagePort} */
|
/** @type {MessagePort} */
|
||||||
let hostPort;
|
let hostPort;
|
||||||
|
@ -28,14 +32,6 @@ let hostPort;
|
||||||
* The client should append the bytes to a single buffer in the order they were received.
|
* The client should append the bytes to a single buffer in the order they were received.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO(bitjs): De-dupe this typedef and the one in compress.js.
|
|
||||||
/**
|
|
||||||
* @typedef FileInfo An object that is sent by the client to represent a file.
|
|
||||||
* @property {string} fileName The name of this file. TODO: Includes the path?
|
|
||||||
* @property {number} lastModTime The number of ms since the Unix epoch (1970-01-01 at midnight).
|
|
||||||
* @property {Uint8Array} fileData The raw bytes of the file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO(bitjs): Figure out where this typedef should live.
|
// TODO(bitjs): Figure out where this typedef should live.
|
||||||
/**
|
/**
|
||||||
* @typedef CompressFilesMessage A message the client sends to the implementation.
|
* @typedef CompressFilesMessage A message the client sends to the implementation.
|
||||||
|
@ -46,12 +42,6 @@ let hostPort;
|
||||||
// TODO: Support DEFLATE.
|
// TODO: Support DEFLATE.
|
||||||
// TODO: Support options that can let client choose levels of compression/performance.
|
// TODO: Support options that can let client choose levels of compression/performance.
|
||||||
|
|
||||||
// TODO(bitjs): These constants should be defined in a common isomorphic ES module.
|
|
||||||
const zLocalFileHeaderSignature = 0x04034b50;
|
|
||||||
const zCentralFileHeaderSignature = 0x02014b50;
|
|
||||||
const zEndOfCentralDirSignature = 0x06054b50;
|
|
||||||
const zCRC32MagicNumber = 0xedb88320; // 0xdebb20e3;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef CentralDirectoryFileHeaderInfo An object to be used to construct the central directory.
|
* @typedef CentralDirectoryFileHeaderInfo An object to be used to construct the central directory.
|
||||||
* @property {string} fileName
|
* @property {string} fileName
|
||||||
|
@ -93,7 +83,7 @@ function createCRC32Table() {
|
||||||
for (let n = 0; n < 256; n++) {
|
for (let n = 0; n < 256; n++) {
|
||||||
let c = n;
|
let c = n;
|
||||||
for (let k = 0; k < 8; k++) {
|
for (let k = 0; k < 8; k++) {
|
||||||
c = ((c & 1) ? (zCRC32MagicNumber ^ (c >>> 1)) : (c >>> 1));
|
c = ((c & 1) ? (CRC32_MAGIC_NUMBER ^ (c >>> 1)) : (c >>> 1));
|
||||||
}
|
}
|
||||||
table[n] = c;
|
table[n] = c;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +147,7 @@ function zipOneFile(file) {
|
||||||
/** @type {ByteBuffer} */
|
/** @type {ByteBuffer} */
|
||||||
const buffer = new ByteBuffer(fileHeaderSize + file.fileData.byteLength);
|
const buffer = new ByteBuffer(fileHeaderSize + file.fileData.byteLength);
|
||||||
|
|
||||||
buffer.writeNumber(zLocalFileHeaderSignature, 4); // Magic number.
|
buffer.writeNumber(LOCAL_FILE_HEADER_SIG, 4); // Magic number.
|
||||||
buffer.writeNumber(0x0A, 2); // Version.
|
buffer.writeNumber(0x0A, 2); // Version.
|
||||||
buffer.writeNumber(0, 2); // General Purpose Flags.
|
buffer.writeNumber(0, 2); // General Purpose Flags.
|
||||||
buffer.writeNumber(0, 2); // Compression Method. 0 = Store only.
|
buffer.writeNumber(0, 2); // Compression Method. 0 = Store only.
|
||||||
|
@ -201,7 +191,7 @@ function writeCentralFileDirectory() {
|
||||||
const buffer = new ByteBuffer(cdsLength + 22);
|
const buffer = new ByteBuffer(cdsLength + 22);
|
||||||
|
|
||||||
for (const cdInfo of centralDirectoryInfos) {
|
for (const cdInfo of centralDirectoryInfos) {
|
||||||
buffer.writeNumber(zCentralFileHeaderSignature, 4); // Magic number.
|
buffer.writeNumber(CENTRAL_FILE_HEADER_SIG, 4); // Magic number.
|
||||||
buffer.writeNumber(0, 2); // Version made by. // 0x31e
|
buffer.writeNumber(0, 2); // Version made by. // 0x31e
|
||||||
buffer.writeNumber(0, 2); // Version needed to extract (minimum). // 0x14
|
buffer.writeNumber(0, 2); // Version needed to extract (minimum). // 0x14
|
||||||
buffer.writeNumber(0, 2); // General purpose bit flag
|
buffer.writeNumber(0, 2); // General purpose bit flag
|
||||||
|
@ -222,7 +212,7 @@ function writeCentralFileDirectory() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 22 more bytes.
|
// 22 more bytes.
|
||||||
buffer.writeNumber(zEndOfCentralDirSignature, 4); // Magic number.
|
buffer.writeNumber(END_OF_CENTRAL_DIR_SIG, 4); // Magic number.
|
||||||
buffer.writeNumber(0, 2); // Number of this disk.
|
buffer.writeNumber(0, 2); // Number of this disk.
|
||||||
buffer.writeNumber(0, 2); // Disk where central directory starts.
|
buffer.writeNumber(0, 2); // Disk where central directory starts.
|
||||||
buffer.writeNumber(filesCompressed.length, 2); // Number of central directory records on this disk.
|
buffer.writeNumber(filesCompressed.length, 2); // Number of central directory records on this disk.
|
||||||
|
@ -287,7 +277,7 @@ export function connect(port) {
|
||||||
|
|
||||||
export function disconnect() {
|
export function disconnect() {
|
||||||
if (!hostPort) {
|
if (!hostPort) {
|
||||||
throw `hostPort was not connected in unzip.js`;
|
throw `hostPort was not connected in zip.js`;
|
||||||
}
|
}
|
||||||
|
|
||||||
hostPort = null;
|
hostPort = null;
|
||||||
|
|
|
@ -65,6 +65,8 @@ export class BitBuffer {
|
||||||
this.bitPtr = this.mtl ? 7 : 0;
|
this.bitPtr = this.mtl ? 7 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Be consistent with naming across classes (big-endian and little-endian).
|
||||||
|
|
||||||
/** @returns {boolean} */
|
/** @returns {boolean} */
|
||||||
getPackingDirection() {
|
getPackingDirection() {
|
||||||
return this.mtl;
|
return this.mtl;
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
* Copyright(c) 2011 antimatter15
|
* Copyright(c) 2011 antimatter15
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// TODO: Allow big-endian and little-endian, with consistent naming.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A write-only Byte buffer which uses a Uint8 Typed Array as a backing store.
|
* A write-only Byte buffer which uses a Uint8 Typed Array as a backing store.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@codedread/bitjs",
|
"name": "@codedread/bitjs",
|
||||||
"version": "1.2.1",
|
"version": "1.2.2",
|
||||||
"description": "Binary Tools for JavaScript",
|
"description": "Binary Tools for JavaScript",
|
||||||
"homepage": "https://github.com/codedread/bitjs",
|
"homepage": "https://github.com/codedread/bitjs",
|
||||||
"author": "Jeff Schiller",
|
"author": "Jeff Schiller",
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import * as fs from 'node:fs';
|
import * as fs from 'node:fs';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { Unarchiver, getUnarchiver } from '../archive/decompress.js';
|
import { getUnarchiver } from '../archive/decompress.js';
|
||||||
import { CompressStatus, Zipper, ZipCompressionMethod } from '../archive/compress.js';
|
import { CompressStatus, Zipper } from '../archive/compress.js';
|
||||||
|
import { ZipCompressionMethod } from '../archive/common.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('./archive/compress.js').FileInfo} FileInfo
|
* @typedef {import('./archive/compress.js').FileInfo} FileInfo
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue