7z-iterator 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/FileEntry.d.cts +4 -2
- package/dist/cjs/FileEntry.d.ts +4 -2
- package/dist/cjs/FileEntry.js +0 -1
- package/dist/cjs/FileEntry.js.map +1 -1
- package/dist/cjs/SevenZipIterator.js +0 -1
- package/dist/cjs/SevenZipIterator.js.map +1 -1
- package/dist/cjs/nextEntry.d.cts +2 -2
- package/dist/cjs/nextEntry.d.ts +2 -2
- package/dist/cjs/nextEntry.js.map +1 -1
- package/dist/cjs/sevenz/SevenZipParser.js +2 -8
- package/dist/cjs/sevenz/SevenZipParser.js.map +1 -1
- package/dist/cjs/sevenz/codecs/BZip2.d.cts +4 -3
- package/dist/cjs/sevenz/codecs/BZip2.d.ts +4 -3
- package/dist/cjs/sevenz/codecs/BZip2.js +11 -7
- package/dist/cjs/sevenz/codecs/BZip2.js.map +1 -1
- package/dist/cjs/types.d.cts +1 -1
- package/dist/cjs/types.d.ts +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/esm/FileEntry.d.ts +4 -2
- package/dist/esm/FileEntry.js +0 -1
- package/dist/esm/FileEntry.js.map +1 -1
- package/dist/esm/SevenZipIterator.js +0 -1
- package/dist/esm/SevenZipIterator.js.map +1 -1
- package/dist/esm/nextEntry.d.ts +2 -2
- package/dist/esm/nextEntry.js.map +1 -1
- package/dist/esm/sevenz/SevenZipParser.js +2 -8
- package/dist/esm/sevenz/SevenZipParser.js.map +1 -1
- package/dist/esm/sevenz/codecs/BZip2.d.ts +4 -3
- package/dist/esm/sevenz/codecs/BZip2.js +15 -9
- package/dist/esm/sevenz/codecs/BZip2.js.map +1 -1
- package/dist/esm/types.d.ts +1 -1
- package/dist/esm/types.js.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/codecs/BZip2.ts"],"sourcesContent":["// BZip2 codec - bzip2 compression\n// 7z stores bzip2 data with the standard BZh header\n//\n// Uses
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/codecs/BZip2.ts"],"sourcesContent":["// BZip2 codec - bzip2 compression\n// 7z stores bzip2 data with the standard BZh header\n//\n// Uses unbzip2-stream's internal bzip2 library for both sync and streaming decompression\n\nimport { bufferFrom } from 'extract-base-iterator';\nimport type { Transform } from 'readable-stream';\nimport unbzip2Stream from 'unbzip2-stream';\n\n// Access the internal bzip2 decoder from unbzip2-stream\nimport bzip2 from 'unbzip2-stream/lib/bzip2.js';\n\n/**\n * Decode BZip2 compressed data synchronously\n *\n * @param input - BZip2 compressed data (with BZh header)\n * @param _properties - Unused for BZip2\n * @param _unpackSize - Unused\n * @returns Decompressed data\n */\nexport function decodeBzip2(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer {\n const chunks: number[] = [];\n bzip2.simple(bzip2.array(input), (byte: number) => {\n chunks.push(byte);\n });\n return bufferFrom(chunks);\n}\n\n/**\n * Create a BZip2 decoder Transform stream\n * Uses unbzip2-stream for true streaming decompression (block by block)\n */\nexport function createBzip2Decoder(_properties?: Buffer, _unpackSize?: number): Transform {\n return unbzip2Stream() as Transform;\n}\n"],"names":["createBzip2Decoder","decodeBzip2","input","_properties","_unpackSize","chunks","bzip2","simple","array","byte","push","bufferFrom","unbzip2Stream"],"mappings":"AAAA,kCAAkC;AAClC,oDAAoD;AACpD,EAAE;AACF,yFAAyF;;;;;;;;;;;;QA6BzEA;eAAAA;;QAZAC;eAAAA;;;mCAfW;oEAED;4DAGR;;;;;;AAUX,SAASA,YAAYC,KAAa,EAAEC,WAAoB,EAAEC,WAAoB;IACnF,IAAMC,SAAmB,EAAE;IAC3BC,cAAK,CAACC,MAAM,CAACD,cAAK,CAACE,KAAK,CAACN,QAAQ,SAACO;QAChCJ,OAAOK,IAAI,CAACD;IACd;IACA,OAAOE,IAAAA,+BAAU,EAACN;AACpB;AAMO,SAASL,mBAAmBG,WAAoB,EAAEC,WAAoB;IAC3E,OAAOQ,IAAAA,sBAAa;AACtB"}
|
package/dist/cjs/types.d.cts
CHANGED
|
@@ -27,4 +27,4 @@ export interface SevenZipFileIterator {
|
|
|
27
27
|
next: () => SevenZipEntry | null;
|
|
28
28
|
getParser: () => SevenZipParser;
|
|
29
29
|
}
|
|
30
|
-
export type EntryCallback = (error?: Error, result?: IteratorResult<Entry>) =>
|
|
30
|
+
export type EntryCallback = (error?: Error, result?: IteratorResult<Entry>) => void;
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -27,4 +27,4 @@ export interface SevenZipFileIterator {
|
|
|
27
27
|
next: () => SevenZipEntry | null;
|
|
28
28
|
getParser: () => SevenZipParser;
|
|
29
29
|
}
|
|
30
|
-
export type EntryCallback = (error?: Error, result?: IteratorResult<Entry>) =>
|
|
30
|
+
export type EntryCallback = (error?: Error, result?: IteratorResult<Entry>) => void;
|
package/dist/cjs/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/types.ts"],"sourcesContent":["export { DirectoryEntry, LinkEntry, Lock, SymbolicLinkEntry } from 'extract-base-iterator';\n\nimport type { ExtractOptions as BaseExtractOptions, DirectoryEntry, LinkEntry, SymbolicLinkEntry } from 'extract-base-iterator';\nimport type FileEntry from './FileEntry.ts';\n\n// 7z-specific Entry union type with 7z-specific FileEntry\nexport type Entry = DirectoryEntry | FileEntry | LinkEntry | SymbolicLinkEntry;\n\n/**\n * Options for SevenZipIterator\n */\nexport interface ExtractOptions extends BaseExtractOptions {\n /**\n * Password for encrypted archives\n */\n password?: string;\n\n /**\n * Memory threshold in bytes for stream input.\n * Archives smaller than this are buffered in memory for faster processing.\n * Archives larger than this are written to a temp file.\n * Default: 100 MB (100 * 1024 * 1024)\n */\n memoryThreshold?: number;\n}\nexport { default as FileEntry } from './FileEntry.ts';\n\nimport type { SevenZipEntry, SevenZipParser } from './sevenz/SevenZipParser.ts';\n\nexport interface SevenZipFile {\n getStream: () => NodeJS.ReadableStream;\n}\n\nexport interface SevenZipFileIterator {\n next: () => SevenZipEntry | null;\n getParser: () => SevenZipParser;\n}\n\nexport type EntryCallback = (error?: Error, result?: IteratorResult<Entry>) =>
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/types.ts"],"sourcesContent":["export { DirectoryEntry, LinkEntry, Lock, SymbolicLinkEntry } from 'extract-base-iterator';\n\nimport type { ExtractOptions as BaseExtractOptions, DirectoryEntry, LinkEntry, SymbolicLinkEntry } from 'extract-base-iterator';\nimport type FileEntry from './FileEntry.ts';\n\n// 7z-specific Entry union type with 7z-specific FileEntry\nexport type Entry = DirectoryEntry | FileEntry | LinkEntry | SymbolicLinkEntry;\n\n/**\n * Options for SevenZipIterator\n */\nexport interface ExtractOptions extends BaseExtractOptions {\n /**\n * Password for encrypted archives\n */\n password?: string;\n\n /**\n * Memory threshold in bytes for stream input.\n * Archives smaller than this are buffered in memory for faster processing.\n * Archives larger than this are written to a temp file.\n * Default: 100 MB (100 * 1024 * 1024)\n */\n memoryThreshold?: number;\n}\nexport { default as FileEntry } from './FileEntry.ts';\n\nimport type { SevenZipEntry, SevenZipParser } from './sevenz/SevenZipParser.ts';\n\nexport interface SevenZipFile {\n getStream: () => NodeJS.ReadableStream;\n}\n\nexport interface SevenZipFileIterator {\n next: () => SevenZipEntry | null;\n getParser: () => SevenZipParser;\n}\n\nexport type EntryCallback = (error?: Error, result?: IteratorResult<Entry>) => void;\n"],"names":["DirectoryEntry","FileEntry","LinkEntry","Lock","SymbolicLinkEntry"],"mappings":";;;;;;;;;;;QAASA;eAAAA,mCAAc;;QAyBHC;eAAAA,oBAAS;;QAzBJC;eAAAA,8BAAS;;QAAEC;eAAAA,yBAAI;;QAAEC;eAAAA,sCAAiB;;;mCAAQ;kEAyB9B"}
|
package/dist/esm/FileEntry.d.ts
CHANGED
|
@@ -6,7 +6,9 @@ export default class SevenZipFileEntry extends FileEntry {
|
|
|
6
6
|
private entry;
|
|
7
7
|
private parser;
|
|
8
8
|
constructor(attributes: FileAttributes, entry: SevenZipEntry, parser: SevenZipParser, lock: Lock);
|
|
9
|
-
create(dest: string,
|
|
10
|
-
|
|
9
|
+
create(dest: string, callback: NoParamCallback): void;
|
|
10
|
+
create(dest: string, options: ExtractOptions, callback: NoParamCallback): void;
|
|
11
|
+
create(dest: string, options?: ExtractOptions): Promise<boolean>;
|
|
12
|
+
_writeFile(fullPath: string, _options: ExtractOptions, callback: NoParamCallback): void;
|
|
11
13
|
destroy(): void;
|
|
12
14
|
}
|
package/dist/esm/FileEntry.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/FileEntry.ts"],"sourcesContent":["import { type FileAttributes, FileEntry, type Lock, type NoParamCallback, waitForAccess } from 'extract-base-iterator';\nimport fs from 'fs';\nimport oo from 'on-one';\nimport type { SevenZipEntry, SevenZipParser } from './sevenz/SevenZipParser.ts';\nimport type { ExtractOptions } from './types.ts';\n\nexport default class SevenZipFileEntry extends FileEntry {\n private lock: Lock;\n private entry: SevenZipEntry;\n private parser: SevenZipParser;\n\n constructor(attributes: FileAttributes, entry: SevenZipEntry, parser: SevenZipParser, lock: Lock) {\n super(attributes);\n this.entry = entry;\n this.parser = parser;\n this.lock = lock;\n this.lock.retain();\n }\n\n create(dest: string, options: ExtractOptions | NoParamCallback, callback
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/FileEntry.ts"],"sourcesContent":["import { type FileAttributes, FileEntry, type Lock, type NoParamCallback, waitForAccess } from 'extract-base-iterator';\nimport fs from 'fs';\nimport oo from 'on-one';\nimport type { SevenZipEntry, SevenZipParser } from './sevenz/SevenZipParser.ts';\nimport type { ExtractOptions } from './types.ts';\n\nexport default class SevenZipFileEntry extends FileEntry {\n private lock: Lock;\n private entry: SevenZipEntry;\n private parser: SevenZipParser;\n\n constructor(attributes: FileAttributes, entry: SevenZipEntry, parser: SevenZipParser, lock: Lock) {\n super(attributes);\n this.entry = entry;\n this.parser = parser;\n this.lock = lock;\n this.lock.retain();\n }\n\n create(dest: string, callback: NoParamCallback): void;\n create(dest: string, options: ExtractOptions, callback: NoParamCallback): void;\n create(dest: string, options?: ExtractOptions): Promise<boolean>;\n create(dest: string, options?: ExtractOptions | NoParamCallback, callback?: NoParamCallback): void | Promise<boolean> {\n if (typeof options === 'function') {\n callback = options;\n options = null;\n }\n\n if (typeof callback === 'function') {\n options = options || {};\n return FileEntry.prototype.create.call(this, dest, options, (err?: Error) => {\n callback(err);\n if (this.lock) {\n this.lock.release();\n this.lock = null;\n }\n });\n }\n return new Promise((resolve, reject) => {\n this.create(dest, options as ExtractOptions, (err?: Error, done?: boolean) => {\n err ? reject(err) : resolve(done);\n });\n });\n }\n\n _writeFile(fullPath: string, _options: ExtractOptions, callback: NoParamCallback): void {\n if (!this.entry || !this.parser) {\n callback(new Error('7z FileEntry missing entry. Check for calling create multiple times'));\n return;\n }\n\n // Use callback-based async decompression\n this.parser.getEntryStreamAsync(this.entry, (err, stream) => {\n if (err) return callback(err);\n if (!stream) return callback(new Error('No stream returned'));\n\n const res = stream.pipe(fs.createWriteStream(fullPath));\n oo(res, ['error', 'close', 'finish'], (writeErr?: Error) => {\n writeErr ? callback(writeErr) : waitForAccess(fullPath, callback);\n });\n });\n }\n\n destroy() {\n FileEntry.prototype.destroy.call(this);\n this.entry = null;\n this.parser = null;\n if (this.lock) {\n this.lock.release();\n this.lock = null;\n }\n }\n}\n"],"names":["FileEntry","waitForAccess","fs","oo","SevenZipFileEntry","create","dest","options","callback","prototype","call","err","lock","release","Promise","resolve","reject","done","_writeFile","fullPath","_options","entry","parser","Error","getEntryStreamAsync","stream","res","pipe","createWriteStream","writeErr","destroy","attributes","retain"],"mappings":"AAAA,SAA8BA,SAAS,EAAmCC,aAAa,QAAQ,wBAAwB;AACvH,OAAOC,QAAQ,KAAK;AACpB,OAAOC,QAAQ,SAAS;AAIT,IAAA,AAAMC,oBAAN,MAAMA,0BAA0BJ;IAgB7CK,OAAOC,IAAY,EAAEC,OAA0C,EAAEC,QAA0B,EAA2B;QACpH,IAAI,OAAOD,YAAY,YAAY;YACjCC,WAAWD;YACXA,UAAU;QACZ;QAEA,IAAI,OAAOC,aAAa,YAAY;YAClCD,UAAUA,WAAW,CAAC;YACtB,OAAOP,UAAUS,SAAS,CAACJ,MAAM,CAACK,IAAI,CAAC,IAAI,EAAEJ,MAAMC,SAAS,CAACI;gBAC3DH,SAASG;gBACT,IAAI,IAAI,CAACC,IAAI,EAAE;oBACb,IAAI,CAACA,IAAI,CAACC,OAAO;oBACjB,IAAI,CAACD,IAAI,GAAG;gBACd;YACF;QACF;QACA,OAAO,IAAIE,QAAQ,CAACC,SAASC;YAC3B,IAAI,CAACX,MAAM,CAACC,MAAMC,SAA2B,CAACI,KAAaM;gBACzDN,MAAMK,OAAOL,OAAOI,QAAQE;YAC9B;QACF;IACF;IAEAC,WAAWC,QAAgB,EAAEC,QAAwB,EAAEZ,QAAyB,EAAQ;QACtF,IAAI,CAAC,IAAI,CAACa,KAAK,IAAI,CAAC,IAAI,CAACC,MAAM,EAAE;YAC/Bd,SAAS,IAAIe,MAAM;YACnB;QACF;QAEA,yCAAyC;QACzC,IAAI,CAACD,MAAM,CAACE,mBAAmB,CAAC,IAAI,CAACH,KAAK,EAAE,CAACV,KAAKc;YAChD,IAAId,KAAK,OAAOH,SAASG;YACzB,IAAI,CAACc,QAAQ,OAAOjB,SAAS,IAAIe,MAAM;YAEvC,MAAMG,MAAMD,OAAOE,IAAI,CAACzB,GAAG0B,iBAAiB,CAACT;YAC7ChB,GAAGuB,KAAK;gBAAC;gBAAS;gBAAS;aAAS,EAAE,CAACG;gBACrCA,WAAWrB,SAASqB,YAAY5B,cAAckB,UAAUX;YAC1D;QACF;IACF;IAEAsB,UAAU;QACR9B,UAAUS,SAAS,CAACqB,OAAO,CAACpB,IAAI,CAAC,IAAI;QACrC,IAAI,CAACW,KAAK,GAAG;QACb,IAAI,CAACC,MAAM,GAAG;QACd,IAAI,IAAI,CAACV,IAAI,EAAE;YACb,IAAI,CAACA,IAAI,CAACC,OAAO;YACjB,IAAI,CAACD,IAAI,GAAG;QACd;IACF;IA5DA,YAAYmB,UAA0B,EAAEV,KAAoB,EAAEC,MAAsB,EAAEV,IAAU,CAAE;QAChG,KAAK,CAACmB;QACN,IAAI,CAACV,KAAK,GAAGA;QACb,IAAI,CAACC,MAAM,GAAGA;QACd,IAAI,CAACV,IAAI,GAAGA;QACZ,IAAI,CAACA,IAAI,CAACoB,MAAM;IAClB;AAuDF;AAlEA,SAAqB5B,+BAkEpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/SevenZipIterator.ts"],"sourcesContent":["import BaseIterator, { Lock } from 'extract-base-iterator';\nimport fs from 'fs';\nimport { rmSync } from 'fs-remove-compat';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport shortHash from 'short-hash';\nimport tempSuffix from 'temp-suffix';\nimport { tmpdir } from './compat.ts';\nimport streamToSource, { type SourceResult } from './lib/streamToSource.ts';\nimport nextEntry from './nextEntry.ts';\nimport { setPassword } from './sevenz/codecs/index.ts';\nimport { type ArchiveSource, FileSource, type SevenZipEntry, SevenZipParser } from './sevenz/SevenZipParser.ts';\n\nimport type { Entry, ExtractOptions, SevenZipFileIterator } from './types.ts';\n\n/**\n * Iterator wrapper around SevenZipParser entries\n */\nclass EntryIterator implements SevenZipFileIterator {\n private parser: SevenZipParser;\n private entries: SevenZipEntry[];\n private index = 0;\n\n constructor(parser: SevenZipParser) {\n this.parser = parser;\n this.entries = parser.getEntries();\n }\n\n next(): SevenZipEntry | null {\n if (this.index >= this.entries.length) {\n return null;\n }\n return this.entries[this.index++];\n }\n\n getParser(): SevenZipParser {\n return this.parser;\n }\n}\n\nexport default class SevenZipIterator extends BaseIterator<Entry> {\n lock: Lock | null;\n iterator: SevenZipFileIterator;\n\n constructor(source: string | NodeJS.ReadableStream, options: ExtractOptions = {}) {\n super(options);\n this.lock = new Lock();\n this.lock.onDestroy = (err) => BaseIterator.prototype.end.call(this, err);\n const queue = new Queue(1);\n let cancelled = false;\n let archiveSource: ArchiveSource | null = null;\n const setup = ():
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/SevenZipIterator.ts"],"sourcesContent":["import BaseIterator, { Lock } from 'extract-base-iterator';\nimport fs from 'fs';\nimport { rmSync } from 'fs-remove-compat';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport shortHash from 'short-hash';\nimport tempSuffix from 'temp-suffix';\nimport { tmpdir } from './compat.ts';\nimport streamToSource, { type SourceResult } from './lib/streamToSource.ts';\nimport nextEntry from './nextEntry.ts';\nimport { setPassword } from './sevenz/codecs/index.ts';\nimport { type ArchiveSource, FileSource, type SevenZipEntry, SevenZipParser } from './sevenz/SevenZipParser.ts';\n\nimport type { Entry, ExtractOptions, SevenZipFileIterator } from './types.ts';\n\n/**\n * Iterator wrapper around SevenZipParser entries\n */\nclass EntryIterator implements SevenZipFileIterator {\n private parser: SevenZipParser;\n private entries: SevenZipEntry[];\n private index = 0;\n\n constructor(parser: SevenZipParser) {\n this.parser = parser;\n this.entries = parser.getEntries();\n }\n\n next(): SevenZipEntry | null {\n if (this.index >= this.entries.length) {\n return null;\n }\n return this.entries[this.index++];\n }\n\n getParser(): SevenZipParser {\n return this.parser;\n }\n}\n\nexport default class SevenZipIterator extends BaseIterator<Entry> {\n lock: Lock | null;\n iterator: SevenZipFileIterator;\n\n constructor(source: string | NodeJS.ReadableStream, options: ExtractOptions = {}) {\n super(options);\n this.lock = new Lock();\n this.lock.onDestroy = (err) => BaseIterator.prototype.end.call(this, err);\n const queue = new Queue(1);\n let cancelled = false;\n let archiveSource: ArchiveSource | null = null;\n const setup = (): void => {\n cancelled = true;\n };\n this.processing.push(setup);\n\n // Set password (or clear if not provided)\n setPassword(options.password || null);\n\n if (typeof source === 'string') {\n // File path input - use FileSource directly\n queue.defer((cb: (err?: Error) => void) => {\n fs.stat(source, (statErr, stats) => {\n if (this.done || cancelled) return;\n if (statErr) return cb(statErr);\n\n fs.open(source, 'r', (err, fd) => {\n if (this.done || cancelled) return;\n if (err) return cb(err);\n\n archiveSource = new FileSource(fd, stats.size);\n // Register cleanup for file descriptor\n this.lock.registerCleanup(() => {\n fs.closeSync(fd);\n });\n cb();\n });\n });\n });\n } else {\n // Stream input - use hybrid memory/temp-file approach\n // Register cleanup for source stream\n const stream = source as NodeJS.ReadableStream;\n this.lock.registerCleanup(() => {\n const s = stream as NodeJS.ReadableStream & { destroy?: () => void };\n if (typeof s.destroy === 'function') s.destroy();\n });\n\n const tempPath = path.join(tmpdir(), '7z-iterator', shortHash(process.cwd()), tempSuffix('tmp.7z'));\n queue.defer((cb: (err?: Error) => void) => {\n streamToSource(\n source,\n {\n memoryThreshold: options.memoryThreshold,\n tempPath: tempPath,\n },\n (err?: Error, result?: SourceResult) => {\n if (this.done || cancelled) return;\n if (err) return cb(err);\n if (!result) return cb(new Error('No result from streamToSource'));\n\n archiveSource = result.source;\n if (result.fd !== undefined) {\n const fd = result.fd;\n // Register cleanup for file descriptor\n this.lock.registerCleanup(() => {\n fs.closeSync(fd);\n });\n }\n if (result.tempPath) {\n const tp = result.tempPath;\n // Register cleanup for temp file\n this.lock.registerCleanup(() => {\n try {\n rmSync(tp);\n } catch (_e) {\n /* ignore */\n }\n });\n }\n cb();\n }\n );\n });\n }\n\n // Parse and build iterator\n queue.defer((cb: (err?: Error) => void) => {\n if (this.done || cancelled) return;\n if (!archiveSource) return cb(new Error('No archive source'));\n\n try {\n const parser = new SevenZipParser(archiveSource);\n parser.parse();\n this.iterator = new EntryIterator(parser);\n cb();\n } catch (parseErr) {\n cb(parseErr as Error);\n }\n });\n\n // start processing\n queue.await((err?: Error) => {\n this.processing.remove(setup);\n if (this.done || cancelled) return;\n err ? this.end(err) : this.push(nextEntry);\n });\n }\n\n end(err?: Error) {\n if (this.lock) {\n const lock = this.lock;\n this.lock = null; // Clear before release to prevent re-entrancy\n lock.err = err;\n lock.release();\n }\n // Don't call base end here - Lock.__destroy() handles it\n this.iterator = null;\n }\n}\n"],"names":["BaseIterator","Lock","fs","rmSync","path","Queue","shortHash","tempSuffix","tmpdir","streamToSource","nextEntry","setPassword","FileSource","SevenZipParser","EntryIterator","next","index","entries","length","getParser","parser","getEntries","SevenZipIterator","end","err","lock","release","iterator","source","options","onDestroy","prototype","call","queue","cancelled","archiveSource","setup","processing","push","password","defer","cb","stat","statErr","stats","done","open","fd","size","registerCleanup","closeSync","stream","s","destroy","tempPath","join","process","cwd","memoryThreshold","result","Error","undefined","tp","_e","parse","parseErr","await","remove"],"mappings":"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"}
|
package/dist/esm/nextEntry.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type SevenZipIterator from './SevenZipIterator.js';
|
|
2
2
|
import type { Entry, EntryCallback } from './types.js';
|
|
3
|
-
export type NextCallback = (error?: Error, entry?: Entry) =>
|
|
4
|
-
export default function nextEntry<_T>(iterator: SevenZipIterator, callback: EntryCallback):
|
|
3
|
+
export type NextCallback = (error?: Error, entry?: Entry) => void;
|
|
4
|
+
export default function nextEntry<_T>(iterator: SevenZipIterator, callback: EntryCallback): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/nextEntry.ts"],"sourcesContent":["import once from 'call-once-fn';\nimport { type DirectoryAttributes, DirectoryEntry, type FileAttributes, type LinkAttributes, SymbolicLinkEntry } from 'extract-base-iterator';\nimport compact from 'lodash.compact';\nimport path from 'path';\nimport FileEntry from './FileEntry.ts';\nimport type SevenZipIterator from './SevenZipIterator.ts';\nimport type { SevenZipEntry } from './sevenz/SevenZipParser.ts';\nimport type { Entry, EntryCallback } from './types.ts';\n\nexport type NextCallback = (error?: Error, entry?: Entry) =>
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/nextEntry.ts"],"sourcesContent":["import once from 'call-once-fn';\nimport { type DirectoryAttributes, DirectoryEntry, type FileAttributes, type LinkAttributes, SymbolicLinkEntry } from 'extract-base-iterator';\nimport compact from 'lodash.compact';\nimport path from 'path';\nimport FileEntry from './FileEntry.ts';\nimport type SevenZipIterator from './SevenZipIterator.ts';\nimport type { SevenZipEntry } from './sevenz/SevenZipParser.ts';\nimport type { Entry, EntryCallback } from './types.ts';\n\nexport type NextCallback = (error?: Error, entry?: Entry) => void;\n\n// Entry attributes object that gets mutated in switch - union of possible shapes\n// mtime is number for FileAttributes compatibility (timestamp in ms)\ntype EntryAttributesBuilder = {\n path: string;\n basename: string;\n mtime: number;\n mode: number;\n type?: 'file' | 'directory';\n size?: number;\n};\n\nexport default function nextEntry<_T>(iterator: SevenZipIterator, callback: EntryCallback): void {\n if (!iterator.iterator) {\n callback(new Error('iterator missing'));\n return;\n }\n\n let entry: SevenZipEntry | null = null;\n entry = iterator.iterator.next();\n\n const nextCallback = once((err?: Error, entry?: Entry) => {\n // keep processing\n if (entry) iterator.push(nextEntry);\n err ? callback(err) : callback(null, entry ? { done: false, value: entry } : { done: true, value: null });\n }) as NextCallback;\n\n // done: signal iteration is complete (guard against stale lock)\n if (!iterator.lock || iterator.isDone() || !entry) return callback(null, { done: true, value: null });\n\n // Skip anti-files (these mark files to delete in delta archives)\n if (entry.isAntiFile) {\n iterator.push(nextEntry);\n return callback(null, null);\n }\n\n // Determine type from entry\n const type = entry.type;\n\n // Default modes (decimal values for Node 0.8 compatibility)\n // 0o755 = 493, 0o644 = 420\n const defaultMode = type === 'directory' ? 493 : 420;\n\n // Build attributes from 7z entry\n // mtime must be timestamp (number) for FileAttributes compatibility\n const mtimeDate = entry.mtime || new Date();\n const attributes: EntryAttributesBuilder = {\n path: compact(entry.path.split(path.sep)).join(path.sep),\n basename: entry.name,\n mtime: mtimeDate.getTime(),\n mode: entry.mode !== undefined ? entry.mode : defaultMode,\n };\n\n switch (type) {\n case 'directory':\n attributes.type = 'directory';\n return nextCallback(null, new DirectoryEntry(attributes as DirectoryAttributes));\n\n case 'link': {\n // For symlinks, the file content IS the symlink target path\n // Read the content to get the linkpath for SymbolicLinkEntry\n const parser = iterator.iterator.getParser();\n\n // Use callback-based async decompression\n parser.getEntryStreamAsync(entry, (err, stream) => {\n if (err) return nextCallback(err);\n if (!stream) return nextCallback(new Error('No stream returned'));\n\n const chunks: Buffer[] = [];\n\n stream.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n stream.on('end', () => {\n const linkpath = Buffer.concat(chunks).toString('utf8');\n\n const linkAttributes: LinkAttributes = {\n path: attributes.path,\n mtime: attributes.mtime,\n mode: attributes.mode,\n linkpath: linkpath,\n };\n\n nextCallback(null, new SymbolicLinkEntry(linkAttributes));\n });\n stream.on('error', (streamErr: Error) => {\n nextCallback(streamErr);\n });\n });\n return;\n }\n\n case 'file': {\n attributes.type = 'file';\n attributes.size = entry.size;\n const parser2 = iterator.iterator.getParser();\n return nextCallback(null, new FileEntry(attributes as FileAttributes, entry, parser2, iterator.lock));\n }\n }\n\n return callback(new Error(`Unrecognized entry type: ${type}`));\n}\n"],"names":["once","DirectoryEntry","SymbolicLinkEntry","compact","path","FileEntry","nextEntry","iterator","callback","Error","entry","next","nextCallback","err","push","done","value","lock","isDone","isAntiFile","type","defaultMode","mtimeDate","mtime","Date","attributes","split","sep","join","basename","name","getTime","mode","undefined","parser","getParser","getEntryStreamAsync","stream","chunks","on","chunk","linkpath","Buffer","concat","toString","linkAttributes","streamErr","size","parser2"],"mappings":"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"}
|
|
@@ -548,10 +548,7 @@ export { BufferSource, FileSource } from './ArchiveSource.js';
|
|
|
548
548
|
*/ getDecompressedFolderAsync(folderIndex, callback) {
|
|
549
549
|
const self = this;
|
|
550
550
|
// Check cache first
|
|
551
|
-
if (this.decompressedCache[folderIndex])
|
|
552
|
-
callback(null, this.decompressedCache[folderIndex]);
|
|
553
|
-
return;
|
|
554
|
-
}
|
|
551
|
+
if (this.decompressedCache[folderIndex]) return callback(null, this.decompressedCache[folderIndex]);
|
|
555
552
|
if (!this.streamsInfo) {
|
|
556
553
|
callback(createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER));
|
|
557
554
|
return;
|
|
@@ -630,10 +627,7 @@ export { BufferSource, FileSource } from './ArchiveSource.js';
|
|
|
630
627
|
return;
|
|
631
628
|
}
|
|
632
629
|
decompressWithStream(input, idx, (err, output)=>{
|
|
633
|
-
if (err)
|
|
634
|
-
callback(err);
|
|
635
|
-
return;
|
|
636
|
-
}
|
|
630
|
+
if (err) return callback(err);
|
|
637
631
|
decompressChain(output, idx + 1);
|
|
638
632
|
});
|
|
639
633
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/SevenZipParser.ts"],"sourcesContent":["/**\n * SevenZipParser - Main 7z archive parser\n *\n * Handles reading archive structure and providing file streams.\n *\n * Parser Flow:\n * 1. Read signature header (32 bytes) to get header location\n * 2. Read encoded header from nextHeaderOffset\n * 3. If header is compressed, decompress it first\n * 4. Parse streams info (folder structure, pack positions)\n * 5. Parse files info (names, sizes, attributes)\n * 6. Build entry list for iteration\n *\n * Decompression:\n * - 7z uses \"folders\" as decompression units\n * - Solid archives: multiple files share one folder (decompress once)\n * - Non-solid: one file per folder\n * - Supports LZMA, LZMA2, COPY, BCJ2, and other codecs\n */\n\nimport { crc32 } from 'extract-base-iterator';\nimport oo from 'on-one';\nimport Stream from 'stream';\nimport type { ArchiveSource } from './ArchiveSource.ts';\nimport { decodeBcj2Multi, getCodec, getCodecName, isBcj2Codec, isCodecSupported } from './codecs/index.ts';\n\n// Use native streams when available, readable-stream only for Node 0.x\nconst major = +process.versions.node.split('.')[0];\nlet PassThrough: typeof Stream.PassThrough;\nif (major > 0) {\n PassThrough = Stream.PassThrough;\n} else {\n PassThrough = require('readable-stream').PassThrough;\n}\ntype Readable = Stream.Readable;\n\nimport { type CodedError, createCodedError, ErrorCode, FileAttribute, PropertyId, SIGNATURE_HEADER_SIZE } from './constants.ts';\nimport { type FileInfo, parseEncodedHeader, parseHeaderContent, parseSignatureHeader, type SignatureHeader, type StreamsInfo } from './headers.ts';\nimport { readNumber } from './NumberCodec.ts';\n\n// Re-export for backwards compatibility\nexport { type ArchiveSource, BufferSource, FileSource } from './ArchiveSource.ts';\n\n// Callback type for async operations\ntype DecompressCallback = (err: Error | null, data?: Buffer) => void;\n\n// Entry type for iteration\nexport interface SevenZipEntry {\n name: string;\n path: string;\n type: 'file' | 'directory' | 'link';\n size: number;\n mtime?: Date;\n atime?: Date;\n ctime?: Date;\n mode?: number;\n isAntiFile: boolean;\n // Internal tracking\n _folderIndex: number;\n _streamIndex: number; // Global stream index\n _streamIndexInFolder: number; // Stream index within folder (for solid archives)\n _hasStream: boolean;\n _crc?: number; // Expected CRC32 for this file (if present in archive)\n}\n\n/**\n * SevenZipParser - parses 7z archives and provides entry iteration\n */\nexport class SevenZipParser {\n private source: ArchiveSource;\n private signature: SignatureHeader | null = null;\n private streamsInfo: StreamsInfo | null = null;\n private filesInfo: FileInfo[] = [];\n private entries: SevenZipEntry[] = [];\n private parsed = false;\n // Smart cache for decompressed solid blocks\n // Only caches when multiple files share a block, releases when last file extracted\n private decompressedCache: { [key: number]: Buffer } = {};\n // Track files per folder and how many have been extracted\n private filesPerFolder: { [key: number]: number } = {};\n private extractedPerFolder: { [key: number]: number } = {};\n\n constructor(source: ArchiveSource) {\n this.source = source;\n }\n\n /**\n * Parse the archive structure\n * Must be called before iterating entries\n */\n parse(): void {\n if (this.parsed) return;\n\n // Read signature header\n const sigBuf = this.source.read(0, SIGNATURE_HEADER_SIZE);\n if (sigBuf.length < SIGNATURE_HEADER_SIZE) {\n throw createCodedError('Archive too small', ErrorCode.TRUNCATED_ARCHIVE);\n }\n\n this.signature = parseSignatureHeader(sigBuf);\n\n // Read encoded header\n const headerOffset = SIGNATURE_HEADER_SIZE + this.signature.nextHeaderOffset;\n const headerBuf = this.source.read(headerOffset, this.signature.nextHeaderSize);\n\n if (headerBuf.length < this.signature.nextHeaderSize) {\n throw createCodedError('Truncated header', ErrorCode.TRUNCATED_ARCHIVE);\n }\n\n // Parse encoded header (may need decompression)\n try {\n const headerResult = parseEncodedHeader(headerBuf, this.signature.nextHeaderCRC);\n this.streamsInfo = headerResult.streamsInfo || null;\n this.filesInfo = headerResult.filesInfo;\n } catch (err: unknown) {\n const codedErr = err as CodedError;\n if (codedErr && codedErr.code === ErrorCode.COMPRESSED_HEADER) {\n // Header is compressed - need to decompress first\n this.handleCompressedHeader(headerBuf);\n } else {\n throw err;\n }\n }\n\n // Build entries list\n this.buildEntries();\n this.parsed = true;\n }\n\n /**\n * Handle compressed header (kEncodedHeader)\n */\n private handleCompressedHeader(headerBuf: Buffer): void {\n // Parse the encoded header info to get decompression parameters\n let offset = 1; // Skip kEncodedHeader byte\n\n // Should have StreamsInfo for the header itself\n const propertyId = headerBuf[offset++];\n if (propertyId !== PropertyId.kMainStreamsInfo && propertyId !== PropertyId.kPackInfo) {\n throw createCodedError('Expected StreamsInfo in encoded header', ErrorCode.CORRUPT_HEADER);\n }\n\n // For now, we parse the streams info from the encoded header block\n // This tells us how to decompress the actual header\n\n // Read pack info from the encoded header structure\n const packInfoResult = this.parseEncodedHeaderStreams(headerBuf, 1);\n\n // Calculate compressed header position\n // For simple archives: header is at SIGNATURE_HEADER_SIZE + packPos\n // For BCJ2/complex archives: header may be at the END of pack data area\n // The pack data area ends at nextHeaderOffset (where encoded header starts)\n const compressedStart = SIGNATURE_HEADER_SIZE + packInfoResult.packPos;\n const compressedData = this.source.read(compressedStart, packInfoResult.packSize);\n\n // Decompress using the specified codec\n const codec = getCodec(packInfoResult.codecId);\n let decompressedHeader: Buffer | null = null;\n\n // Try decompressing from the calculated position first\n try {\n decompressedHeader = codec.decode(compressedData, packInfoResult.properties, packInfoResult.unpackSize);\n // Verify CRC if present\n if (packInfoResult.unpackCRC !== undefined) {\n const actualCRC = crc32(decompressedHeader);\n if (actualCRC !== packInfoResult.unpackCRC) {\n decompressedHeader = null; // CRC mismatch, need to search\n }\n }\n } catch {\n decompressedHeader = null; // Decompression failed, need to search\n }\n\n // If initial decompression failed, search for the correct position as a fallback\n // This handles edge cases where packPos doesn't point directly to header pack data\n if (decompressedHeader === null && this.signature) {\n const packAreaEnd = SIGNATURE_HEADER_SIZE + this.signature.nextHeaderOffset;\n const searchStart = packAreaEnd - packInfoResult.packSize;\n const searchEnd = Math.max(SIGNATURE_HEADER_SIZE, compressedStart - 100000);\n\n // Scan for LZMA data starting with 0x00 (range coder init)\n // Try each candidate and validate with CRC\n const scanChunkSize = 4096;\n searchLoop: for (let chunkStart = searchStart; chunkStart >= searchEnd; chunkStart -= scanChunkSize) {\n const chunk = this.source.read(chunkStart, scanChunkSize + packInfoResult.packSize);\n for (let i = 0; i < Math.min(chunk.length, scanChunkSize); i++) {\n if (chunk[i] === 0x00) {\n const candidateData = chunk.subarray(i, i + packInfoResult.packSize);\n if (candidateData.length === packInfoResult.packSize) {\n try {\n const candidateDecompressed = codec.decode(candidateData, packInfoResult.properties, packInfoResult.unpackSize);\n if (packInfoResult.unpackCRC !== undefined) {\n const candCRC = crc32(candidateDecompressed);\n if (candCRC === packInfoResult.unpackCRC) {\n decompressedHeader = candidateDecompressed;\n break searchLoop;\n }\n } else {\n decompressedHeader = candidateDecompressed;\n break searchLoop;\n }\n } catch {\n // Decompression failed, continue searching\n }\n }\n }\n }\n }\n }\n\n if (decompressedHeader === null) {\n throw createCodedError('Failed to decompress header - could not find valid LZMA data', ErrorCode.CORRUPT_HEADER);\n }\n\n // Now parse the decompressed header\n // It should start with kHeader\n let decompOffset = 0;\n const headerId = decompressedHeader[decompOffset++];\n if (headerId !== PropertyId.kHeader) {\n throw createCodedError('Expected kHeader in decompressed header', ErrorCode.CORRUPT_HEADER);\n }\n\n // Parse the decompressed header using shared function from headers.ts\n const result = parseHeaderContent(decompressedHeader, decompOffset);\n this.streamsInfo = result.streamsInfo || null;\n this.filesInfo = result.filesInfo;\n }\n\n /**\n * Parse streams info from encoded header block\n * This is a simplified parser for the header's own compression info\n */\n private parseEncodedHeaderStreams(\n buf: Buffer,\n offset: number\n ): {\n packPos: number;\n packSize: number;\n unpackSize: number;\n codecId: number[];\n properties?: Buffer;\n unpackCRC?: number;\n } {\n // This is a simplified parser for the encoded header's own streams info\n let packPos = 0;\n let packSize = 0;\n let unpackSize = 0;\n let codecId: number[] = [];\n let properties: Buffer | undefined;\n let unpackCRC: number | undefined;\n\n while (offset < buf.length) {\n const propertyId = buf[offset++];\n\n if (propertyId === PropertyId.kEnd) {\n break;\n }\n\n switch (propertyId) {\n case PropertyId.kPackInfo: {\n const packPosResult = readNumber(buf, offset);\n packPos = packPosResult.value;\n offset += packPosResult.bytesRead;\n\n const numPackResult = readNumber(buf, offset);\n offset += numPackResult.bytesRead;\n\n // Read until kEnd\n while (buf[offset] !== PropertyId.kEnd) {\n if (buf[offset] === PropertyId.kSize) {\n offset++;\n const sizeResult = readNumber(buf, offset);\n packSize = sizeResult.value;\n offset += sizeResult.bytesRead;\n } else {\n offset++;\n }\n }\n offset++; // Skip kEnd\n break;\n }\n\n case PropertyId.kUnpackInfo:\n // Find folder/coder info\n while (offset < buf.length && buf[offset] !== PropertyId.kEnd) {\n if (buf[offset] === PropertyId.kFolder) {\n offset++;\n const numFoldersResult = readNumber(buf, offset);\n offset += numFoldersResult.bytesRead;\n offset++; // external flag\n\n // Parse coder\n const numCodersResult = readNumber(buf, offset);\n offset += numCodersResult.bytesRead;\n\n const flags = buf[offset++];\n const idSize = flags & 0x0f;\n const hasAttributes = (flags & 0x20) !== 0;\n\n codecId = [];\n for (let i = 0; i < idSize; i++) {\n codecId.push(buf[offset++]);\n }\n\n if (hasAttributes) {\n const propsLenResult = readNumber(buf, offset);\n offset += propsLenResult.bytesRead;\n properties = buf.slice(offset, offset + propsLenResult.value);\n offset += propsLenResult.value;\n }\n } else if (buf[offset] === PropertyId.kCodersUnpackSize) {\n offset++;\n // Read unpack size - needed for LZMA decoder\n const unpackSizeResult = readNumber(buf, offset);\n unpackSize = unpackSizeResult.value;\n offset += unpackSizeResult.bytesRead;\n } else if (buf[offset] === PropertyId.kCRC) {\n offset++;\n const allDefined = buf[offset++];\n if (allDefined) {\n unpackCRC = buf.readUInt32LE(offset);\n offset += 4;\n }\n } else {\n offset++;\n }\n }\n if (buf[offset] === PropertyId.kEnd) offset++;\n break;\n }\n }\n\n return { packPos: packPos, packSize: packSize, unpackSize: unpackSize, codecId: codecId, properties: properties, unpackCRC: unpackCRC };\n }\n\n /**\n * Build the entries list from parsed file info\n */\n private buildEntries(): void {\n this.entries = [];\n\n if (!this.streamsInfo) {\n // No streams info - just create entries from file info\n for (let i = 0; i < this.filesInfo.length; i++) {\n const file = this.filesInfo[i];\n this.entries.push(this.createEntry(file, 0, 0, 0));\n }\n return;\n }\n\n // Use the properly parsed numUnpackStreamsPerFolder from the archive header\n const streamsPerFolder = this.streamsInfo.numUnpackStreamsPerFolder;\n\n // Initialize files per folder count (for smart caching)\n for (let f = 0; f < streamsPerFolder.length; f++) {\n this.filesPerFolder[f] = streamsPerFolder[f];\n this.extractedPerFolder[f] = 0;\n }\n\n // Now build entries with proper folder/stream tracking\n let streamIndex = 0;\n let folderIndex = 0;\n let streamInFolder = 0;\n let folderStreamCount = streamsPerFolder[0] || 0;\n\n for (let j = 0; j < this.filesInfo.length; j++) {\n const fileInfo = this.filesInfo[j];\n\n // Get size from unpackSizes for files with streams\n let size = 0;\n if (fileInfo.hasStream && streamIndex < this.streamsInfo.unpackSizes.length) {\n size = this.streamsInfo.unpackSizes[streamIndex];\n }\n\n const entry = this.createEntry(fileInfo, size, folderIndex, streamInFolder);\n entry._streamIndex = streamIndex;\n // Set CRC if available\n if (fileInfo.hasStream && this.streamsInfo.unpackCRCs && this.streamsInfo.unpackCRCs[streamIndex] !== undefined) {\n entry._crc = this.streamsInfo.unpackCRCs[streamIndex];\n }\n this.entries.push(entry);\n\n // Advance stream tracking for files with streams\n if (fileInfo.hasStream) {\n streamIndex++;\n streamInFolder++;\n\n // Check if we've exhausted streams in this folder\n if (streamInFolder >= folderStreamCount) {\n folderIndex++;\n streamInFolder = 0;\n folderStreamCount = streamsPerFolder[folderIndex] || 0;\n }\n }\n }\n }\n\n /**\n * Create an entry from file info\n */\n private createEntry(file: FileInfo, size: number, folderIndex: number, streamInFolder: number): SevenZipEntry {\n // Determine entry type\n // Note: 7z format doesn't natively support symlinks. p7zip with -snl stores\n // symlinks as regular files with the target path as content.\n let type: 'file' | 'directory' | 'link' = 'file';\n if (file.isDirectory) {\n type = 'directory';\n }\n\n // Calculate mode from Windows attributes\n let mode: number | undefined;\n if (file.attributes !== undefined) {\n // Check for Unix extension bit\n if ((file.attributes & FileAttribute.UNIX_EXTENSION) !== 0) {\n mode = (file.attributes >>> 16) & 0xffff;\n // Check for symlink (S_IFLNK = 0xA000)\n // Note: Most 7z implementations don't preserve symlink mode bits\n if ((mode & 0xf000) === 0xa000) {\n type = 'link';\n }\n } else if (file.isDirectory) {\n mode = 493; // 0o755\n } else {\n mode = 420; // 0o644\n }\n }\n\n return {\n name: getBaseName(file.name),\n path: file.name,\n type: type,\n size: size,\n mtime: file.mtime,\n atime: file.atime,\n ctime: file.ctime,\n mode: mode,\n isAntiFile: file.isAntiFile,\n _folderIndex: folderIndex,\n _streamIndex: 0, // Set by caller\n _streamIndexInFolder: streamInFolder,\n _hasStream: file.hasStream,\n };\n }\n\n /**\n * Get the list of entries\n */\n getEntries(): SevenZipEntry[] {\n if (!this.parsed) {\n this.parse();\n }\n return this.entries;\n }\n\n /**\n * Get a readable stream for an entry's content\n */\n getEntryStream(entry: SevenZipEntry): Readable {\n if (!entry._hasStream || entry.type === 'directory') {\n // Return empty stream for directories and empty files\n const emptyStream = new PassThrough();\n emptyStream.end();\n return emptyStream;\n }\n\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n // Get folder info\n const folder = this.streamsInfo.folders[entry._folderIndex];\n if (!folder) {\n throw createCodedError('Invalid folder index', ErrorCode.CORRUPT_HEADER);\n }\n\n // Check codec support\n for (let i = 0; i < folder.coders.length; i++) {\n const coder = folder.coders[i];\n if (!isCodecSupported(coder.id)) {\n const codecName = getCodecName(coder.id);\n throw createCodedError(`Unsupported codec: ${codecName}`, ErrorCode.UNSUPPORTED_CODEC);\n }\n }\n\n // Get decompressed data for this folder (with smart caching)\n const folderIdx = entry._folderIndex;\n const data = this.getDecompressedFolder(folderIdx);\n\n // Calculate file offset within the decompressed block\n // For solid archives, multiple files are concatenated in the block\n let fileStart = 0;\n for (let m = 0; m < entry._streamIndexInFolder; m++) {\n // Sum sizes of all streams before this one in the folder\n const prevStreamGlobalIndex = entry._streamIndex - entry._streamIndexInFolder + m;\n fileStart += this.streamsInfo.unpackSizes[prevStreamGlobalIndex];\n }\n\n const fileSize = entry.size;\n\n // Create a PassThrough stream with the file data\n const outputStream = new PassThrough();\n\n // Bounds check to prevent \"oob\" error on older Node versions\n if (fileStart + fileSize > data.length) {\n throw createCodedError(`File data out of bounds: offset ${fileStart} + size ${fileSize} > decompressed length ${data.length}`, ErrorCode.DECOMPRESSION_FAILED);\n }\n\n const fileData = data.slice(fileStart, fileStart + fileSize);\n\n // Verify CRC if present\n if (entry._crc !== undefined) {\n const actualCRC = crc32(fileData);\n if (actualCRC !== entry._crc) {\n throw createCodedError(`CRC mismatch for ${entry.path}: expected ${entry._crc.toString(16)}, got ${actualCRC.toString(16)}`, ErrorCode.CRC_MISMATCH);\n }\n }\n\n outputStream.end(fileData);\n\n // Track extraction and release cache when all files from this folder are done\n this.extractedPerFolder[folderIdx] = (this.extractedPerFolder[folderIdx] || 0) + 1;\n if (this.extractedPerFolder[folderIdx] >= this.filesPerFolder[folderIdx]) {\n // All files from this folder extracted, release cache\n delete this.decompressedCache[folderIdx];\n }\n\n return outputStream;\n }\n\n /**\n * Get a readable stream for an entry's content (callback-based async version)\n * Uses streaming decompression for non-blocking I/O\n */\n getEntryStreamAsync(entry: SevenZipEntry, callback: (err: Error | null, stream?: Readable) => void): void {\n if (!entry._hasStream || entry.type === 'directory') {\n // Return empty stream for directories and empty files\n const emptyStream = new PassThrough();\n emptyStream.end();\n callback(null, emptyStream);\n return;\n }\n\n if (!this.streamsInfo) {\n callback(createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n // Get folder info\n const folder = this.streamsInfo.folders[entry._folderIndex];\n if (!folder) {\n callback(createCodedError('Invalid folder index', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n // Check codec support\n for (let i = 0; i < folder.coders.length; i++) {\n const coder = folder.coders[i];\n if (!isCodecSupported(coder.id)) {\n const codecName = getCodecName(coder.id);\n callback(createCodedError(`Unsupported codec: ${codecName}`, ErrorCode.UNSUPPORTED_CODEC));\n return;\n }\n }\n\n // Get decompressed data for this folder using async method\n const folderIdx = entry._folderIndex;\n const streamsInfo = this.streamsInfo;\n\n this.getDecompressedFolderAsync(folderIdx, (err, data) => {\n if (err) return callback(err);\n if (!data) return callback(new Error('No data returned from decompression'));\n\n // Calculate file offset within the decompressed block\n let fileStart = 0;\n for (let m = 0; m < entry._streamIndexInFolder; m++) {\n const prevStreamGlobalIndex = entry._streamIndex - entry._streamIndexInFolder + m;\n fileStart += streamsInfo.unpackSizes[prevStreamGlobalIndex];\n }\n\n const fileSize = entry.size;\n\n // Bounds check\n if (fileStart + fileSize > data.length) {\n return callback(createCodedError(`File data out of bounds: offset ${fileStart} + size ${fileSize} > decompressed length ${data.length}`, ErrorCode.DECOMPRESSION_FAILED));\n }\n\n // Create a PassThrough stream with the file data\n const outputStream = new PassThrough();\n const fileData = data.slice(fileStart, fileStart + fileSize);\n\n // Verify CRC if present\n if (entry._crc !== undefined) {\n const actualCRC = crc32(fileData);\n if (actualCRC !== entry._crc) {\n return callback(createCodedError(`CRC mismatch for ${entry.path}: expected ${entry._crc.toString(16)}, got ${actualCRC.toString(16)}`, ErrorCode.CRC_MISMATCH));\n }\n }\n\n outputStream.end(fileData);\n\n // Track extraction and release cache when all files from this folder are done\n this.extractedPerFolder[folderIdx] = (this.extractedPerFolder[folderIdx] || 0) + 1;\n if (this.extractedPerFolder[folderIdx] >= this.filesPerFolder[folderIdx]) {\n delete this.decompressedCache[folderIdx];\n }\n\n callback(null, outputStream);\n });\n }\n\n /**\n * Check if a folder uses BCJ2 codec\n */\n private folderHasBcj2(folder: { coders: { id: number[] }[] }): boolean {\n for (let i = 0; i < folder.coders.length; i++) {\n if (isBcj2Codec(folder.coders[i].id)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get decompressed data for a folder, with smart caching for solid archives\n * Only caches when multiple files share a block, releases when last file extracted\n */\n private getDecompressedFolder(folderIndex: number): Buffer {\n // Check cache first\n if (this.decompressedCache[folderIndex]) {\n return this.decompressedCache[folderIndex];\n }\n\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n const folder = this.streamsInfo.folders[folderIndex];\n\n // Check how many files remain in this folder\n const filesInFolder = this.filesPerFolder[folderIndex] || 1;\n const extractedFromFolder = this.extractedPerFolder[folderIndex] || 0;\n const remainingFiles = filesInFolder - extractedFromFolder;\n // Only cache if more than 1 file remains (including the current one being extracted)\n const shouldCache = remainingFiles > 1;\n\n // Check if this folder uses BCJ2 (requires special multi-stream handling)\n if (this.folderHasBcj2(folder)) {\n const data = this.decompressBcj2Folder(folderIndex);\n if (shouldCache) {\n this.decompressedCache[folderIndex] = data;\n }\n return data;\n }\n\n // Calculate packed data position\n let packPos = SIGNATURE_HEADER_SIZE + this.streamsInfo.packPos;\n\n // Find which pack stream this folder uses\n let packStreamIndex = 0;\n for (let j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n\n // Calculate position of this pack stream\n for (let k = 0; k < packStreamIndex; k++) {\n packPos += this.streamsInfo.packSizes[k];\n }\n\n const packSize = this.streamsInfo.packSizes[packStreamIndex];\n\n // Read packed data\n const packedData = this.source.read(packPos, packSize);\n\n // Decompress through codec chain\n let data2 = packedData;\n for (let l = 0; l < folder.coders.length; l++) {\n const coderInfo = folder.coders[l];\n const codec = getCodec(coderInfo.id);\n // Get unpack size for this coder (needed by LZMA)\n const unpackSize = folder.unpackSizes[l];\n data2 = codec.decode(data2, coderInfo.properties, unpackSize);\n }\n\n // Cache only if more files remain in this folder\n if (shouldCache) {\n this.decompressedCache[folderIndex] = data2;\n }\n\n return data2;\n }\n\n /**\n * Get decompressed data for a folder using streaming (callback-based async)\n * Uses createDecoder() streams for non-blocking decompression\n */\n private getDecompressedFolderAsync(folderIndex: number, callback: DecompressCallback): void {\n const self = this;\n\n // Check cache first\n if (this.decompressedCache[folderIndex]) {\n callback(null, this.decompressedCache[folderIndex]);\n return;\n }\n\n if (!this.streamsInfo) {\n callback(createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n const folder = this.streamsInfo.folders[folderIndex];\n\n // Check how many files remain in this folder\n const filesInFolder = this.filesPerFolder[folderIndex] || 1;\n const extractedFromFolder = this.extractedPerFolder[folderIndex] || 0;\n const remainingFiles = filesInFolder - extractedFromFolder;\n const shouldCache = remainingFiles > 1;\n\n // BCJ2 requires special handling - use sync version for now\n // TODO: Add async BCJ2 support\n if (this.folderHasBcj2(folder)) {\n try {\n const data = this.decompressBcj2Folder(folderIndex);\n if (shouldCache) {\n this.decompressedCache[folderIndex] = data;\n }\n callback(null, data);\n } catch (err) {\n callback(err as Error);\n }\n return;\n }\n\n // Calculate packed data position\n let packPos = SIGNATURE_HEADER_SIZE + this.streamsInfo.packPos;\n\n // Find which pack stream this folder uses\n let packStreamIndex = 0;\n for (let j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n\n // Calculate position of this pack stream\n for (let k = 0; k < packStreamIndex; k++) {\n packPos += this.streamsInfo.packSizes[k];\n }\n\n const packSize = this.streamsInfo.packSizes[packStreamIndex];\n\n // Read packed data\n const packedData = this.source.read(packPos, packSize);\n\n // Create decoder stream chain and decompress\n const coders = folder.coders;\n const unpackSizes = folder.unpackSizes;\n\n // Helper to decompress through a single codec stream\n function decompressWithStream(input: Buffer, coderIdx: number, cb: DecompressCallback): void {\n const coderInfo = coders[coderIdx];\n const codec = getCodec(coderInfo.id);\n const decoder = codec.createDecoder(coderInfo.properties, unpackSizes[coderIdx]);\n\n const chunks: Buffer[] = [];\n let errorOccurred = false;\n\n decoder.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n\n oo(decoder, ['error', 'end', 'close', 'finish'], (err?: Error) => {\n if (errorOccurred) return;\n if (err) {\n errorOccurred = true;\n return cb(err);\n }\n cb(null, Buffer.concat(chunks));\n });\n\n // Write input data to decoder and signal end\n decoder.end(input);\n }\n\n // Chain decompression through all codecs\n function decompressChain(input: Buffer, idx: number): void {\n if (idx >= coders.length) {\n // All done - cache and return\n if (shouldCache) {\n self.decompressedCache[folderIndex] = input;\n }\n callback(null, input);\n return;\n }\n\n decompressWithStream(input, idx, (err, output) => {\n if (err) {\n callback(err);\n return;\n }\n decompressChain(output as Buffer, idx + 1);\n });\n }\n\n // Start the chain\n decompressChain(packedData, 0);\n }\n\n /**\n * Decompress a BCJ2 folder with multi-stream handling\n * BCJ2 uses 4 input streams: main, call, jump, range coder\n */\n private decompressBcj2Folder(folderIndex: number): Buffer {\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n const folder = this.streamsInfo.folders[folderIndex];\n\n // Calculate starting pack position\n let packPos = SIGNATURE_HEADER_SIZE + this.streamsInfo.packPos;\n\n // Find which pack stream index this folder starts at\n let packStreamIndex = 0;\n for (let j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n\n // Calculate position\n for (let k = 0; k < packStreamIndex; k++) {\n packPos += this.streamsInfo.packSizes[k];\n }\n\n // Read all pack streams for this folder\n const numPackStreams = folder.packedStreams.length;\n const packStreams: Buffer[] = [];\n let currentPos = packPos;\n\n for (let p = 0; p < numPackStreams; p++) {\n const size = this.streamsInfo.packSizes[packStreamIndex + p];\n packStreams.push(this.source.read(currentPos, size));\n currentPos += size;\n }\n\n // Build a map of coder outputs\n // For BCJ2, typical structure is:\n // Coder 0: LZMA2 (main stream) - 1 in, 1 out\n // Coder 1: LZMA (call stream) - 1 in, 1 out\n // Coder 2: LZMA (jump stream) - 1 in, 1 out\n // Coder 3: BCJ2 - 4 in, 1 out\n // Pack streams map to: coder inputs not bound to other coder outputs\n\n // First, decompress each non-BCJ2 coder\n const coderOutputs: { [key: number]: Buffer } = {};\n\n // Find the BCJ2 coder\n let bcj2CoderIndex = -1;\n for (let c = 0; c < folder.coders.length; c++) {\n if (isBcj2Codec(folder.coders[c].id)) {\n bcj2CoderIndex = c;\n break;\n }\n }\n\n if (bcj2CoderIndex === -1) {\n throw createCodedError('BCJ2 coder not found in folder', ErrorCode.CORRUPT_HEADER);\n }\n\n // Build input stream index -> pack stream mapping\n // folder.packedStreams tells us which input indices are unbound and their order\n const inputToPackStream: { [key: number]: number } = {};\n for (let pi = 0; pi < folder.packedStreams.length; pi++) {\n inputToPackStream[folder.packedStreams[pi]] = pi;\n }\n\n // Build output stream index -> coder mapping\n const outputToCoder: { [key: number]: number } = {};\n let totalOutputs = 0;\n for (let co = 0; co < folder.coders.length; co++) {\n const numOut = folder.coders[co].numOutStreams;\n for (let outp = 0; outp < numOut; outp++) {\n outputToCoder[totalOutputs + outp] = co;\n }\n totalOutputs += numOut;\n }\n\n // Decompress non-BCJ2 coders (LZMA, LZMA2)\n // We need to process in dependency order\n const processed: { [key: number]: boolean } = {};\n\n const processOrder = this.getCoderProcessOrder(folder, bcj2CoderIndex);\n\n for (let po = 0; po < processOrder.length; po++) {\n const coderIdx = processOrder[po];\n if (coderIdx === bcj2CoderIndex) continue;\n\n const coder = folder.coders[coderIdx];\n const codec = getCodec(coder.id);\n\n // Find input for this coder\n let coderInputStart = 0;\n for (let ci2 = 0; ci2 < coderIdx; ci2++) {\n coderInputStart += folder.coders[ci2].numInStreams;\n }\n\n // Get input data (from pack stream)\n const inputIdx = coderInputStart;\n const packStreamIdx = inputToPackStream[inputIdx];\n const inputData = packStreams[packStreamIdx];\n\n // Decompress\n const unpackSize = folder.unpackSizes[coderIdx];\n const outputData = codec.decode(inputData, coder.properties, unpackSize);\n\n // Store in coder outputs\n let coderOutputStart = 0;\n for (let co2 = 0; co2 < coderIdx; co2++) {\n coderOutputStart += folder.coders[co2].numOutStreams;\n }\n coderOutputs[coderOutputStart] = outputData;\n processed[coderIdx] = true;\n }\n\n // Now process BCJ2\n // BCJ2 has 4 inputs, need to map them correctly\n // Standard order: main(LZMA2 output), call(LZMA output), jump(LZMA output), range(raw pack)\n let bcj2InputStart = 0;\n for (let ci3 = 0; ci3 < bcj2CoderIndex; ci3++) {\n bcj2InputStart += folder.coders[ci3].numInStreams;\n }\n\n const bcj2Inputs: Buffer[] = [];\n for (let bi = 0; bi < 4; bi++) {\n const globalIdx = bcj2InputStart + bi;\n\n // Check if this input is bound to a coder output\n let boundOutput = -1;\n for (let bp2 = 0; bp2 < folder.bindPairs.length; bp2++) {\n if (folder.bindPairs[bp2].inIndex === globalIdx) {\n boundOutput = folder.bindPairs[bp2].outIndex;\n break;\n }\n }\n\n if (boundOutput >= 0) {\n // Get from coder outputs\n bcj2Inputs.push(coderOutputs[boundOutput]);\n } else {\n // Get from pack streams\n const psIdx = inputToPackStream[globalIdx];\n bcj2Inputs.push(packStreams[psIdx]);\n }\n }\n\n // Get BCJ2 unpack size\n let bcj2OutputStart = 0;\n for (let co3 = 0; co3 < bcj2CoderIndex; co3++) {\n bcj2OutputStart += folder.coders[co3].numOutStreams;\n }\n const bcj2UnpackSize = folder.unpackSizes[bcj2OutputStart];\n\n // Memory optimization: Clear intermediate buffers to help GC\n // These are no longer needed after bcj2Inputs is built\n for (const key in coderOutputs) {\n delete coderOutputs[key];\n }\n // Clear packStreams array (allows GC to free compressed data)\n packStreams.length = 0;\n\n // Decode BCJ2\n return decodeBcj2Multi(bcj2Inputs, undefined, bcj2UnpackSize);\n }\n\n /**\n * Get processing order for coders (dependency order)\n */\n private getCoderProcessOrder(folder: { coders: { numInStreams: number; numOutStreams: number }[]; bindPairs: { inIndex: number; outIndex: number }[] }, excludeIdx: number): number[] {\n const order: number[] = [];\n const processed: { [key: number]: boolean } = {};\n\n // Simple approach: process coders that don't depend on unprocessed outputs\n let changed = true;\n while (changed) {\n changed = false;\n for (let c = 0; c < folder.coders.length; c++) {\n if (processed[c] || c === excludeIdx) continue;\n\n // Check if all inputs are satisfied\n let inputStart = 0;\n for (let i = 0; i < c; i++) {\n inputStart += folder.coders[i].numInStreams;\n }\n\n let canProcess = true;\n for (let inp = 0; inp < folder.coders[c].numInStreams; inp++) {\n const globalIdx = inputStart + inp;\n // Check if bound to an unprocessed coder\n for (let bp = 0; bp < folder.bindPairs.length; bp++) {\n if (folder.bindPairs[bp].inIndex === globalIdx) {\n // Find which coder produces this output\n const outIdx = folder.bindPairs[bp].outIndex;\n let outStart = 0;\n for (let oc = 0; oc < folder.coders.length; oc++) {\n const numOut = folder.coders[oc].numOutStreams;\n if (outIdx < outStart + numOut) {\n if (!processed[oc] && oc !== excludeIdx) {\n canProcess = false;\n }\n break;\n }\n outStart += numOut;\n }\n }\n }\n }\n\n if (canProcess) {\n order.push(c);\n processed[c] = true;\n changed = true;\n }\n }\n }\n\n return order;\n }\n\n /**\n * Close the parser and release resources\n */\n close(): void {\n if (this.source) {\n this.source.close();\n }\n }\n}\n\n/**\n * Get base name from a path\n */\nfunction getBaseName(path: string): string {\n const lastSlash = path.lastIndexOf('/');\n const lastBackslash = path.lastIndexOf('\\\\');\n const lastSep = Math.max(lastSlash, lastBackslash);\n return lastSep >= 0 ? path.slice(lastSep + 1) : path;\n}\n"],"names":["crc32","oo","Stream","decodeBcj2Multi","getCodec","getCodecName","isBcj2Codec","isCodecSupported","major","process","versions","node","split","PassThrough","require","createCodedError","ErrorCode","FileAttribute","PropertyId","SIGNATURE_HEADER_SIZE","parseEncodedHeader","parseHeaderContent","parseSignatureHeader","readNumber","BufferSource","FileSource","SevenZipParser","parse","parsed","sigBuf","source","read","length","TRUNCATED_ARCHIVE","signature","headerOffset","nextHeaderOffset","headerBuf","nextHeaderSize","headerResult","nextHeaderCRC","streamsInfo","filesInfo","err","codedErr","code","COMPRESSED_HEADER","handleCompressedHeader","buildEntries","offset","propertyId","kMainStreamsInfo","kPackInfo","CORRUPT_HEADER","packInfoResult","parseEncodedHeaderStreams","compressedStart","packPos","compressedData","packSize","codec","codecId","decompressedHeader","decode","properties","unpackSize","unpackCRC","undefined","actualCRC","packAreaEnd","searchStart","searchEnd","Math","max","scanChunkSize","searchLoop","chunkStart","chunk","i","min","candidateData","subarray","candidateDecompressed","candCRC","decompOffset","headerId","kHeader","result","buf","kEnd","packPosResult","value","bytesRead","numPackResult","kSize","sizeResult","kUnpackInfo","kFolder","numFoldersResult","numCodersResult","flags","idSize","hasAttributes","push","propsLenResult","slice","kCodersUnpackSize","unpackSizeResult","kCRC","allDefined","readUInt32LE","entries","file","createEntry","streamsPerFolder","numUnpackStreamsPerFolder","f","filesPerFolder","extractedPerFolder","streamIndex","folderIndex","streamInFolder","folderStreamCount","j","fileInfo","size","hasStream","unpackSizes","entry","_streamIndex","unpackCRCs","_crc","type","isDirectory","mode","attributes","UNIX_EXTENSION","name","getBaseName","path","mtime","atime","ctime","isAntiFile","_folderIndex","_streamIndexInFolder","_hasStream","getEntries","getEntryStream","emptyStream","end","folder","folders","coders","coder","id","codecName","UNSUPPORTED_CODEC","folderIdx","data","getDecompressedFolder","fileStart","m","prevStreamGlobalIndex","fileSize","outputStream","DECOMPRESSION_FAILED","fileData","toString","CRC_MISMATCH","decompressedCache","getEntryStreamAsync","callback","getDecompressedFolderAsync","Error","folderHasBcj2","filesInFolder","extractedFromFolder","remainingFiles","shouldCache","decompressBcj2Folder","packStreamIndex","packedStreams","k","packSizes","packedData","data2","l","coderInfo","self","decompressWithStream","input","coderIdx","cb","decoder","createDecoder","chunks","errorOccurred","on","Buffer","concat","decompressChain","idx","output","numPackStreams","packStreams","currentPos","p","coderOutputs","bcj2CoderIndex","c","inputToPackStream","pi","outputToCoder","totalOutputs","co","numOut","numOutStreams","outp","processed","processOrder","getCoderProcessOrder","po","coderInputStart","ci2","numInStreams","inputIdx","packStreamIdx","inputData","outputData","coderOutputStart","co2","bcj2InputStart","ci3","bcj2Inputs","bi","globalIdx","boundOutput","bp2","bindPairs","inIndex","outIndex","psIdx","bcj2OutputStart","co3","bcj2UnpackSize","key","excludeIdx","order","changed","inputStart","canProcess","inp","bp","outIdx","outStart","oc","close","lastSlash","lastIndexOf","lastBackslash","lastSep"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/SevenZipParser.ts"],"sourcesContent":["/**\n * SevenZipParser - Main 7z archive parser\n *\n * Handles reading archive structure and providing file streams.\n *\n * Parser Flow:\n * 1. Read signature header (32 bytes) to get header location\n * 2. Read encoded header from nextHeaderOffset\n * 3. If header is compressed, decompress it first\n * 4. Parse streams info (folder structure, pack positions)\n * 5. Parse files info (names, sizes, attributes)\n * 6. Build entry list for iteration\n *\n * Decompression:\n * - 7z uses \"folders\" as decompression units\n * - Solid archives: multiple files share one folder (decompress once)\n * - Non-solid: one file per folder\n * - Supports LZMA, LZMA2, COPY, BCJ2, and other codecs\n */\n\nimport { crc32 } from 'extract-base-iterator';\nimport oo from 'on-one';\nimport Stream from 'stream';\nimport type { ArchiveSource } from './ArchiveSource.ts';\nimport { decodeBcj2Multi, getCodec, getCodecName, isBcj2Codec, isCodecSupported } from './codecs/index.ts';\n\n// Use native streams when available, readable-stream only for Node 0.x\nconst major = +process.versions.node.split('.')[0];\nlet PassThrough: typeof Stream.PassThrough;\nif (major > 0) {\n PassThrough = Stream.PassThrough;\n} else {\n PassThrough = require('readable-stream').PassThrough;\n}\ntype Readable = Stream.Readable;\n\nimport { type CodedError, createCodedError, ErrorCode, FileAttribute, PropertyId, SIGNATURE_HEADER_SIZE } from './constants.ts';\nimport { type FileInfo, parseEncodedHeader, parseHeaderContent, parseSignatureHeader, type SignatureHeader, type StreamsInfo } from './headers.ts';\nimport { readNumber } from './NumberCodec.ts';\n\n// Re-export for backwards compatibility\nexport { type ArchiveSource, BufferSource, FileSource } from './ArchiveSource.ts';\n\n// Callback type for async operations\ntype DecompressCallback = (err: Error | null, data?: Buffer) => void;\n\n// Entry type for iteration\nexport interface SevenZipEntry {\n name: string;\n path: string;\n type: 'file' | 'directory' | 'link';\n size: number;\n mtime?: Date;\n atime?: Date;\n ctime?: Date;\n mode?: number;\n isAntiFile: boolean;\n // Internal tracking\n _folderIndex: number;\n _streamIndex: number; // Global stream index\n _streamIndexInFolder: number; // Stream index within folder (for solid archives)\n _hasStream: boolean;\n _crc?: number; // Expected CRC32 for this file (if present in archive)\n}\n\n/**\n * SevenZipParser - parses 7z archives and provides entry iteration\n */\nexport class SevenZipParser {\n private source: ArchiveSource;\n private signature: SignatureHeader | null = null;\n private streamsInfo: StreamsInfo | null = null;\n private filesInfo: FileInfo[] = [];\n private entries: SevenZipEntry[] = [];\n private parsed = false;\n // Smart cache for decompressed solid blocks\n // Only caches when multiple files share a block, releases when last file extracted\n private decompressedCache: { [key: number]: Buffer } = {};\n // Track files per folder and how many have been extracted\n private filesPerFolder: { [key: number]: number } = {};\n private extractedPerFolder: { [key: number]: number } = {};\n\n constructor(source: ArchiveSource) {\n this.source = source;\n }\n\n /**\n * Parse the archive structure\n * Must be called before iterating entries\n */\n parse(): void {\n if (this.parsed) return;\n\n // Read signature header\n const sigBuf = this.source.read(0, SIGNATURE_HEADER_SIZE);\n if (sigBuf.length < SIGNATURE_HEADER_SIZE) {\n throw createCodedError('Archive too small', ErrorCode.TRUNCATED_ARCHIVE);\n }\n\n this.signature = parseSignatureHeader(sigBuf);\n\n // Read encoded header\n const headerOffset = SIGNATURE_HEADER_SIZE + this.signature.nextHeaderOffset;\n const headerBuf = this.source.read(headerOffset, this.signature.nextHeaderSize);\n\n if (headerBuf.length < this.signature.nextHeaderSize) {\n throw createCodedError('Truncated header', ErrorCode.TRUNCATED_ARCHIVE);\n }\n\n // Parse encoded header (may need decompression)\n try {\n const headerResult = parseEncodedHeader(headerBuf, this.signature.nextHeaderCRC);\n this.streamsInfo = headerResult.streamsInfo || null;\n this.filesInfo = headerResult.filesInfo;\n } catch (err: unknown) {\n const codedErr = err as CodedError;\n if (codedErr && codedErr.code === ErrorCode.COMPRESSED_HEADER) {\n // Header is compressed - need to decompress first\n this.handleCompressedHeader(headerBuf);\n } else {\n throw err;\n }\n }\n\n // Build entries list\n this.buildEntries();\n this.parsed = true;\n }\n\n /**\n * Handle compressed header (kEncodedHeader)\n */\n private handleCompressedHeader(headerBuf: Buffer): void {\n // Parse the encoded header info to get decompression parameters\n let offset = 1; // Skip kEncodedHeader byte\n\n // Should have StreamsInfo for the header itself\n const propertyId = headerBuf[offset++];\n if (propertyId !== PropertyId.kMainStreamsInfo && propertyId !== PropertyId.kPackInfo) {\n throw createCodedError('Expected StreamsInfo in encoded header', ErrorCode.CORRUPT_HEADER);\n }\n\n // For now, we parse the streams info from the encoded header block\n // This tells us how to decompress the actual header\n\n // Read pack info from the encoded header structure\n const packInfoResult = this.parseEncodedHeaderStreams(headerBuf, 1);\n\n // Calculate compressed header position\n // For simple archives: header is at SIGNATURE_HEADER_SIZE + packPos\n // For BCJ2/complex archives: header may be at the END of pack data area\n // The pack data area ends at nextHeaderOffset (where encoded header starts)\n const compressedStart = SIGNATURE_HEADER_SIZE + packInfoResult.packPos;\n const compressedData = this.source.read(compressedStart, packInfoResult.packSize);\n\n // Decompress using the specified codec\n const codec = getCodec(packInfoResult.codecId);\n let decompressedHeader: Buffer | null = null;\n\n // Try decompressing from the calculated position first\n try {\n decompressedHeader = codec.decode(compressedData, packInfoResult.properties, packInfoResult.unpackSize);\n // Verify CRC if present\n if (packInfoResult.unpackCRC !== undefined) {\n const actualCRC = crc32(decompressedHeader);\n if (actualCRC !== packInfoResult.unpackCRC) {\n decompressedHeader = null; // CRC mismatch, need to search\n }\n }\n } catch {\n decompressedHeader = null; // Decompression failed, need to search\n }\n\n // If initial decompression failed, search for the correct position as a fallback\n // This handles edge cases where packPos doesn't point directly to header pack data\n if (decompressedHeader === null && this.signature) {\n const packAreaEnd = SIGNATURE_HEADER_SIZE + this.signature.nextHeaderOffset;\n const searchStart = packAreaEnd - packInfoResult.packSize;\n const searchEnd = Math.max(SIGNATURE_HEADER_SIZE, compressedStart - 100000);\n\n // Scan for LZMA data starting with 0x00 (range coder init)\n // Try each candidate and validate with CRC\n const scanChunkSize = 4096;\n searchLoop: for (let chunkStart = searchStart; chunkStart >= searchEnd; chunkStart -= scanChunkSize) {\n const chunk = this.source.read(chunkStart, scanChunkSize + packInfoResult.packSize);\n for (let i = 0; i < Math.min(chunk.length, scanChunkSize); i++) {\n if (chunk[i] === 0x00) {\n const candidateData = chunk.subarray(i, i + packInfoResult.packSize);\n if (candidateData.length === packInfoResult.packSize) {\n try {\n const candidateDecompressed = codec.decode(candidateData, packInfoResult.properties, packInfoResult.unpackSize);\n if (packInfoResult.unpackCRC !== undefined) {\n const candCRC = crc32(candidateDecompressed);\n if (candCRC === packInfoResult.unpackCRC) {\n decompressedHeader = candidateDecompressed;\n break searchLoop;\n }\n } else {\n decompressedHeader = candidateDecompressed;\n break searchLoop;\n }\n } catch {\n // Decompression failed, continue searching\n }\n }\n }\n }\n }\n }\n\n if (decompressedHeader === null) {\n throw createCodedError('Failed to decompress header - could not find valid LZMA data', ErrorCode.CORRUPT_HEADER);\n }\n\n // Now parse the decompressed header\n // It should start with kHeader\n let decompOffset = 0;\n const headerId = decompressedHeader[decompOffset++];\n if (headerId !== PropertyId.kHeader) {\n throw createCodedError('Expected kHeader in decompressed header', ErrorCode.CORRUPT_HEADER);\n }\n\n // Parse the decompressed header using shared function from headers.ts\n const result = parseHeaderContent(decompressedHeader, decompOffset);\n this.streamsInfo = result.streamsInfo || null;\n this.filesInfo = result.filesInfo;\n }\n\n /**\n * Parse streams info from encoded header block\n * This is a simplified parser for the header's own compression info\n */\n private parseEncodedHeaderStreams(\n buf: Buffer,\n offset: number\n ): {\n packPos: number;\n packSize: number;\n unpackSize: number;\n codecId: number[];\n properties?: Buffer;\n unpackCRC?: number;\n } {\n // This is a simplified parser for the encoded header's own streams info\n let packPos = 0;\n let packSize = 0;\n let unpackSize = 0;\n let codecId: number[] = [];\n let properties: Buffer | undefined;\n let unpackCRC: number | undefined;\n\n while (offset < buf.length) {\n const propertyId = buf[offset++];\n\n if (propertyId === PropertyId.kEnd) {\n break;\n }\n\n switch (propertyId) {\n case PropertyId.kPackInfo: {\n const packPosResult = readNumber(buf, offset);\n packPos = packPosResult.value;\n offset += packPosResult.bytesRead;\n\n const numPackResult = readNumber(buf, offset);\n offset += numPackResult.bytesRead;\n\n // Read until kEnd\n while (buf[offset] !== PropertyId.kEnd) {\n if (buf[offset] === PropertyId.kSize) {\n offset++;\n const sizeResult = readNumber(buf, offset);\n packSize = sizeResult.value;\n offset += sizeResult.bytesRead;\n } else {\n offset++;\n }\n }\n offset++; // Skip kEnd\n break;\n }\n\n case PropertyId.kUnpackInfo:\n // Find folder/coder info\n while (offset < buf.length && buf[offset] !== PropertyId.kEnd) {\n if (buf[offset] === PropertyId.kFolder) {\n offset++;\n const numFoldersResult = readNumber(buf, offset);\n offset += numFoldersResult.bytesRead;\n offset++; // external flag\n\n // Parse coder\n const numCodersResult = readNumber(buf, offset);\n offset += numCodersResult.bytesRead;\n\n const flags = buf[offset++];\n const idSize = flags & 0x0f;\n const hasAttributes = (flags & 0x20) !== 0;\n\n codecId = [];\n for (let i = 0; i < idSize; i++) {\n codecId.push(buf[offset++]);\n }\n\n if (hasAttributes) {\n const propsLenResult = readNumber(buf, offset);\n offset += propsLenResult.bytesRead;\n properties = buf.slice(offset, offset + propsLenResult.value);\n offset += propsLenResult.value;\n }\n } else if (buf[offset] === PropertyId.kCodersUnpackSize) {\n offset++;\n // Read unpack size - needed for LZMA decoder\n const unpackSizeResult = readNumber(buf, offset);\n unpackSize = unpackSizeResult.value;\n offset += unpackSizeResult.bytesRead;\n } else if (buf[offset] === PropertyId.kCRC) {\n offset++;\n const allDefined = buf[offset++];\n if (allDefined) {\n unpackCRC = buf.readUInt32LE(offset);\n offset += 4;\n }\n } else {\n offset++;\n }\n }\n if (buf[offset] === PropertyId.kEnd) offset++;\n break;\n }\n }\n\n return { packPos: packPos, packSize: packSize, unpackSize: unpackSize, codecId: codecId, properties: properties, unpackCRC: unpackCRC };\n }\n\n /**\n * Build the entries list from parsed file info\n */\n private buildEntries(): void {\n this.entries = [];\n\n if (!this.streamsInfo) {\n // No streams info - just create entries from file info\n for (let i = 0; i < this.filesInfo.length; i++) {\n const file = this.filesInfo[i];\n this.entries.push(this.createEntry(file, 0, 0, 0));\n }\n return;\n }\n\n // Use the properly parsed numUnpackStreamsPerFolder from the archive header\n const streamsPerFolder = this.streamsInfo.numUnpackStreamsPerFolder;\n\n // Initialize files per folder count (for smart caching)\n for (let f = 0; f < streamsPerFolder.length; f++) {\n this.filesPerFolder[f] = streamsPerFolder[f];\n this.extractedPerFolder[f] = 0;\n }\n\n // Now build entries with proper folder/stream tracking\n let streamIndex = 0;\n let folderIndex = 0;\n let streamInFolder = 0;\n let folderStreamCount = streamsPerFolder[0] || 0;\n\n for (let j = 0; j < this.filesInfo.length; j++) {\n const fileInfo = this.filesInfo[j];\n\n // Get size from unpackSizes for files with streams\n let size = 0;\n if (fileInfo.hasStream && streamIndex < this.streamsInfo.unpackSizes.length) {\n size = this.streamsInfo.unpackSizes[streamIndex];\n }\n\n const entry = this.createEntry(fileInfo, size, folderIndex, streamInFolder);\n entry._streamIndex = streamIndex;\n // Set CRC if available\n if (fileInfo.hasStream && this.streamsInfo.unpackCRCs && this.streamsInfo.unpackCRCs[streamIndex] !== undefined) {\n entry._crc = this.streamsInfo.unpackCRCs[streamIndex];\n }\n this.entries.push(entry);\n\n // Advance stream tracking for files with streams\n if (fileInfo.hasStream) {\n streamIndex++;\n streamInFolder++;\n\n // Check if we've exhausted streams in this folder\n if (streamInFolder >= folderStreamCount) {\n folderIndex++;\n streamInFolder = 0;\n folderStreamCount = streamsPerFolder[folderIndex] || 0;\n }\n }\n }\n }\n\n /**\n * Create an entry from file info\n */\n private createEntry(file: FileInfo, size: number, folderIndex: number, streamInFolder: number): SevenZipEntry {\n // Determine entry type\n // Note: 7z format doesn't natively support symlinks. p7zip with -snl stores\n // symlinks as regular files with the target path as content.\n let type: 'file' | 'directory' | 'link' = 'file';\n if (file.isDirectory) {\n type = 'directory';\n }\n\n // Calculate mode from Windows attributes\n let mode: number | undefined;\n if (file.attributes !== undefined) {\n // Check for Unix extension bit\n if ((file.attributes & FileAttribute.UNIX_EXTENSION) !== 0) {\n mode = (file.attributes >>> 16) & 0xffff;\n // Check for symlink (S_IFLNK = 0xA000)\n // Note: Most 7z implementations don't preserve symlink mode bits\n if ((mode & 0xf000) === 0xa000) {\n type = 'link';\n }\n } else if (file.isDirectory) {\n mode = 493; // 0o755\n } else {\n mode = 420; // 0o644\n }\n }\n\n return {\n name: getBaseName(file.name),\n path: file.name,\n type: type,\n size: size,\n mtime: file.mtime,\n atime: file.atime,\n ctime: file.ctime,\n mode: mode,\n isAntiFile: file.isAntiFile,\n _folderIndex: folderIndex,\n _streamIndex: 0, // Set by caller\n _streamIndexInFolder: streamInFolder,\n _hasStream: file.hasStream,\n };\n }\n\n /**\n * Get the list of entries\n */\n getEntries(): SevenZipEntry[] {\n if (!this.parsed) {\n this.parse();\n }\n return this.entries;\n }\n\n /**\n * Get a readable stream for an entry's content\n */\n getEntryStream(entry: SevenZipEntry): Readable {\n if (!entry._hasStream || entry.type === 'directory') {\n // Return empty stream for directories and empty files\n const emptyStream = new PassThrough();\n emptyStream.end();\n return emptyStream;\n }\n\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n // Get folder info\n const folder = this.streamsInfo.folders[entry._folderIndex];\n if (!folder) {\n throw createCodedError('Invalid folder index', ErrorCode.CORRUPT_HEADER);\n }\n\n // Check codec support\n for (let i = 0; i < folder.coders.length; i++) {\n const coder = folder.coders[i];\n if (!isCodecSupported(coder.id)) {\n const codecName = getCodecName(coder.id);\n throw createCodedError(`Unsupported codec: ${codecName}`, ErrorCode.UNSUPPORTED_CODEC);\n }\n }\n\n // Get decompressed data for this folder (with smart caching)\n const folderIdx = entry._folderIndex;\n const data = this.getDecompressedFolder(folderIdx);\n\n // Calculate file offset within the decompressed block\n // For solid archives, multiple files are concatenated in the block\n let fileStart = 0;\n for (let m = 0; m < entry._streamIndexInFolder; m++) {\n // Sum sizes of all streams before this one in the folder\n const prevStreamGlobalIndex = entry._streamIndex - entry._streamIndexInFolder + m;\n fileStart += this.streamsInfo.unpackSizes[prevStreamGlobalIndex];\n }\n\n const fileSize = entry.size;\n\n // Create a PassThrough stream with the file data\n const outputStream = new PassThrough();\n\n // Bounds check to prevent \"oob\" error on older Node versions\n if (fileStart + fileSize > data.length) {\n throw createCodedError(`File data out of bounds: offset ${fileStart} + size ${fileSize} > decompressed length ${data.length}`, ErrorCode.DECOMPRESSION_FAILED);\n }\n\n const fileData = data.slice(fileStart, fileStart + fileSize);\n\n // Verify CRC if present\n if (entry._crc !== undefined) {\n const actualCRC = crc32(fileData);\n if (actualCRC !== entry._crc) {\n throw createCodedError(`CRC mismatch for ${entry.path}: expected ${entry._crc.toString(16)}, got ${actualCRC.toString(16)}`, ErrorCode.CRC_MISMATCH);\n }\n }\n\n outputStream.end(fileData);\n\n // Track extraction and release cache when all files from this folder are done\n this.extractedPerFolder[folderIdx] = (this.extractedPerFolder[folderIdx] || 0) + 1;\n if (this.extractedPerFolder[folderIdx] >= this.filesPerFolder[folderIdx]) {\n // All files from this folder extracted, release cache\n delete this.decompressedCache[folderIdx];\n }\n\n return outputStream;\n }\n\n /**\n * Get a readable stream for an entry's content (callback-based async version)\n * Uses streaming decompression for non-blocking I/O\n */\n getEntryStreamAsync(entry: SevenZipEntry, callback: (err: Error | null, stream?: Readable) => void): void {\n if (!entry._hasStream || entry.type === 'directory') {\n // Return empty stream for directories and empty files\n const emptyStream = new PassThrough();\n emptyStream.end();\n callback(null, emptyStream);\n return;\n }\n\n if (!this.streamsInfo) {\n callback(createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n // Get folder info\n const folder = this.streamsInfo.folders[entry._folderIndex];\n if (!folder) {\n callback(createCodedError('Invalid folder index', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n // Check codec support\n for (let i = 0; i < folder.coders.length; i++) {\n const coder = folder.coders[i];\n if (!isCodecSupported(coder.id)) {\n const codecName = getCodecName(coder.id);\n callback(createCodedError(`Unsupported codec: ${codecName}`, ErrorCode.UNSUPPORTED_CODEC));\n return;\n }\n }\n\n // Get decompressed data for this folder using async method\n const folderIdx = entry._folderIndex;\n const streamsInfo = this.streamsInfo;\n\n this.getDecompressedFolderAsync(folderIdx, (err, data) => {\n if (err) return callback(err);\n if (!data) return callback(new Error('No data returned from decompression'));\n\n // Calculate file offset within the decompressed block\n let fileStart = 0;\n for (let m = 0; m < entry._streamIndexInFolder; m++) {\n const prevStreamGlobalIndex = entry._streamIndex - entry._streamIndexInFolder + m;\n fileStart += streamsInfo.unpackSizes[prevStreamGlobalIndex];\n }\n\n const fileSize = entry.size;\n\n // Bounds check\n if (fileStart + fileSize > data.length) {\n return callback(createCodedError(`File data out of bounds: offset ${fileStart} + size ${fileSize} > decompressed length ${data.length}`, ErrorCode.DECOMPRESSION_FAILED));\n }\n\n // Create a PassThrough stream with the file data\n const outputStream = new PassThrough();\n const fileData = data.slice(fileStart, fileStart + fileSize);\n\n // Verify CRC if present\n if (entry._crc !== undefined) {\n const actualCRC = crc32(fileData);\n if (actualCRC !== entry._crc) {\n return callback(createCodedError(`CRC mismatch for ${entry.path}: expected ${entry._crc.toString(16)}, got ${actualCRC.toString(16)}`, ErrorCode.CRC_MISMATCH));\n }\n }\n\n outputStream.end(fileData);\n\n // Track extraction and release cache when all files from this folder are done\n this.extractedPerFolder[folderIdx] = (this.extractedPerFolder[folderIdx] || 0) + 1;\n if (this.extractedPerFolder[folderIdx] >= this.filesPerFolder[folderIdx]) {\n delete this.decompressedCache[folderIdx];\n }\n\n callback(null, outputStream);\n });\n }\n\n /**\n * Check if a folder uses BCJ2 codec\n */\n private folderHasBcj2(folder: { coders: { id: number[] }[] }): boolean {\n for (let i = 0; i < folder.coders.length; i++) {\n if (isBcj2Codec(folder.coders[i].id)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get decompressed data for a folder, with smart caching for solid archives\n * Only caches when multiple files share a block, releases when last file extracted\n */\n private getDecompressedFolder(folderIndex: number): Buffer {\n // Check cache first\n if (this.decompressedCache[folderIndex]) {\n return this.decompressedCache[folderIndex];\n }\n\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n const folder = this.streamsInfo.folders[folderIndex];\n\n // Check how many files remain in this folder\n const filesInFolder = this.filesPerFolder[folderIndex] || 1;\n const extractedFromFolder = this.extractedPerFolder[folderIndex] || 0;\n const remainingFiles = filesInFolder - extractedFromFolder;\n // Only cache if more than 1 file remains (including the current one being extracted)\n const shouldCache = remainingFiles > 1;\n\n // Check if this folder uses BCJ2 (requires special multi-stream handling)\n if (this.folderHasBcj2(folder)) {\n const data = this.decompressBcj2Folder(folderIndex);\n if (shouldCache) {\n this.decompressedCache[folderIndex] = data;\n }\n return data;\n }\n\n // Calculate packed data position\n let packPos = SIGNATURE_HEADER_SIZE + this.streamsInfo.packPos;\n\n // Find which pack stream this folder uses\n let packStreamIndex = 0;\n for (let j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n\n // Calculate position of this pack stream\n for (let k = 0; k < packStreamIndex; k++) {\n packPos += this.streamsInfo.packSizes[k];\n }\n\n const packSize = this.streamsInfo.packSizes[packStreamIndex];\n\n // Read packed data\n const packedData = this.source.read(packPos, packSize);\n\n // Decompress through codec chain\n let data2 = packedData;\n for (let l = 0; l < folder.coders.length; l++) {\n const coderInfo = folder.coders[l];\n const codec = getCodec(coderInfo.id);\n // Get unpack size for this coder (needed by LZMA)\n const unpackSize = folder.unpackSizes[l];\n data2 = codec.decode(data2, coderInfo.properties, unpackSize);\n }\n\n // Cache only if more files remain in this folder\n if (shouldCache) {\n this.decompressedCache[folderIndex] = data2;\n }\n\n return data2;\n }\n\n /**\n * Get decompressed data for a folder using streaming (callback-based async)\n * Uses createDecoder() streams for non-blocking decompression\n */\n private getDecompressedFolderAsync(folderIndex: number, callback: DecompressCallback): void {\n const self = this;\n\n // Check cache first\n if (this.decompressedCache[folderIndex]) return callback(null, this.decompressedCache[folderIndex]);\n\n if (!this.streamsInfo) {\n callback(createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n const folder = this.streamsInfo.folders[folderIndex];\n\n // Check how many files remain in this folder\n const filesInFolder = this.filesPerFolder[folderIndex] || 1;\n const extractedFromFolder = this.extractedPerFolder[folderIndex] || 0;\n const remainingFiles = filesInFolder - extractedFromFolder;\n const shouldCache = remainingFiles > 1;\n\n // BCJ2 requires special handling - use sync version for now\n // TODO: Add async BCJ2 support\n if (this.folderHasBcj2(folder)) {\n try {\n const data = this.decompressBcj2Folder(folderIndex);\n if (shouldCache) {\n this.decompressedCache[folderIndex] = data;\n }\n callback(null, data);\n } catch (err) {\n callback(err as Error);\n }\n return;\n }\n\n // Calculate packed data position\n let packPos = SIGNATURE_HEADER_SIZE + this.streamsInfo.packPos;\n\n // Find which pack stream this folder uses\n let packStreamIndex = 0;\n for (let j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n\n // Calculate position of this pack stream\n for (let k = 0; k < packStreamIndex; k++) {\n packPos += this.streamsInfo.packSizes[k];\n }\n\n const packSize = this.streamsInfo.packSizes[packStreamIndex];\n\n // Read packed data\n const packedData = this.source.read(packPos, packSize);\n\n // Create decoder stream chain and decompress\n const coders = folder.coders;\n const unpackSizes = folder.unpackSizes;\n\n // Helper to decompress through a single codec stream\n function decompressWithStream(input: Buffer, coderIdx: number, cb: DecompressCallback): void {\n const coderInfo = coders[coderIdx];\n const codec = getCodec(coderInfo.id);\n const decoder = codec.createDecoder(coderInfo.properties, unpackSizes[coderIdx]);\n\n const chunks: Buffer[] = [];\n let errorOccurred = false;\n\n decoder.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n\n oo(decoder, ['error', 'end', 'close', 'finish'], (err?: Error) => {\n if (errorOccurred) return;\n if (err) {\n errorOccurred = true;\n return cb(err);\n }\n cb(null, Buffer.concat(chunks));\n });\n\n // Write input data to decoder and signal end\n decoder.end(input);\n }\n\n // Chain decompression through all codecs\n function decompressChain(input: Buffer, idx: number): void {\n if (idx >= coders.length) {\n // All done - cache and return\n if (shouldCache) {\n self.decompressedCache[folderIndex] = input;\n }\n callback(null, input);\n return;\n }\n\n decompressWithStream(input, idx, (err, output) => {\n if (err) return callback(err);\n decompressChain(output as Buffer, idx + 1);\n });\n }\n\n // Start the chain\n decompressChain(packedData, 0);\n }\n\n /**\n * Decompress a BCJ2 folder with multi-stream handling\n * BCJ2 uses 4 input streams: main, call, jump, range coder\n */\n private decompressBcj2Folder(folderIndex: number): Buffer {\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n const folder = this.streamsInfo.folders[folderIndex];\n\n // Calculate starting pack position\n let packPos = SIGNATURE_HEADER_SIZE + this.streamsInfo.packPos;\n\n // Find which pack stream index this folder starts at\n let packStreamIndex = 0;\n for (let j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n\n // Calculate position\n for (let k = 0; k < packStreamIndex; k++) {\n packPos += this.streamsInfo.packSizes[k];\n }\n\n // Read all pack streams for this folder\n const numPackStreams = folder.packedStreams.length;\n const packStreams: Buffer[] = [];\n let currentPos = packPos;\n\n for (let p = 0; p < numPackStreams; p++) {\n const size = this.streamsInfo.packSizes[packStreamIndex + p];\n packStreams.push(this.source.read(currentPos, size));\n currentPos += size;\n }\n\n // Build a map of coder outputs\n // For BCJ2, typical structure is:\n // Coder 0: LZMA2 (main stream) - 1 in, 1 out\n // Coder 1: LZMA (call stream) - 1 in, 1 out\n // Coder 2: LZMA (jump stream) - 1 in, 1 out\n // Coder 3: BCJ2 - 4 in, 1 out\n // Pack streams map to: coder inputs not bound to other coder outputs\n\n // First, decompress each non-BCJ2 coder\n const coderOutputs: { [key: number]: Buffer } = {};\n\n // Find the BCJ2 coder\n let bcj2CoderIndex = -1;\n for (let c = 0; c < folder.coders.length; c++) {\n if (isBcj2Codec(folder.coders[c].id)) {\n bcj2CoderIndex = c;\n break;\n }\n }\n\n if (bcj2CoderIndex === -1) {\n throw createCodedError('BCJ2 coder not found in folder', ErrorCode.CORRUPT_HEADER);\n }\n\n // Build input stream index -> pack stream mapping\n // folder.packedStreams tells us which input indices are unbound and their order\n const inputToPackStream: { [key: number]: number } = {};\n for (let pi = 0; pi < folder.packedStreams.length; pi++) {\n inputToPackStream[folder.packedStreams[pi]] = pi;\n }\n\n // Build output stream index -> coder mapping\n const outputToCoder: { [key: number]: number } = {};\n let totalOutputs = 0;\n for (let co = 0; co < folder.coders.length; co++) {\n const numOut = folder.coders[co].numOutStreams;\n for (let outp = 0; outp < numOut; outp++) {\n outputToCoder[totalOutputs + outp] = co;\n }\n totalOutputs += numOut;\n }\n\n // Decompress non-BCJ2 coders (LZMA, LZMA2)\n // We need to process in dependency order\n const processed: { [key: number]: boolean } = {};\n\n const processOrder = this.getCoderProcessOrder(folder, bcj2CoderIndex);\n\n for (let po = 0; po < processOrder.length; po++) {\n const coderIdx = processOrder[po];\n if (coderIdx === bcj2CoderIndex) continue;\n\n const coder = folder.coders[coderIdx];\n const codec = getCodec(coder.id);\n\n // Find input for this coder\n let coderInputStart = 0;\n for (let ci2 = 0; ci2 < coderIdx; ci2++) {\n coderInputStart += folder.coders[ci2].numInStreams;\n }\n\n // Get input data (from pack stream)\n const inputIdx = coderInputStart;\n const packStreamIdx = inputToPackStream[inputIdx];\n const inputData = packStreams[packStreamIdx];\n\n // Decompress\n const unpackSize = folder.unpackSizes[coderIdx];\n const outputData = codec.decode(inputData, coder.properties, unpackSize);\n\n // Store in coder outputs\n let coderOutputStart = 0;\n for (let co2 = 0; co2 < coderIdx; co2++) {\n coderOutputStart += folder.coders[co2].numOutStreams;\n }\n coderOutputs[coderOutputStart] = outputData;\n processed[coderIdx] = true;\n }\n\n // Now process BCJ2\n // BCJ2 has 4 inputs, need to map them correctly\n // Standard order: main(LZMA2 output), call(LZMA output), jump(LZMA output), range(raw pack)\n let bcj2InputStart = 0;\n for (let ci3 = 0; ci3 < bcj2CoderIndex; ci3++) {\n bcj2InputStart += folder.coders[ci3].numInStreams;\n }\n\n const bcj2Inputs: Buffer[] = [];\n for (let bi = 0; bi < 4; bi++) {\n const globalIdx = bcj2InputStart + bi;\n\n // Check if this input is bound to a coder output\n let boundOutput = -1;\n for (let bp2 = 0; bp2 < folder.bindPairs.length; bp2++) {\n if (folder.bindPairs[bp2].inIndex === globalIdx) {\n boundOutput = folder.bindPairs[bp2].outIndex;\n break;\n }\n }\n\n if (boundOutput >= 0) {\n // Get from coder outputs\n bcj2Inputs.push(coderOutputs[boundOutput]);\n } else {\n // Get from pack streams\n const psIdx = inputToPackStream[globalIdx];\n bcj2Inputs.push(packStreams[psIdx]);\n }\n }\n\n // Get BCJ2 unpack size\n let bcj2OutputStart = 0;\n for (let co3 = 0; co3 < bcj2CoderIndex; co3++) {\n bcj2OutputStart += folder.coders[co3].numOutStreams;\n }\n const bcj2UnpackSize = folder.unpackSizes[bcj2OutputStart];\n\n // Memory optimization: Clear intermediate buffers to help GC\n // These are no longer needed after bcj2Inputs is built\n for (const key in coderOutputs) {\n delete coderOutputs[key];\n }\n // Clear packStreams array (allows GC to free compressed data)\n packStreams.length = 0;\n\n // Decode BCJ2\n return decodeBcj2Multi(bcj2Inputs, undefined, bcj2UnpackSize);\n }\n\n /**\n * Get processing order for coders (dependency order)\n */\n private getCoderProcessOrder(folder: { coders: { numInStreams: number; numOutStreams: number }[]; bindPairs: { inIndex: number; outIndex: number }[] }, excludeIdx: number): number[] {\n const order: number[] = [];\n const processed: { [key: number]: boolean } = {};\n\n // Simple approach: process coders that don't depend on unprocessed outputs\n let changed = true;\n while (changed) {\n changed = false;\n for (let c = 0; c < folder.coders.length; c++) {\n if (processed[c] || c === excludeIdx) continue;\n\n // Check if all inputs are satisfied\n let inputStart = 0;\n for (let i = 0; i < c; i++) {\n inputStart += folder.coders[i].numInStreams;\n }\n\n let canProcess = true;\n for (let inp = 0; inp < folder.coders[c].numInStreams; inp++) {\n const globalIdx = inputStart + inp;\n // Check if bound to an unprocessed coder\n for (let bp = 0; bp < folder.bindPairs.length; bp++) {\n if (folder.bindPairs[bp].inIndex === globalIdx) {\n // Find which coder produces this output\n const outIdx = folder.bindPairs[bp].outIndex;\n let outStart = 0;\n for (let oc = 0; oc < folder.coders.length; oc++) {\n const numOut = folder.coders[oc].numOutStreams;\n if (outIdx < outStart + numOut) {\n if (!processed[oc] && oc !== excludeIdx) {\n canProcess = false;\n }\n break;\n }\n outStart += numOut;\n }\n }\n }\n }\n\n if (canProcess) {\n order.push(c);\n processed[c] = true;\n changed = true;\n }\n }\n }\n\n return order;\n }\n\n /**\n * Close the parser and release resources\n */\n close(): void {\n if (this.source) {\n this.source.close();\n }\n }\n}\n\n/**\n * Get base name from a path\n */\nfunction getBaseName(path: string): string {\n const lastSlash = path.lastIndexOf('/');\n const lastBackslash = path.lastIndexOf('\\\\');\n const lastSep = Math.max(lastSlash, lastBackslash);\n return lastSep >= 0 ? path.slice(lastSep + 1) : path;\n}\n"],"names":["crc32","oo","Stream","decodeBcj2Multi","getCodec","getCodecName","isBcj2Codec","isCodecSupported","major","process","versions","node","split","PassThrough","require","createCodedError","ErrorCode","FileAttribute","PropertyId","SIGNATURE_HEADER_SIZE","parseEncodedHeader","parseHeaderContent","parseSignatureHeader","readNumber","BufferSource","FileSource","SevenZipParser","parse","parsed","sigBuf","source","read","length","TRUNCATED_ARCHIVE","signature","headerOffset","nextHeaderOffset","headerBuf","nextHeaderSize","headerResult","nextHeaderCRC","streamsInfo","filesInfo","err","codedErr","code","COMPRESSED_HEADER","handleCompressedHeader","buildEntries","offset","propertyId","kMainStreamsInfo","kPackInfo","CORRUPT_HEADER","packInfoResult","parseEncodedHeaderStreams","compressedStart","packPos","compressedData","packSize","codec","codecId","decompressedHeader","decode","properties","unpackSize","unpackCRC","undefined","actualCRC","packAreaEnd","searchStart","searchEnd","Math","max","scanChunkSize","searchLoop","chunkStart","chunk","i","min","candidateData","subarray","candidateDecompressed","candCRC","decompOffset","headerId","kHeader","result","buf","kEnd","packPosResult","value","bytesRead","numPackResult","kSize","sizeResult","kUnpackInfo","kFolder","numFoldersResult","numCodersResult","flags","idSize","hasAttributes","push","propsLenResult","slice","kCodersUnpackSize","unpackSizeResult","kCRC","allDefined","readUInt32LE","entries","file","createEntry","streamsPerFolder","numUnpackStreamsPerFolder","f","filesPerFolder","extractedPerFolder","streamIndex","folderIndex","streamInFolder","folderStreamCount","j","fileInfo","size","hasStream","unpackSizes","entry","_streamIndex","unpackCRCs","_crc","type","isDirectory","mode","attributes","UNIX_EXTENSION","name","getBaseName","path","mtime","atime","ctime","isAntiFile","_folderIndex","_streamIndexInFolder","_hasStream","getEntries","getEntryStream","emptyStream","end","folder","folders","coders","coder","id","codecName","UNSUPPORTED_CODEC","folderIdx","data","getDecompressedFolder","fileStart","m","prevStreamGlobalIndex","fileSize","outputStream","DECOMPRESSION_FAILED","fileData","toString","CRC_MISMATCH","decompressedCache","getEntryStreamAsync","callback","getDecompressedFolderAsync","Error","folderHasBcj2","filesInFolder","extractedFromFolder","remainingFiles","shouldCache","decompressBcj2Folder","packStreamIndex","packedStreams","k","packSizes","packedData","data2","l","coderInfo","self","decompressWithStream","input","coderIdx","cb","decoder","createDecoder","chunks","errorOccurred","on","Buffer","concat","decompressChain","idx","output","numPackStreams","packStreams","currentPos","p","coderOutputs","bcj2CoderIndex","c","inputToPackStream","pi","outputToCoder","totalOutputs","co","numOut","numOutStreams","outp","processed","processOrder","getCoderProcessOrder","po","coderInputStart","ci2","numInStreams","inputIdx","packStreamIdx","inputData","outputData","coderOutputStart","co2","bcj2InputStart","ci3","bcj2Inputs","bi","globalIdx","boundOutput","bp2","bindPairs","inIndex","outIndex","psIdx","bcj2OutputStart","co3","bcj2UnpackSize","key","excludeIdx","order","changed","inputStart","canProcess","inp","bp","outIdx","outStart","oc","close","lastSlash","lastIndexOf","lastBackslash","lastSep"],"mappings":"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"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type { Transform } from 'readable-stream';
|
|
2
2
|
/**
|
|
3
|
-
* Decode BZip2 compressed data
|
|
3
|
+
* Decode BZip2 compressed data synchronously
|
|
4
4
|
*
|
|
5
5
|
* @param input - BZip2 compressed data (with BZh header)
|
|
6
6
|
* @param _properties - Unused for BZip2
|
|
7
|
-
* @param _unpackSize - Unused
|
|
7
|
+
* @param _unpackSize - Unused
|
|
8
8
|
* @returns Decompressed data
|
|
9
9
|
*/
|
|
10
10
|
export declare function decodeBzip2(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer;
|
|
11
11
|
/**
|
|
12
12
|
* Create a BZip2 decoder Transform stream
|
|
13
|
+
* Uses unbzip2-stream for true streaming decompression (block by block)
|
|
13
14
|
*/
|
|
14
|
-
export declare function createBzip2Decoder(
|
|
15
|
+
export declare function createBzip2Decoder(_properties?: Buffer, _unpackSize?: number): Transform;
|
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
// BZip2 codec - bzip2 compression
|
|
2
2
|
// 7z stores bzip2 data with the standard BZh header
|
|
3
3
|
//
|
|
4
|
-
// Uses
|
|
5
|
-
import
|
|
6
|
-
import
|
|
4
|
+
// Uses unbzip2-stream's internal bzip2 library for both sync and streaming decompression
|
|
5
|
+
import { bufferFrom } from 'extract-base-iterator';
|
|
6
|
+
import unbzip2Stream from 'unbzip2-stream';
|
|
7
|
+
// Access the internal bzip2 decoder from unbzip2-stream
|
|
8
|
+
import bzip2 from 'unbzip2-stream/lib/bzip2.js';
|
|
7
9
|
/**
|
|
8
|
-
* Decode BZip2 compressed data
|
|
10
|
+
* Decode BZip2 compressed data synchronously
|
|
9
11
|
*
|
|
10
12
|
* @param input - BZip2 compressed data (with BZh header)
|
|
11
13
|
* @param _properties - Unused for BZip2
|
|
12
|
-
* @param _unpackSize - Unused
|
|
14
|
+
* @param _unpackSize - Unused
|
|
13
15
|
* @returns Decompressed data
|
|
14
16
|
*/ export function decodeBzip2(input, _properties, _unpackSize) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
const chunks = [];
|
|
18
|
+
bzip2.simple(bzip2.array(input), (byte)=>{
|
|
19
|
+
chunks.push(byte);
|
|
20
|
+
});
|
|
21
|
+
return bufferFrom(chunks);
|
|
17
22
|
}
|
|
18
23
|
/**
|
|
19
24
|
* Create a BZip2 decoder Transform stream
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
* Uses unbzip2-stream for true streaming decompression (block by block)
|
|
26
|
+
*/ export function createBzip2Decoder(_properties, _unpackSize) {
|
|
27
|
+
return unbzip2Stream();
|
|
22
28
|
}
|