7z-iterator 0.2.8 → 0.2.10
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.js.map +1 -1
- package/dist/cjs/SevenZipIterator.js.map +1 -1
- package/dist/cjs/compat.js.map +1 -1
- package/dist/cjs/lib/streamToSource.js.map +1 -1
- package/dist/cjs/nextEntry.js.map +1 -1
- package/dist/cjs/sevenz/NumberCodec.js.map +1 -1
- package/dist/cjs/sevenz/SevenZipParser.d.cts +1 -0
- package/dist/cjs/sevenz/SevenZipParser.d.ts +1 -0
- package/dist/cjs/sevenz/SevenZipParser.js +18 -0
- package/dist/cjs/sevenz/SevenZipParser.js.map +1 -1
- package/dist/cjs/sevenz/codecs/Aes.js.map +1 -1
- package/dist/cjs/sevenz/codecs/Bcj.js +1 -1
- package/dist/cjs/sevenz/codecs/Bcj.js.map +1 -1
- package/dist/cjs/sevenz/codecs/Bcj2.js.map +1 -1
- package/dist/cjs/sevenz/codecs/BcjArm.js.map +1 -1
- package/dist/cjs/sevenz/codecs/BcjArm64.js.map +1 -1
- package/dist/cjs/sevenz/codecs/BcjArmt.js.map +1 -1
- package/dist/cjs/sevenz/codecs/BcjIa64.js.map +1 -1
- package/dist/cjs/sevenz/codecs/BcjPpc.js.map +1 -1
- package/dist/cjs/sevenz/codecs/BcjSparc.js.map +1 -1
- package/dist/cjs/sevenz/codecs/Delta.js.map +1 -1
- package/dist/cjs/sevenz/codecs/Lzma.js.map +1 -1
- package/dist/cjs/sevenz/codecs/Lzma2.js.map +1 -1
- package/dist/cjs/sevenz/codecs/createBufferingDecoder.js.map +1 -1
- package/dist/cjs/sevenz/codecs/index.js.map +1 -1
- package/dist/cjs/sevenz/codecs/lzmaCompat.d.cts +1 -1
- package/dist/cjs/sevenz/codecs/lzmaCompat.d.ts +1 -1
- package/dist/cjs/sevenz/codecs/lzmaCompat.js.map +1 -1
- package/dist/cjs/sevenz/codecs/streams.js.map +1 -1
- package/dist/cjs/sevenz/constants.d.cts +8 -8
- package/dist/cjs/sevenz/constants.d.ts +8 -8
- package/dist/cjs/sevenz/constants.js.map +1 -1
- package/dist/cjs/sevenz/headers.js +1 -1
- package/dist/cjs/sevenz/headers.js.map +1 -1
- package/dist/esm/FileEntry.js +1 -1
- package/dist/esm/FileEntry.js.map +1 -1
- package/dist/esm/SevenZipIterator.js +6 -6
- package/dist/esm/SevenZipIterator.js.map +1 -1
- package/dist/esm/compat.js +2 -2
- package/dist/esm/compat.js.map +1 -1
- package/dist/esm/lib/streamToSource.js +12 -12
- package/dist/esm/lib/streamToSource.js.map +1 -1
- package/dist/esm/nextEntry.js +11 -11
- package/dist/esm/nextEntry.js.map +1 -1
- package/dist/esm/sevenz/NumberCodec.js +19 -19
- package/dist/esm/sevenz/NumberCodec.js.map +1 -1
- package/dist/esm/sevenz/SevenZipParser.d.ts +1 -0
- package/dist/esm/sevenz/SevenZipParser.js +207 -189
- package/dist/esm/sevenz/SevenZipParser.js.map +1 -1
- package/dist/esm/sevenz/codecs/Aes.js +29 -29
- package/dist/esm/sevenz/codecs/Aes.js.map +1 -1
- package/dist/esm/sevenz/codecs/Bcj.js +8 -8
- package/dist/esm/sevenz/codecs/Bcj.js.map +1 -1
- package/dist/esm/sevenz/codecs/Bcj2.js +35 -35
- package/dist/esm/sevenz/codecs/Bcj2.js.map +1 -1
- package/dist/esm/sevenz/codecs/BcjArm.js +4 -4
- package/dist/esm/sevenz/codecs/BcjArm.js.map +1 -1
- package/dist/esm/sevenz/codecs/BcjArm64.js +5 -5
- package/dist/esm/sevenz/codecs/BcjArm64.js.map +1 -1
- package/dist/esm/sevenz/codecs/BcjArmt.js +10 -10
- package/dist/esm/sevenz/codecs/BcjArmt.js.map +1 -1
- package/dist/esm/sevenz/codecs/BcjIa64.js +24 -24
- package/dist/esm/sevenz/codecs/BcjIa64.js.map +1 -1
- package/dist/esm/sevenz/codecs/BcjPpc.js +5 -5
- package/dist/esm/sevenz/codecs/BcjPpc.js.map +1 -1
- package/dist/esm/sevenz/codecs/BcjSparc.js +8 -8
- package/dist/esm/sevenz/codecs/BcjSparc.js.map +1 -1
- package/dist/esm/sevenz/codecs/Delta.js +6 -6
- package/dist/esm/sevenz/codecs/Delta.js.map +1 -1
- package/dist/esm/sevenz/codecs/Lzma.js +16 -16
- package/dist/esm/sevenz/codecs/Lzma.js.map +1 -1
- package/dist/esm/sevenz/codecs/Lzma2.js +35 -35
- package/dist/esm/sevenz/codecs/Lzma2.js.map +1 -1
- package/dist/esm/sevenz/codecs/createBufferingDecoder.js +3 -3
- package/dist/esm/sevenz/codecs/createBufferingDecoder.js.map +1 -1
- package/dist/esm/sevenz/codecs/index.js +6 -6
- package/dist/esm/sevenz/codecs/index.js.map +1 -1
- package/dist/esm/sevenz/codecs/lzmaCompat.d.ts +1 -1
- package/dist/esm/sevenz/codecs/lzmaCompat.js +5 -5
- package/dist/esm/sevenz/codecs/lzmaCompat.js.map +1 -1
- package/dist/esm/sevenz/codecs/streams.js +13 -13
- package/dist/esm/sevenz/codecs/streams.js.map +1 -1
- package/dist/esm/sevenz/constants.d.ts +8 -8
- package/dist/esm/sevenz/constants.js +9 -9
- package/dist/esm/sevenz/constants.js.map +1 -1
- package/dist/esm/sevenz/headers.js +134 -134
- package/dist/esm/sevenz/headers.js.map +1 -1
- package/package.json +20 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/lib/streamToSource.ts"],"sourcesContent":["// Hybrid stream handling: buffers in memory up to threshold, then switches to temp file\nimport once from 'call-once-fn';\nimport { bufferFrom } from 'extract-base-iterator';\nimport fs from 'fs';\nimport mkdirp from 'mkdirp-classic';\nimport oo from 'on-one';\nimport path from 'path';\nimport { BufferSource, FileSource } from '../sevenz/SevenZipParser.ts';\n\n// Default memory threshold: 100 MB\
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/lib/streamToSource.ts"],"sourcesContent":["// Hybrid stream handling: buffers in memory up to threshold, then switches to temp file\nimport once from 'call-once-fn';\nimport { bufferFrom } from 'extract-base-iterator';\nimport fs from 'fs';\nimport mkdirp from 'mkdirp-classic';\nimport oo from 'on-one';\nimport path from 'path';\nimport { BufferSource, FileSource } from '../sevenz/SevenZipParser.ts';\n\n// Default memory threshold: 100 MB\nconst DEFAULT_MEMORY_THRESHOLD = 100 * 1024 * 1024;\n\nexport interface StreamToSourceOptions {\n memoryThreshold?: number;\n tempPath?: string;\n}\n\nexport interface SourceResult {\n source: BufferSource | FileSource;\n fd?: number; // Set if FileSource was used (caller must close)\n tempPath?: string; // Set if temp file was created (caller must clean up)\n}\n\nexport type Callback = (error?: Error, result?: SourceResult) => void;\n\n/**\n * Convert a stream to an ArchiveSource (BufferSource for small files, FileSource for large)\n *\n * Algorithm:\n * 1. Buffer stream data in memory up to memoryThreshold\n * 2. If threshold exceeded, write all buffered data to temp file and continue streaming\n * 3. When done, return BufferSource for memory buffer or FileSource for temp file\n */\nexport default function streamToSource(stream: NodeJS.ReadableStream, options: StreamToSourceOptions, callback: Callback): void {\n const threshold = options.memoryThreshold !== undefined ? options.memoryThreshold : DEFAULT_MEMORY_THRESHOLD;\n const tempPath = options.tempPath;\n\n let chunks: Buffer[] = [];\n let totalSize = 0;\n let writeStream: fs.WriteStream | null = null;\n let useTempFile = false;\n\n const end = once(callback);\n\n function onData(chunk: Buffer | string): void {\n // Convert string chunks to Buffer\n const buf = typeof chunk === 'string' ? bufferFrom(chunk) : chunk;\n totalSize += buf.length;\n\n if (!useTempFile && totalSize <= threshold) {\n // Still under threshold - buffer in memory\n chunks.push(buf);\n } else if (!useTempFile) {\n // Just exceeded threshold - switch to temp file\n useTempFile = true;\n\n if (!tempPath) {\n end(new Error('memoryThreshold exceeded but no tempPath provided'));\n return;\n }\n\n mkdirp.sync(path.dirname(tempPath));\n writeStream = fs.createWriteStream(tempPath);\n\n // Write all buffered chunks to temp file\n for (let i = 0; i < chunks.length; i++) {\n writeStream.write(chunks[i]);\n }\n chunks = []; // Allow GC\n\n // Write current chunk\n writeStream.write(buf);\n } else {\n // Already using temp file - write directly\n if (writeStream) {\n writeStream.write(buf);\n }\n }\n }\n\n function onEnd(): void {\n if (useTempFile && writeStream && tempPath) {\n // Close write stream, then open for reading\n const filePath = tempPath; // Capture for closure\n writeStream.end(() => {\n fs.open(filePath, 'r', (err, fd) => {\n if (err) return end(err);\n fs.stat(filePath, (statErr, stats) => {\n if (statErr) {\n fs.closeSync(fd);\n return end(statErr);\n }\n end(null, {\n source: new FileSource(fd, stats.size),\n fd: fd,\n tempPath: filePath,\n });\n });\n });\n });\n } else {\n // Use memory buffer\n const fullBuffer = Buffer.concat(chunks);\n end(null, {\n source: new BufferSource(fullBuffer),\n });\n }\n }\n\n function onError(err: Error): void {\n // Clean up if we created a temp file\n if (writeStream) {\n writeStream.end();\n }\n end(err);\n }\n\n stream.on('data', onData);\n oo(stream, ['error'], onError);\n oo(stream, ['end', 'close', 'finish'], onEnd);\n}\n"],"names":["once","bufferFrom","fs","mkdirp","oo","path","BufferSource","FileSource","DEFAULT_MEMORY_THRESHOLD","streamToSource","stream","options","callback","threshold","memoryThreshold","undefined","tempPath","chunks","totalSize","writeStream","useTempFile","end","onData","chunk","buf","length","push","Error","sync","dirname","createWriteStream","i","write","onEnd","filePath","open","err","fd","stat","statErr","stats","closeSync","source","size","fullBuffer","Buffer","concat","onError","on"],"mappings":"AAAA,wFAAwF;AACxF,OAAOA,UAAU,eAAe;AAChC,SAASC,UAAU,QAAQ,wBAAwB;AACnD,OAAOC,QAAQ,KAAK;AACpB,OAAOC,YAAY,iBAAiB;AACpC,OAAOC,QAAQ,SAAS;AACxB,OAAOC,UAAU,OAAO;AACxB,SAASC,YAAY,EAAEC,UAAU,QAAQ,8BAA8B;AAEvE,mCAAmC;AACnC,MAAMC,2BAA2B,MAAM,OAAO;AAe9C;;;;;;;CAOC,GACD,eAAe,SAASC,eAAeC,MAA6B,EAAEC,OAA8B,EAAEC,QAAkB;IACtH,MAAMC,YAAYF,QAAQG,eAAe,KAAKC,YAAYJ,QAAQG,eAAe,GAAGN;IACpF,MAAMQ,WAAWL,QAAQK,QAAQ;IAEjC,IAAIC,SAAmB,EAAE;IACzB,IAAIC,YAAY;IAChB,IAAIC,cAAqC;IACzC,IAAIC,cAAc;IAElB,MAAMC,MAAMrB,KAAKY;IAEjB,SAASU,OAAOC,KAAsB;QACpC,kCAAkC;QAClC,MAAMC,MAAM,OAAOD,UAAU,WAAWtB,WAAWsB,SAASA;QAC5DL,aAAaM,IAAIC,MAAM;QAEvB,IAAI,CAACL,eAAeF,aAAaL,WAAW;YAC1C,2CAA2C;YAC3CI,OAAOS,IAAI,CAACF;QACd,OAAO,IAAI,CAACJ,aAAa;YACvB,gDAAgD;YAChDA,cAAc;YAEd,IAAI,CAACJ,UAAU;gBACbK,IAAI,IAAIM,MAAM;gBACd;YACF;YAEAxB,OAAOyB,IAAI,CAACvB,KAAKwB,OAAO,CAACb;YACzBG,cAAcjB,GAAG4B,iBAAiB,CAACd;YAEnC,yCAAyC;YACzC,IAAK,IAAIe,IAAI,GAAGA,IAAId,OAAOQ,MAAM,EAAEM,IAAK;gBACtCZ,YAAYa,KAAK,CAACf,MAAM,CAACc,EAAE;YAC7B;YACAd,SAAS,EAAE,EAAE,WAAW;YAExB,sBAAsB;YACtBE,YAAYa,KAAK,CAACR;QACpB,OAAO;YACL,2CAA2C;YAC3C,IAAIL,aAAa;gBACfA,YAAYa,KAAK,CAACR;YACpB;QACF;IACF;IAEA,SAASS;QACP,IAAIb,eAAeD,eAAeH,UAAU;YAC1C,4CAA4C;YAC5C,MAAMkB,WAAWlB,UAAU,sBAAsB;YACjDG,YAAYE,GAAG,CAAC;gBACdnB,GAAGiC,IAAI,CAACD,UAAU,KAAK,CAACE,KAAKC;oBAC3B,IAAID,KAAK,OAAOf,IAAIe;oBACpBlC,GAAGoC,IAAI,CAACJ,UAAU,CAACK,SAASC;wBAC1B,IAAID,SAAS;4BACXrC,GAAGuC,SAAS,CAACJ;4BACb,OAAOhB,IAAIkB;wBACb;wBACAlB,IAAI,MAAM;4BACRqB,QAAQ,IAAInC,WAAW8B,IAAIG,MAAMG,IAAI;4BACrCN,IAAIA;4BACJrB,UAAUkB;wBACZ;oBACF;gBACF;YACF;QACF,OAAO;YACL,oBAAoB;YACpB,MAAMU,aAAaC,OAAOC,MAAM,CAAC7B;YACjCI,IAAI,MAAM;gBACRqB,QAAQ,IAAIpC,aAAasC;YAC3B;QACF;IACF;IAEA,SAASG,QAAQX,GAAU;QACzB,qCAAqC;QACrC,IAAIjB,aAAa;YACfA,YAAYE,GAAG;QACjB;QACAA,IAAIe;IACN;IAEA1B,OAAOsC,EAAE,CAAC,QAAQ1B;IAClBlB,GAAGM,QAAQ;QAAC;KAAQ,EAAEqC;IACtB3C,GAAGM,QAAQ;QAAC;QAAO;QAAS;KAAS,EAAEuB;AACzC"}
|
package/dist/esm/nextEntry.js
CHANGED
|
@@ -8,9 +8,9 @@ export default function nextEntry(iterator, callback) {
|
|
|
8
8
|
callback(new Error('iterator missing'));
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
let entry = null;
|
|
12
12
|
entry = iterator.iterator.next();
|
|
13
|
-
|
|
13
|
+
const nextCallback = once((err, entry)=>{
|
|
14
14
|
// keep processing
|
|
15
15
|
if (entry) iterator.push(nextEntry);
|
|
16
16
|
err ? callback(err) : callback(null, entry ? {
|
|
@@ -32,14 +32,14 @@ export default function nextEntry(iterator, callback) {
|
|
|
32
32
|
return callback(null, null);
|
|
33
33
|
}
|
|
34
34
|
// Determine type from entry
|
|
35
|
-
|
|
35
|
+
const type = entry.type;
|
|
36
36
|
// Default modes (decimal values for Node 0.8 compatibility)
|
|
37
37
|
// 0o755 = 493, 0o644 = 420
|
|
38
|
-
|
|
38
|
+
const defaultMode = type === 'directory' ? 493 : 420;
|
|
39
39
|
// Build attributes from 7z entry
|
|
40
40
|
// mtime must be timestamp (number) for FileAttributes compatibility
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
const mtimeDate = entry.mtime || new Date();
|
|
42
|
+
const attributes = {
|
|
43
43
|
path: compact(entry.path.split(path.sep)).join(path.sep),
|
|
44
44
|
basename: entry.name,
|
|
45
45
|
mtime: mtimeDate.getTime(),
|
|
@@ -53,18 +53,18 @@ export default function nextEntry(iterator, callback) {
|
|
|
53
53
|
{
|
|
54
54
|
// For symlinks, the file content IS the symlink target path
|
|
55
55
|
// Read the content to get the linkpath for SymbolicLinkEntry
|
|
56
|
-
|
|
56
|
+
const parser = iterator.iterator.getParser();
|
|
57
57
|
// Use callback-based async decompression
|
|
58
58
|
parser.getEntryStreamAsync(entry, (err, stream)=>{
|
|
59
59
|
if (err) return nextCallback(err);
|
|
60
60
|
if (!stream) return nextCallback(new Error('No stream returned'));
|
|
61
|
-
|
|
61
|
+
const chunks = [];
|
|
62
62
|
stream.on('data', (chunk)=>{
|
|
63
63
|
chunks.push(chunk);
|
|
64
64
|
});
|
|
65
65
|
stream.on('end', ()=>{
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
const linkpath = Buffer.concat(chunks).toString('utf8');
|
|
67
|
+
const linkAttributes = {
|
|
68
68
|
path: attributes.path,
|
|
69
69
|
mtime: attributes.mtime,
|
|
70
70
|
mode: attributes.mode,
|
|
@@ -82,7 +82,7 @@ export default function nextEntry(iterator, callback) {
|
|
|
82
82
|
{
|
|
83
83
|
attributes.type = 'file';
|
|
84
84
|
attributes.size = entry.size;
|
|
85
|
-
|
|
85
|
+
const parser2 = iterator.iterator.getParser();
|
|
86
86
|
return nextCallback(null, new FileEntry(attributes, entry, parser2, iterator.lock));
|
|
87
87
|
}
|
|
88
88
|
}
|
|
@@ -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
|
|
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 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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"}
|
|
@@ -30,7 +30,7 @@ import { readUInt64LE } from 'extract-base-iterator';
|
|
|
30
30
|
* @param offset - Offset to start reading from
|
|
31
31
|
* @returns Object with value and number of bytes consumed
|
|
32
32
|
*/ export function readNumber(buf, offset) {
|
|
33
|
-
|
|
33
|
+
const firstByte = buf[offset];
|
|
34
34
|
// Special case: 0xFF means 8 extra bytes (full 64-bit value)
|
|
35
35
|
if (firstByte === 0xff) {
|
|
36
36
|
return {
|
|
@@ -40,8 +40,8 @@ import { readUInt64LE } from 'extract-base-iterator';
|
|
|
40
40
|
}
|
|
41
41
|
// Determine number of extra bytes based on first byte value thresholds
|
|
42
42
|
// This matches the 7z format specification
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
let extraBytes = 0;
|
|
44
|
+
let mask = 0x80;
|
|
45
45
|
if (firstByte <= 0x7f) {
|
|
46
46
|
extraBytes = 0;
|
|
47
47
|
mask = 0x80;
|
|
@@ -69,10 +69,10 @@ import { readUInt64LE } from 'extract-base-iterator';
|
|
|
69
69
|
mask = 0x01;
|
|
70
70
|
}
|
|
71
71
|
// Get high part from first byte (bits below the length indicator)
|
|
72
|
-
|
|
72
|
+
const highPart = firstByte & mask - 1;
|
|
73
73
|
// Read extra bytes as LITTLE-ENDIAN
|
|
74
|
-
|
|
75
|
-
for(
|
|
74
|
+
let value = 0;
|
|
75
|
+
for(let i = 0; i < extraBytes; i++){
|
|
76
76
|
value += buf[offset + 1 + i] * 256 ** i;
|
|
77
77
|
}
|
|
78
78
|
// Combine: value + (highPart << (extraBytes * 8))
|
|
@@ -126,21 +126,21 @@ import { readUInt64LE } from 'extract-base-iterator';
|
|
|
126
126
|
* @param count - Number of items
|
|
127
127
|
* @returns Object with defined array and bytes consumed
|
|
128
128
|
*/ export function readDefinedVector(buf, offset, count) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
const allDefined = buf[offset] !== 0;
|
|
130
|
+
let bytesRead = 1;
|
|
131
|
+
const defined = [];
|
|
132
132
|
if (allDefined) {
|
|
133
133
|
// All items are defined
|
|
134
|
-
for(
|
|
134
|
+
for(let i = 0; i < count; i++){
|
|
135
135
|
defined.push(true);
|
|
136
136
|
}
|
|
137
137
|
} else {
|
|
138
138
|
// Read bitmask
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
for(
|
|
142
|
-
|
|
143
|
-
for(
|
|
139
|
+
const bitsNeeded = count;
|
|
140
|
+
const bytesNeeded = Math.ceil(bitsNeeded / 8);
|
|
141
|
+
for(let byteIdx = 0; byteIdx < bytesNeeded; byteIdx++){
|
|
142
|
+
const byte = buf[offset + 1 + byteIdx];
|
|
143
|
+
for(let bit = 7; bit >= 0 && defined.length < count; bit--){
|
|
144
144
|
defined.push((byte & 1 << bit) !== 0);
|
|
145
145
|
}
|
|
146
146
|
}
|
|
@@ -158,10 +158,10 @@ import { readUInt64LE } from 'extract-base-iterator';
|
|
|
158
158
|
* @param count - Number of items to read
|
|
159
159
|
* @returns Object with values array and bytes consumed
|
|
160
160
|
*/ export function readNumberArray(buf, offset, count) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
for(
|
|
164
|
-
|
|
161
|
+
const values = [];
|
|
162
|
+
let totalBytesRead = 0;
|
|
163
|
+
for(let i = 0; i < count; i++){
|
|
164
|
+
const result = readNumber(buf, offset + totalBytesRead);
|
|
165
165
|
values.push(result.value);
|
|
166
166
|
totalBytesRead += result.bytesRead;
|
|
167
167
|
}
|
|
@@ -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 * 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
|
|
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 const 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 let extraBytes = 0;\n let 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 const highPart = firstByte & (mask - 1);\n\n // Read extra bytes as LITTLE-ENDIAN\n let value = 0;\n for (let 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 const allDefined = buf[offset] !== 0;\n let bytesRead = 1;\n const defined: boolean[] = [];\n\n if (allDefined) {\n // All items are defined\n for (let i = 0; i < count; i++) {\n defined.push(true);\n }\n } else {\n // Read bitmask\n const bitsNeeded = count;\n const bytesNeeded = Math.ceil(bitsNeeded / 8);\n\n for (let byteIdx = 0; byteIdx < bytesNeeded; byteIdx++) {\n const byte = buf[offset + 1 + byteIdx];\n for (let 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 const values: number[] = [];\n let totalBytesRead = 0;\n\n for (let i = 0; i < count; i++) {\n const 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":["readUInt64LE","readNumber","buf","offset","firstByte","value","bytesRead","extraBytes","mask","highPart","i","readRawNumber","encodedSize","readBoolean","readDefinedVector","count","allDefined","defined","push","bitsNeeded","bytesNeeded","Math","ceil","byteIdx","byte","bit","length","readNumberArray","values","totalBytesRead","result"],"mappings":"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"}
|