7z-iterator 0.1.2 → 0.1.4
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/SevenZipIterator.js +2 -0
- package/dist/cjs/SevenZipIterator.js.map +1 -1
- package/dist/cjs/lib/Lock.d.cts +1 -0
- package/dist/cjs/lib/Lock.d.ts +1 -0
- package/dist/cjs/lib/Lock.js +8 -0
- package/dist/cjs/lib/Lock.js.map +1 -1
- package/dist/cjs/nextEntry.js +2 -2
- package/dist/cjs/nextEntry.js.map +1 -1
- package/dist/cjs/sevenz/NumberCodec.d.cts +9 -0
- package/dist/cjs/sevenz/NumberCodec.d.ts +9 -0
- package/dist/cjs/sevenz/NumberCodec.js +39 -14
- package/dist/cjs/sevenz/NumberCodec.js.map +1 -1
- package/dist/cjs/sevenz/SevenZipParser.d.cts +13 -0
- package/dist/cjs/sevenz/SevenZipParser.d.ts +13 -0
- package/dist/cjs/sevenz/SevenZipParser.js +250 -11
- package/dist/cjs/sevenz/SevenZipParser.js.map +1 -1
- package/dist/cjs/sevenz/codecs/Bcj2.d.cts +16 -0
- package/dist/cjs/sevenz/codecs/Bcj2.d.ts +16 -0
- package/dist/cjs/sevenz/codecs/Bcj2.js +201 -0
- package/dist/cjs/sevenz/codecs/Bcj2.js.map +1 -0
- package/dist/cjs/sevenz/codecs/Lzma2.js +54 -10
- package/dist/cjs/sevenz/codecs/Lzma2.js.map +1 -1
- package/dist/cjs/sevenz/codecs/index.d.cts +6 -0
- package/dist/cjs/sevenz/codecs/index.d.ts +6 -0
- package/dist/cjs/sevenz/codecs/index.js +17 -0
- package/dist/cjs/sevenz/codecs/index.js.map +1 -1
- package/dist/cjs/sevenz/constants.d.cts +1 -0
- package/dist/cjs/sevenz/constants.d.ts +1 -0
- package/dist/cjs/sevenz/constants.js +6 -0
- package/dist/cjs/sevenz/constants.js.map +1 -1
- package/dist/cjs/types.d.cts +1 -0
- package/dist/cjs/types.d.ts +1 -0
- package/dist/cjs/types.js.map +1 -1
- package/dist/esm/SevenZipIterator.js +2 -0
- package/dist/esm/SevenZipIterator.js.map +1 -1
- package/dist/esm/lib/Lock.d.ts +1 -0
- package/dist/esm/lib/Lock.js +8 -0
- package/dist/esm/lib/Lock.js.map +1 -1
- package/dist/esm/nextEntry.js +2 -2
- package/dist/esm/nextEntry.js.map +1 -1
- package/dist/esm/sevenz/NumberCodec.d.ts +9 -0
- package/dist/esm/sevenz/NumberCodec.js +48 -14
- package/dist/esm/sevenz/NumberCodec.js.map +1 -1
- package/dist/esm/sevenz/SevenZipParser.d.ts +13 -0
- package/dist/esm/sevenz/SevenZipParser.js +251 -12
- package/dist/esm/sevenz/SevenZipParser.js.map +1 -1
- package/dist/esm/sevenz/codecs/Bcj2.d.ts +16 -0
- package/dist/esm/sevenz/codecs/Bcj2.js +183 -0
- package/dist/esm/sevenz/codecs/Bcj2.js.map +1 -0
- package/dist/esm/sevenz/codecs/Lzma2.js +54 -10
- package/dist/esm/sevenz/codecs/Lzma2.js.map +1 -1
- package/dist/esm/sevenz/codecs/index.d.ts +6 -0
- package/dist/esm/sevenz/codecs/index.js +15 -0
- package/dist/esm/sevenz/codecs/index.js.map +1 -1
- package/dist/esm/sevenz/constants.d.ts +1 -0
- package/dist/esm/sevenz/constants.js +6 -0
- package/dist/esm/sevenz/constants.js.map +1 -1
- package/dist/esm/types.d.ts +1 -0
- package/dist/esm/types.js.map +1 -1
- package/package.json +9 -3
|
@@ -147,6 +147,8 @@ var SevenZipIterator = /*#__PURE__*/ function(BaseIterator) {
|
|
|
147
147
|
});
|
|
148
148
|
} else {
|
|
149
149
|
// Stream input - use hybrid memory/temp-file approach
|
|
150
|
+
// Store source stream in lock for cleanup if destroyed during download
|
|
151
|
+
_this.lock.sourceStream = source;
|
|
150
152
|
var tempPath = _path.default.join(tmpdir(), '7z-iterator', (0, _shorthash.default)(process.cwd()), (0, _tempsuffix.default)('tmp.7z'));
|
|
151
153
|
queue.defer(function(cb) {
|
|
152
154
|
(0, _streamToSourcets.default)(source, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/SevenZipIterator.ts"],"sourcesContent":["import BaseIterator from 'extract-base-iterator';\nimport fs from 'fs';\nimport os from 'os';\nimport osShim from 'os-shim';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport shortHash from 'short-hash';\nimport tempSuffix from 'temp-suffix';\nimport Lock from './lib/Lock.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\nvar tmpdir = os.tmpdir || osShim.tmpdir;\n\nimport type { ExtractOptions, LockT, 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 {\n lock: LockT;\n iterator: SevenZipFileIterator;\n\n constructor(source: string | NodeJS.ReadableStream, options: ExtractOptions = {}) {\n super(options);\n this.lock = new Lock();\n this.lock.iterator = this;\n var queue = new Queue(1);\n var cancelled = false;\n var archiveSource: ArchiveSource | null = null;\n var setup = (): undefined => {\n cancelled = true;\n return undefined;\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 this.lock.fd = fd;\n cb();\n });\n });\n });\n } else {\n // Stream input - use hybrid memory/temp-file approach\n var 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 this.lock.fd = result.fd;\n }\n if (result.tempPath) {\n this.lock.tempPath = result.tempPath;\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 var 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":["SevenZipIterator","tmpdir","os","osShim","EntryIterator","parser","index","entries","getEntries","next","length","getParser","source","options","lock","Lock","iterator","queue","Queue","cancelled","archiveSource","setup","undefined","processing","push","setPassword","password","defer","cb","fs","stat","statErr","stats","done","open","err","fd","FileSource","size","tempPath","path","join","shortHash","process","cwd","tempSuffix","streamToSource","memoryThreshold","result","Error","SevenZipParser","parse","parseErr","await","remove","end","nextEntry","release","BaseIterator"],"mappings":";;;;;;;eA2CqBA;;;0EA3CI;yDACV;yDACA;6DACI;2DACF;8DACC;gEACI;iEACC;6DACN;uEACiC;kEAC5B;uBACM;gCACuD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEnF,IAAIC,SAASC,WAAE,CAACD,MAAM,IAAIE,eAAM,CAACF,MAAM;AAIvC;;CAEC,GACD,IAAA,AAAMG,8BAAN;;aAAMA,cAKQC,MAAsB;gCAL9BD;aAGIE,QAAQ;QAGd,IAAI,CAACD,MAAM,GAAGA;QACd,IAAI,CAACE,OAAO,GAAGF,OAAOG,UAAU;;iBAP9BJ;IAUJK,OAAAA,IAKC,GALDA,SAAAA;QACE,IAAI,IAAI,CAACH,KAAK,IAAI,IAAI,CAACC,OAAO,CAACG,MAAM,EAAE;YACrC,OAAO;QACT;QACA,OAAO,IAAI,CAACH,OAAO,CAAC,IAAI,CAACD,KAAK,GAAG;IACnC;IAEAK,OAAAA,SAEC,GAFDA,SAAAA;QACE,OAAO,IAAI,CAACN,MAAM;IACpB;WAnBID;;AAsBS,IAAA,AAAMJ,iCAAN;;cAAMA;aAAAA,iBAIPY,MAAsC;YAAEC,UAAAA,iEAA0B,CAAC;gCAJ5Db;;gBAKjB,kBALiBA;YAKXa;;QACN,MAAKC,IAAI,GAAG,IAAIC,eAAI;QACpB,MAAKD,IAAI,CAACE,QAAQ;QAClB,IAAIC,QAAQ,IAAIC,gBAAK,CAAC;QACtB,IAAIC,YAAY;QAChB,IAAIC,gBAAsC;QAC1C,IAAIC,QAAQ;YACVF,YAAY;YACZ,OAAOG;QACT;QACA,MAAKC,UAAU,CAACC,IAAI,CAACH;QAErB,0CAA0C;QAC1CI,IAAAA,oBAAW,EAACZ,QAAQa,QAAQ,IAAI;QAEhC,IAAI,OAAOd,WAAW,UAAU;YAC9B,4CAA4C;YAC5CK,MAAMU,KAAK,CAAC,SAACC;gBACXC,WAAE,CAACC,IAAI,CAAClB,QAAQ,SAACmB,SAASC;oBACxB,IAAI,MAAKC,IAAI,IAAId,WAAW;oBAC5B,IAAIY,SAAS,OAAOH,GAAGG;oBAEvBF,WAAE,CAACK,IAAI,CAACtB,QAAQ,KAAK,SAACuB,KAAKC;wBACzB,IAAI,MAAKH,IAAI,IAAId,WAAW;wBAC5B,IAAIgB,KAAK,OAAOP,GAAGO;wBAEnBf,gBAAgB,IAAIiB,4BAAU,CAACD,IAAIJ,MAAMM,IAAI;wBAC7C,MAAKxB,IAAI,CAACsB,EAAE,GAAGA;wBACfR;oBACF;gBACF;YACF;QACF,OAAO;YACL,sDAAsD;YACtD,
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/SevenZipIterator.ts"],"sourcesContent":["import BaseIterator from 'extract-base-iterator';\nimport fs from 'fs';\nimport os from 'os';\nimport osShim from 'os-shim';\nimport path from 'path';\nimport Queue from 'queue-cb';\nimport shortHash from 'short-hash';\nimport tempSuffix from 'temp-suffix';\nimport Lock from './lib/Lock.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\nvar tmpdir = os.tmpdir || osShim.tmpdir;\n\nimport type { ExtractOptions, LockT, 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 {\n lock: LockT;\n iterator: SevenZipFileIterator;\n\n constructor(source: string | NodeJS.ReadableStream, options: ExtractOptions = {}) {\n super(options);\n this.lock = new Lock();\n this.lock.iterator = this;\n var queue = new Queue(1);\n var cancelled = false;\n var archiveSource: ArchiveSource | null = null;\n var setup = (): undefined => {\n cancelled = true;\n return undefined;\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 this.lock.fd = fd;\n cb();\n });\n });\n });\n } else {\n // Stream input - use hybrid memory/temp-file approach\n // Store source stream in lock for cleanup if destroyed during download\n this.lock.sourceStream = source as NodeJS.ReadableStream;\n var 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 this.lock.fd = result.fd;\n }\n if (result.tempPath) {\n this.lock.tempPath = result.tempPath;\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 var 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":["SevenZipIterator","tmpdir","os","osShim","EntryIterator","parser","index","entries","getEntries","next","length","getParser","source","options","lock","Lock","iterator","queue","Queue","cancelled","archiveSource","setup","undefined","processing","push","setPassword","password","defer","cb","fs","stat","statErr","stats","done","open","err","fd","FileSource","size","sourceStream","tempPath","path","join","shortHash","process","cwd","tempSuffix","streamToSource","memoryThreshold","result","Error","SevenZipParser","parse","parseErr","await","remove","end","nextEntry","release","BaseIterator"],"mappings":"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"}
|
package/dist/cjs/lib/Lock.d.cts
CHANGED
package/dist/cjs/lib/Lock.d.ts
CHANGED
package/dist/cjs/lib/Lock.js
CHANGED
|
@@ -31,6 +31,8 @@ var Lock = /*#__PURE__*/ function() {
|
|
|
31
31
|
this.fd = null;
|
|
32
32
|
this.iterator = null;
|
|
33
33
|
this.err = null;
|
|
34
|
+
// cleanup resources
|
|
35
|
+
this.sourceStream = null;
|
|
34
36
|
}
|
|
35
37
|
var _proto = Lock.prototype;
|
|
36
38
|
_proto.retain = function retain() {
|
|
@@ -42,6 +44,12 @@ var Lock = /*#__PURE__*/ function() {
|
|
|
42
44
|
if (this.count === 0) this.__destroy();
|
|
43
45
|
};
|
|
44
46
|
_proto.__destroy = function __destroy() {
|
|
47
|
+
// Destroy source stream FIRST to stop data flow (e.g., during download)
|
|
48
|
+
if (this.sourceStream) {
|
|
49
|
+
var stream = this.sourceStream;
|
|
50
|
+
if (typeof stream.destroy === 'function') stream.destroy();
|
|
51
|
+
this.sourceStream = null;
|
|
52
|
+
}
|
|
45
53
|
if (this.tempPath) {
|
|
46
54
|
try {
|
|
47
55
|
_rimraf2.default.sync(this.tempPath, {
|
package/dist/cjs/lib/Lock.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/lib/Lock.ts"],"sourcesContent":["import BaseIterator from 'extract-base-iterator';\nimport fs from 'fs';\nimport rimraf2 from 'rimraf2';\n\nexport default class Lock {\n private count = 1;\n\n // members\n tempPath: string = null;\n fd: number = null;\n iterator: BaseIterator = null;\n err: Error = null;\n\n retain() {\n this.count++;\n }\n\n release() {\n if (this.count <= 0) throw new Error('Lock count is corrupted');\n this.count--;\n if (this.count === 0) this.__destroy();\n }\n\n private __destroy() {\n if (this.tempPath) {\n try {\n rimraf2.sync(this.tempPath, { disableGlob: true });\n } catch (_err) {\n /* empty */\n }\n this.tempPath = null;\n }\n\n if (this.fd) {\n fs.closeSync(this.fd);\n this.fd = null;\n }\n\n if (this.iterator) {\n BaseIterator.prototype.end.call(this.iterator, this.err || null);\n this.iterator = null;\n }\n }\n}\n"],"names":["Lock","count","tempPath","fd","iterator","err","retain","release","Error","__destroy","rimraf2","sync","disableGlob","_err","fs","closeSync","BaseIterator","prototype","end","call"],"mappings":";;;;;;;eAIqBA;;;0EAJI;yDACV;8DACK;;;;;;;;;;;AAEL,IAAA,AAAMA,qBAAN;;aAAMA;gCAAAA;aACXC,QAAQ;QAEhB,UAAU;aACVC,WAAmB;aACnBC,KAAa;aACbC,WAAyB;aACzBC,MAAa;;
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/lib/Lock.ts"],"sourcesContent":["import BaseIterator from 'extract-base-iterator';\nimport fs from 'fs';\nimport rimraf2 from 'rimraf2';\n\nexport default class Lock {\n private count = 1;\n\n // members\n tempPath: string = null;\n fd: number = null;\n iterator: BaseIterator = null;\n err: Error = null;\n\n // cleanup resources\n sourceStream: NodeJS.ReadableStream = null;\n\n retain() {\n this.count++;\n }\n\n release() {\n if (this.count <= 0) throw new Error('Lock count is corrupted');\n this.count--;\n if (this.count === 0) this.__destroy();\n }\n\n private __destroy() {\n // Destroy source stream FIRST to stop data flow (e.g., during download)\n if (this.sourceStream) {\n const stream = this.sourceStream as NodeJS.ReadableStream & { destroy?: () => void };\n if (typeof stream.destroy === 'function') stream.destroy();\n this.sourceStream = null;\n }\n\n if (this.tempPath) {\n try {\n rimraf2.sync(this.tempPath, { disableGlob: true });\n } catch (_err) {\n /* empty */\n }\n this.tempPath = null;\n }\n\n if (this.fd) {\n fs.closeSync(this.fd);\n this.fd = null;\n }\n\n if (this.iterator) {\n BaseIterator.prototype.end.call(this.iterator, this.err || null);\n this.iterator = null;\n }\n }\n}\n"],"names":["Lock","count","tempPath","fd","iterator","err","sourceStream","retain","release","Error","__destroy","stream","destroy","rimraf2","sync","disableGlob","_err","fs","closeSync","BaseIterator","prototype","end","call"],"mappings":";;;;;;;eAIqBA;;;0EAJI;yDACV;8DACK;;;;;;;;;;;AAEL,IAAA,AAAMA,qBAAN;;aAAMA;gCAAAA;aACXC,QAAQ;QAEhB,UAAU;aACVC,WAAmB;aACnBC,KAAa;aACbC,WAAyB;aACzBC,MAAa;QAEb,oBAAoB;aACpBC,eAAsC;;iBAVnBN;IAYnBO,OAAAA,MAEC,GAFDA,SAAAA;QACE,IAAI,CAACN,KAAK;IACZ;IAEAO,OAAAA,OAIC,GAJDA,SAAAA;QACE,IAAI,IAAI,CAACP,KAAK,IAAI,GAAG,MAAM,IAAIQ,MAAM;QACrC,IAAI,CAACR,KAAK;QACV,IAAI,IAAI,CAACA,KAAK,KAAK,GAAG,IAAI,CAACS,SAAS;IACtC;IAEA,OAAQA,SA0BP,GA1BD,SAAQA;QACN,wEAAwE;QACxE,IAAI,IAAI,CAACJ,YAAY,EAAE;YACrB,IAAMK,SAAS,IAAI,CAACL,YAAY;YAChC,IAAI,OAAOK,OAAOC,OAAO,KAAK,YAAYD,OAAOC,OAAO;YACxD,IAAI,CAACN,YAAY,GAAG;QACtB;QAEA,IAAI,IAAI,CAACJ,QAAQ,EAAE;YACjB,IAAI;gBACFW,gBAAO,CAACC,IAAI,CAAC,IAAI,CAACZ,QAAQ,EAAE;oBAAEa,aAAa;gBAAK;YAClD,EAAE,OAAOC,MAAM;YACb,SAAS,GACX;YACA,IAAI,CAACd,QAAQ,GAAG;QAClB;QAEA,IAAI,IAAI,CAACC,EAAE,EAAE;YACXc,WAAE,CAACC,SAAS,CAAC,IAAI,CAACf,EAAE;YACpB,IAAI,CAACA,EAAE,GAAG;QACZ;QAEA,IAAI,IAAI,CAACC,QAAQ,EAAE;YACjBe,4BAAY,CAACC,SAAS,CAACC,GAAG,CAACC,IAAI,CAAC,IAAI,CAAClB,QAAQ,EAAE,IAAI,CAACC,GAAG,IAAI;YAC3D,IAAI,CAACD,QAAQ,GAAG;QAClB;IACF;WAhDmBJ"}
|
package/dist/cjs/nextEntry.js
CHANGED
|
@@ -36,8 +36,8 @@ function nextEntry(iterator, callback) {
|
|
|
36
36
|
value: null
|
|
37
37
|
});
|
|
38
38
|
});
|
|
39
|
-
// done: signal iteration is complete
|
|
40
|
-
if (iterator.isDone() || !entry) return callback(null, {
|
|
39
|
+
// done: signal iteration is complete (guard against stale lock)
|
|
40
|
+
if (!iterator.lock || iterator.isDone() || !entry) return callback(null, {
|
|
41
41
|
done: true,
|
|
42
42
|
value: null
|
|
43
43
|
});
|
|
@@ -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) => undefined;\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): undefined {\n if (!iterator.iterator) {\n callback(new Error('iterator missing'));\n return;\n }\n\n var entry: SevenZipEntry | null = null;\n entry = iterator.iterator.next();\n\n var 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\n if (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 var type = entry.type;\n\n // Default modes (decimal values for Node 0.8 compatibility)\n // 0o755 = 493, 0o644 = 420\n var defaultMode = type === 'directory' ? 493 : 420;\n\n // Build attributes from 7z entry\n // mtime must be timestamp (number) for FileAttributes compatibility\n var mtimeDate = entry.mtime || new Date();\n var 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 var parser = iterator.iterator.getParser();\n var stream = parser.getEntryStream(entry);\n var chunks: Buffer[] = [];\n\n stream.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n stream.on('end', () => {\n var linkpath = Buffer.concat(chunks).toString('utf8');\n\n var 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', (err: Error) => {\n nextCallback(err);\n });\n return;\n }\n\n case 'file': {\n attributes.type = 'file';\n attributes.size = entry.size;\n var 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":["nextEntry","iterator","callback","Error","entry","next","nextCallback","once","err","push","done","value","isDone","isAntiFile","type","defaultMode","mtimeDate","mtime","Date","attributes","path","compact","split","sep","join","basename","name","getTime","mode","undefined","DirectoryEntry","parser","getParser","stream","getEntryStream","chunks","on","chunk","linkpath","Buffer","concat","toString","linkAttributes","SymbolicLinkEntry","size","parser2","FileEntry"
|
|
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) => undefined;\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): undefined {\n if (!iterator.iterator) {\n callback(new Error('iterator missing'));\n return;\n }\n\n var entry: SevenZipEntry | null = null;\n entry = iterator.iterator.next();\n\n var 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 var type = entry.type;\n\n // Default modes (decimal values for Node 0.8 compatibility)\n // 0o755 = 493, 0o644 = 420\n var defaultMode = type === 'directory' ? 493 : 420;\n\n // Build attributes from 7z entry\n // mtime must be timestamp (number) for FileAttributes compatibility\n var mtimeDate = entry.mtime || new Date();\n var 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 var parser = iterator.iterator.getParser();\n var stream = parser.getEntryStream(entry);\n var chunks: Buffer[] = [];\n\n stream.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n stream.on('end', () => {\n var linkpath = Buffer.concat(chunks).toString('utf8');\n\n var 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', (err: Error) => {\n nextCallback(err);\n });\n return;\n }\n\n case 'file': {\n attributes.type = 'file';\n attributes.size = entry.size;\n var 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":["nextEntry","iterator","callback","Error","entry","next","nextCallback","once","err","push","done","value","lock","isDone","isAntiFile","type","defaultMode","mtimeDate","mtime","Date","attributes","path","compact","split","sep","join","basename","name","getTime","mode","undefined","DirectoryEntry","parser","getParser","stream","getEntryStream","chunks","on","chunk","linkpath","Buffer","concat","toString","linkAttributes","SymbolicLinkEntry","size","parser2","FileEntry"],"mappings":";;;;+BAsBA;;;eAAwBA;;;iEAtBP;mCACqG;oEAClG;2DACH;kEACK;;;;;;AAkBP,SAASA,UAAcC,QAA0B,EAAEC,QAAuB;IACvF,IAAI,CAACD,SAASA,QAAQ,EAAE;QACtBC,SAAS,IAAIC,MAAM;QACnB;IACF;IAEA,IAAIC,QAA8B;IAClCA,QAAQH,SAASA,QAAQ,CAACI,IAAI;IAE9B,IAAIC,eAAeC,IAAAA,mBAAI,EAAC,SAACC,KAAaJ;QACpC,kBAAkB;QAClB,IAAIA,OAAOH,SAASQ,IAAI,CAACT;QACzBQ,MAAMN,SAASM,OAAON,SAAS,MAAME,QAAQ;YAAEM,MAAM;YAAOC,OAAOP;QAAM,IAAI;YAAEM,MAAM;YAAMC,OAAO;QAAK;IACzG;IAEA,gEAAgE;IAChE,IAAI,CAACV,SAASW,IAAI,IAAIX,SAASY,MAAM,MAAM,CAACT,OAAO,OAAOF,SAAS,MAAM;QAAEQ,MAAM;QAAMC,OAAO;IAAK;IAEnG,iEAAiE;IACjE,IAAIP,MAAMU,UAAU,EAAE;QACpBb,SAASQ,IAAI,CAACT;QACd,OAAOE,SAAS,MAAM;IACxB;IAEA,4BAA4B;IAC5B,IAAIa,OAAOX,MAAMW,IAAI;IAErB,4DAA4D;IAC5D,2BAA2B;IAC3B,IAAIC,cAAcD,SAAS,cAAc,MAAM;IAE/C,iCAAiC;IACjC,oEAAoE;IACpE,IAAIE,YAAYb,MAAMc,KAAK,IAAI,IAAIC;IACnC,IAAIC,aAAqC;QACvCC,MAAMC,IAAAA,sBAAO,EAAClB,MAAMiB,IAAI,CAACE,KAAK,CAACF,aAAI,CAACG,GAAG,GAAGC,IAAI,CAACJ,aAAI,CAACG,GAAG;QACvDE,UAAUtB,MAAMuB,IAAI;QACpBT,OAAOD,UAAUW,OAAO;QACxBC,MAAMzB,MAAMyB,IAAI,KAAKC,YAAY1B,MAAMyB,IAAI,GAAGb;IAChD;IAEA,OAAQD;QACN,KAAK;YACHK,WAAWL,IAAI,GAAG;YAClB,OAAOT,aAAa,MAAM,IAAIyB,mCAAc,CAACX;QAE/C,KAAK;YAAQ;gBACX,4DAA4D;gBAC5D,6DAA6D;gBAC7D,IAAIY,SAAS/B,SAASA,QAAQ,CAACgC,SAAS;gBACxC,IAAIC,SAASF,OAAOG,cAAc,CAAC/B;gBACnC,IAAIgC,SAAmB,EAAE;gBAEzBF,OAAOG,EAAE,CAAC,QAAQ,SAACC;oBACjBF,OAAO3B,IAAI,CAAC6B;gBACd;gBACAJ,OAAOG,EAAE,CAAC,OAAO;oBACf,IAAIE,WAAWC,OAAOC,MAAM,CAACL,QAAQM,QAAQ,CAAC;oBAE9C,IAAIC,iBAAiC;wBACnCtB,MAAMD,WAAWC,IAAI;wBACrBH,OAAOE,WAAWF,KAAK;wBACvBW,MAAMT,WAAWS,IAAI;wBACrBU,UAAUA;oBACZ;oBAEAjC,aAAa,MAAM,IAAIsC,sCAAiB,CAACD;gBAC3C;gBACAT,OAAOG,EAAE,CAAC,SAAS,SAAC7B;oBAClBF,aAAaE;gBACf;gBACA;YACF;QAEA,KAAK;YAAQ;gBACXY,WAAWL,IAAI,GAAG;gBAClBK,WAAWyB,IAAI,GAAGzC,MAAMyC,IAAI;gBAC5B,IAAIC,UAAU7C,SAASA,QAAQ,CAACgC,SAAS;gBACzC,OAAO3B,aAAa,MAAM,IAAIyC,oBAAS,CAAC3B,YAA8BhB,OAAO0C,SAAS7C,SAASW,IAAI;YACrG;IACF;IAEA,OAAOV,SAAS,IAAIC,MAAM,AAAC,4BAAgC,OAALY;AACxD"}
|
|
@@ -4,6 +4,15 @@ export interface NumberReadResult {
|
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
6
6
|
* Read a variable-length encoded number from a buffer
|
|
7
|
+
* Uses 7z's variable-length uint64 encoding where the first byte indicates
|
|
8
|
+
* how many additional bytes follow based on its value:
|
|
9
|
+
* - 0x00-0x7F: 0 extra bytes (7 bits of data)
|
|
10
|
+
* - 0x80-0xBF: 1 extra byte (14 bits of data)
|
|
11
|
+
* - 0xC0-0xDF: 2 extra bytes (21 bits of data)
|
|
12
|
+
* - 0xE0-0xEF: 3 extra bytes (28 bits of data)
|
|
13
|
+
* - etc.
|
|
14
|
+
* - 0xFF: 8 extra bytes (full 64-bit value)
|
|
15
|
+
*
|
|
7
16
|
* @param buf - Buffer containing encoded number
|
|
8
17
|
* @param offset - Offset to start reading from
|
|
9
18
|
* @returns Object with value and number of bytes consumed
|
|
@@ -4,6 +4,15 @@ export interface NumberReadResult {
|
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
6
6
|
* Read a variable-length encoded number from a buffer
|
|
7
|
+
* Uses 7z's variable-length uint64 encoding where the first byte indicates
|
|
8
|
+
* how many additional bytes follow based on its value:
|
|
9
|
+
* - 0x00-0x7F: 0 extra bytes (7 bits of data)
|
|
10
|
+
* - 0x80-0xBF: 1 extra byte (14 bits of data)
|
|
11
|
+
* - 0xC0-0xDF: 2 extra bytes (21 bits of data)
|
|
12
|
+
* - 0xE0-0xEF: 3 extra bytes (28 bits of data)
|
|
13
|
+
* - etc.
|
|
14
|
+
* - 0xFF: 8 extra bytes (full 64-bit value)
|
|
15
|
+
*
|
|
7
16
|
* @param buf - Buffer containing encoded number
|
|
8
17
|
* @param offset - Offset to start reading from
|
|
9
18
|
* @returns Object with value and number of bytes consumed
|
|
@@ -47,27 +47,52 @@ _export(exports, {
|
|
|
47
47
|
var _extractbaseiterator = require("extract-base-iterator");
|
|
48
48
|
function readNumber(buf, offset) {
|
|
49
49
|
var firstByte = buf[offset];
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
var extraBytes = 0;
|
|
53
|
-
while((firstByte & mask) !== 0 && extraBytes < 8){
|
|
54
|
-
extraBytes++;
|
|
55
|
-
mask = mask >>> 1;
|
|
56
|
-
}
|
|
57
|
-
// Special case: all 8 bits set means 8 extra bytes
|
|
58
|
-
if (extraBytes === 8) {
|
|
59
|
-
// Full 64-bit value follows
|
|
50
|
+
// Special case: 0xFF means 8 extra bytes (full 64-bit value)
|
|
51
|
+
if (firstByte === 0xff) {
|
|
60
52
|
return {
|
|
61
53
|
value: (0, _extractbaseiterator.readUInt64LE)(buf, offset + 1),
|
|
62
54
|
bytesRead: 9
|
|
63
55
|
};
|
|
64
56
|
}
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
57
|
+
// Determine number of extra bytes based on first byte value thresholds
|
|
58
|
+
// This matches the 7z format specification
|
|
59
|
+
var extraBytes = 0;
|
|
60
|
+
var mask = 0x80;
|
|
61
|
+
if (firstByte <= 0x7f) {
|
|
62
|
+
extraBytes = 0;
|
|
63
|
+
mask = 0x80;
|
|
64
|
+
} else if (firstByte <= 0xbf) {
|
|
65
|
+
extraBytes = 1;
|
|
66
|
+
mask = 0x40;
|
|
67
|
+
} else if (firstByte <= 0xdf) {
|
|
68
|
+
extraBytes = 2;
|
|
69
|
+
mask = 0x20;
|
|
70
|
+
} else if (firstByte <= 0xef) {
|
|
71
|
+
extraBytes = 3;
|
|
72
|
+
mask = 0x10;
|
|
73
|
+
} else if (firstByte <= 0xf7) {
|
|
74
|
+
extraBytes = 4;
|
|
75
|
+
mask = 0x08;
|
|
76
|
+
} else if (firstByte <= 0xfb) {
|
|
77
|
+
extraBytes = 5;
|
|
78
|
+
mask = 0x04;
|
|
79
|
+
} else if (firstByte <= 0xfd) {
|
|
80
|
+
extraBytes = 6;
|
|
81
|
+
mask = 0x02;
|
|
82
|
+
} else {
|
|
83
|
+
// 0xFE
|
|
84
|
+
extraBytes = 7;
|
|
85
|
+
mask = 0x01;
|
|
86
|
+
}
|
|
87
|
+
// Get high part from first byte (bits below the length indicator)
|
|
88
|
+
var highPart = firstByte & mask - 1;
|
|
89
|
+
// Read extra bytes as LITTLE-ENDIAN
|
|
90
|
+
var value = 0;
|
|
68
91
|
for(var i = 0; i < extraBytes; i++){
|
|
69
|
-
value
|
|
92
|
+
value += buf[offset + 1 + i] * Math.pow(256, i);
|
|
70
93
|
}
|
|
94
|
+
// Combine: value + (highPart << (extraBytes * 8))
|
|
95
|
+
value += highPart * Math.pow(256, extraBytes);
|
|
71
96
|
return {
|
|
72
97
|
value: value,
|
|
73
98
|
bytesRead: 1 + extraBytes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/NumberCodec.ts"],"sourcesContent":["// Variable-length integer encoding for 7z format\n// Reference: https://py7zr.readthedocs.io/en/latest/archive_format.html\n//\n// 7z uses a space-efficient encoding where the first byte determines length:\n// 0xxxxxxx -> 1 byte (0-127)\n// 10xxxxxx xxxxxxxx -> 2 bytes (0-16383)\n// 110xxxxx + 2 bytes -> 3 bytes\n// 1110xxxx + 3 bytes -> 4 bytes\n// 11110xxx + 4 bytes -> 5 bytes\n// 111110xx + 5 bytes -> 6 bytes\n// 1111110x + 6 bytes -> 7 bytes\n// 11111110 + 7 bytes -> 8 bytes\n// 11111111 + 8 bytes -> 9 bytes (full 64-bit)\n//\n// NOTE: Returns JavaScript number which is accurate up to 2^53 - 1 (~9 PB).\n// This covers all practical file sizes.\n\nimport { readUInt64LE } from 'extract-base-iterator';\n\nexport interface NumberReadResult {\n value: number;\n bytesRead: number;\n}\n\n/**\n * Read a variable-length encoded number from a buffer\n * @param buf - Buffer containing encoded number\n * @param offset - Offset to start reading from\n * @returns Object with value and number of bytes consumed\n */\nexport function readNumber(buf: Buffer, offset: number): NumberReadResult {\n var firstByte = buf[offset];\n\n //
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/NumberCodec.ts"],"sourcesContent":["// Variable-length integer encoding for 7z format\n// Reference: https://py7zr.readthedocs.io/en/latest/archive_format.html\n//\n// 7z uses a space-efficient encoding where the first byte determines length:\n// 0xxxxxxx -> 1 byte (0-127)\n// 10xxxxxx xxxxxxxx -> 2 bytes (0-16383)\n// 110xxxxx + 2 bytes -> 3 bytes\n// 1110xxxx + 3 bytes -> 4 bytes\n// 11110xxx + 4 bytes -> 5 bytes\n// 111110xx + 5 bytes -> 6 bytes\n// 1111110x + 6 bytes -> 7 bytes\n// 11111110 + 7 bytes -> 8 bytes\n// 11111111 + 8 bytes -> 9 bytes (full 64-bit)\n//\n// NOTE: Returns JavaScript number which is accurate up to 2^53 - 1 (~9 PB).\n// This covers all practical file sizes.\n\nimport { readUInt64LE } from 'extract-base-iterator';\n\nexport interface NumberReadResult {\n value: number;\n bytesRead: number;\n}\n\n/**\n * Read a variable-length encoded number from a buffer\n * Uses 7z's variable-length uint64 encoding where the first byte indicates\n * how many additional bytes follow based on its value:\n * - 0x00-0x7F: 0 extra bytes (7 bits of data)\n * - 0x80-0xBF: 1 extra byte (14 bits of data)\n * - 0xC0-0xDF: 2 extra bytes (21 bits of data)\n * - 0xE0-0xEF: 3 extra bytes (28 bits of data)\n * - etc.\n * - 0xFF: 8 extra bytes (full 64-bit value)\n *\n * @param buf - Buffer containing encoded number\n * @param offset - Offset to start reading from\n * @returns Object with value and number of bytes consumed\n */\nexport function readNumber(buf: Buffer, offset: number): NumberReadResult {\n var firstByte = buf[offset];\n\n // Special case: 0xFF means 8 extra bytes (full 64-bit value)\n if (firstByte === 0xff) {\n return {\n value: readUInt64LE(buf, offset + 1),\n bytesRead: 9,\n };\n }\n\n // Determine number of extra bytes based on first byte value thresholds\n // This matches the 7z format specification\n var extraBytes = 0;\n var mask = 0x80;\n\n if (firstByte <= 0x7f) {\n extraBytes = 0;\n mask = 0x80;\n } else if (firstByte <= 0xbf) {\n extraBytes = 1;\n mask = 0x40;\n } else if (firstByte <= 0xdf) {\n extraBytes = 2;\n mask = 0x20;\n } else if (firstByte <= 0xef) {\n extraBytes = 3;\n mask = 0x10;\n } else if (firstByte <= 0xf7) {\n extraBytes = 4;\n mask = 0x08;\n } else if (firstByte <= 0xfb) {\n extraBytes = 5;\n mask = 0x04;\n } else if (firstByte <= 0xfd) {\n extraBytes = 6;\n mask = 0x02;\n } else {\n // 0xFE\n extraBytes = 7;\n mask = 0x01;\n }\n\n // Get high part from first byte (bits below the length indicator)\n var highPart = firstByte & (mask - 1);\n\n // Read extra bytes as LITTLE-ENDIAN\n var value = 0;\n for (var i = 0; i < extraBytes; i++) {\n value += buf[offset + 1 + i] * 256 ** i;\n }\n\n // Combine: value + (highPart << (extraBytes * 8))\n value += highPart * 256 ** extraBytes;\n\n return {\n value: value,\n bytesRead: 1 + extraBytes,\n };\n}\n\n/**\n * Read a raw 64-bit little-endian number (used in some fixed-size fields)\n * @param buf - Buffer containing the number\n * @param offset - Offset to start reading from\n * @returns The number value\n */\nexport function readRawNumber(buf: Buffer, offset: number): number {\n return readUInt64LE(buf, offset);\n}\n\n/**\n * Calculate the encoded size of a number\n * @param value - The number to encode\n * @returns Number of bytes needed to encode the value\n */\nexport function encodedSize(value: number): number {\n if (value < 0x80) return 1; // 7 bits\n if (value < 0x4000) return 2; // 14 bits\n if (value < 0x200000) return 3; // 21 bits\n if (value < 0x10000000) return 4; // 28 bits\n if (value < 0x800000000) return 5; // 35 bits\n if (value < 0x40000000000) return 6; // 42 bits\n if (value < 0x2000000000000) return 7; // 49 bits\n // 2^56 = 72057594037927936 (use calculated value to avoid precision loss)\n if (value < 72057594037927936) return 8; // 56 bits\n return 9; // 64 bits\n}\n\n/**\n * Read a boolean encoded as a single byte\n * @param buf - Buffer to read from\n * @param offset - Offset to read from\n * @returns true if byte is non-zero\n */\nexport function readBoolean(buf: Buffer, offset: number): boolean {\n return buf[offset] !== 0;\n}\n\n/**\n * Read a \"defined\" bitmask for an array of items.\n * Used when some items in a list have optional values.\n *\n * Format: If \"allDefined\" byte is 0, a bitmask follows indicating which items have values.\n * If \"allDefined\" byte is non-zero, all items are defined.\n *\n * @param buf - Buffer to read from\n * @param offset - Offset to start reading\n * @param count - Number of items\n * @returns Object with defined array and bytes consumed\n */\nexport function readDefinedVector(buf: Buffer, offset: number, count: number): { defined: boolean[]; bytesRead: number } {\n var allDefined = buf[offset] !== 0;\n var bytesRead = 1;\n var defined: boolean[] = [];\n\n if (allDefined) {\n // All items are defined\n for (var i = 0; i < count; i++) {\n defined.push(true);\n }\n } else {\n // Read bitmask\n var bitsNeeded = count;\n var bytesNeeded = Math.ceil(bitsNeeded / 8);\n\n for (var byteIdx = 0; byteIdx < bytesNeeded; byteIdx++) {\n var byte = buf[offset + 1 + byteIdx];\n for (var bit = 7; bit >= 0 && defined.length < count; bit--) {\n defined.push((byte & (1 << bit)) !== 0);\n }\n }\n bytesRead += bytesNeeded;\n }\n\n return { defined: defined, bytesRead: bytesRead };\n}\n\n/**\n * Read an array of variable-length numbers\n * @param buf - Buffer to read from\n * @param offset - Offset to start reading\n * @param count - Number of items to read\n * @returns Object with values array and bytes consumed\n */\nexport function readNumberArray(buf: Buffer, offset: number, count: number): { values: number[]; bytesRead: number } {\n var values: number[] = [];\n var totalBytesRead = 0;\n\n for (var i = 0; i < count; i++) {\n var result = readNumber(buf, offset + totalBytesRead);\n values.push(result.value);\n totalBytesRead += result.bytesRead;\n }\n\n return { values: values, bytesRead: totalBytesRead };\n}\n"],"names":["encodedSize","readBoolean","readDefinedVector","readNumber","readNumberArray","readRawNumber","buf","offset","firstByte","value","readUInt64LE","bytesRead","extraBytes","mask","highPart","i","count","allDefined","defined","push","bitsNeeded","bytesNeeded","Math","ceil","byteIdx","byte","bit","length","values","totalBytesRead","result"],"mappings":"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"}
|
|
@@ -85,10 +85,23 @@ export declare class SevenZipParser {
|
|
|
85
85
|
* Get a readable stream for an entry's content
|
|
86
86
|
*/
|
|
87
87
|
getEntryStream(entry: SevenZipEntry): Readable;
|
|
88
|
+
/**
|
|
89
|
+
* Check if a folder uses BCJ2 codec
|
|
90
|
+
*/
|
|
91
|
+
private folderHasBcj2;
|
|
88
92
|
/**
|
|
89
93
|
* Get decompressed data for a folder, with caching for solid archives
|
|
90
94
|
*/
|
|
91
95
|
private getDecompressedFolder;
|
|
96
|
+
/**
|
|
97
|
+
* Decompress a BCJ2 folder with multi-stream handling
|
|
98
|
+
* BCJ2 uses 4 input streams: main, call, jump, range coder
|
|
99
|
+
*/
|
|
100
|
+
private decompressBcj2Folder;
|
|
101
|
+
/**
|
|
102
|
+
* Get processing order for coders (dependency order)
|
|
103
|
+
*/
|
|
104
|
+
private getCoderProcessOrder;
|
|
92
105
|
/**
|
|
93
106
|
* Close the parser and release resources
|
|
94
107
|
*/
|
|
@@ -85,10 +85,23 @@ export declare class SevenZipParser {
|
|
|
85
85
|
* Get a readable stream for an entry's content
|
|
86
86
|
*/
|
|
87
87
|
getEntryStream(entry: SevenZipEntry): Readable;
|
|
88
|
+
/**
|
|
89
|
+
* Check if a folder uses BCJ2 codec
|
|
90
|
+
*/
|
|
91
|
+
private folderHasBcj2;
|
|
88
92
|
/**
|
|
89
93
|
* Get decompressed data for a folder, with caching for solid archives
|
|
90
94
|
*/
|
|
91
95
|
private getDecompressedFolder;
|
|
96
|
+
/**
|
|
97
|
+
* Decompress a BCJ2 folder with multi-stream handling
|
|
98
|
+
* BCJ2 uses 4 input streams: main, call, jump, range coder
|
|
99
|
+
*/
|
|
100
|
+
private decompressBcj2Folder;
|
|
101
|
+
/**
|
|
102
|
+
* Get processing order for coders (dependency order)
|
|
103
|
+
*/
|
|
104
|
+
private getCoderProcessOrder;
|
|
92
105
|
/**
|
|
93
106
|
* Close the parser and release resources
|
|
94
107
|
*/
|