7z-iterator 2.2.0 → 2.2.1

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.
Files changed (47) hide show
  1. package/dist/cjs/FileEntry.js.map +1 -1
  2. package/dist/cjs/SevenZipIterator.js.map +1 -1
  3. package/dist/cjs/compat.js.map +1 -1
  4. package/dist/cjs/index.js.map +1 -1
  5. package/dist/cjs/lib/defer.js.map +1 -1
  6. package/dist/cjs/lib/streamToSource.js.map +1 -1
  7. package/dist/cjs/nextEntry.js.map +1 -1
  8. package/dist/cjs/sevenz/ArchiveSource.js.map +1 -1
  9. package/dist/cjs/sevenz/FolderStreamSplitter.js.map +1 -1
  10. package/dist/cjs/sevenz/NumberCodec.js.map +1 -1
  11. package/dist/cjs/sevenz/SevenZipParser.js.map +1 -1
  12. package/dist/cjs/sevenz/codecs/Aes.js.map +1 -1
  13. package/dist/cjs/sevenz/codecs/BZip2.js.map +1 -1
  14. package/dist/cjs/sevenz/codecs/Bcj2.js.map +1 -1
  15. package/dist/cjs/sevenz/codecs/Copy.js.map +1 -1
  16. package/dist/cjs/sevenz/codecs/Deflate.js.map +1 -1
  17. package/dist/cjs/sevenz/codecs/createBufferingDecoder.js.map +1 -1
  18. package/dist/cjs/sevenz/codecs/index.js.map +1 -1
  19. package/dist/cjs/sevenz/codecs/streams.js.map +1 -1
  20. package/dist/cjs/sevenz/constants.js.map +1 -1
  21. package/dist/cjs/sevenz/headers.js.map +1 -1
  22. package/dist/cjs/sevenz/index.js.map +1 -1
  23. package/dist/cjs/types.js.map +1 -1
  24. package/dist/esm/FileEntry.js.map +1 -1
  25. package/dist/esm/SevenZipIterator.js.map +1 -1
  26. package/dist/esm/compat.js.map +1 -1
  27. package/dist/esm/index.js.map +1 -1
  28. package/dist/esm/lib/defer.js.map +1 -1
  29. package/dist/esm/lib/streamToSource.js.map +1 -1
  30. package/dist/esm/nextEntry.js.map +1 -1
  31. package/dist/esm/sevenz/ArchiveSource.js.map +1 -1
  32. package/dist/esm/sevenz/FolderStreamSplitter.js.map +1 -1
  33. package/dist/esm/sevenz/NumberCodec.js.map +1 -1
  34. package/dist/esm/sevenz/SevenZipParser.js.map +1 -1
  35. package/dist/esm/sevenz/codecs/Aes.js.map +1 -1
  36. package/dist/esm/sevenz/codecs/BZip2.js.map +1 -1
  37. package/dist/esm/sevenz/codecs/Bcj2.js.map +1 -1
  38. package/dist/esm/sevenz/codecs/Copy.js.map +1 -1
  39. package/dist/esm/sevenz/codecs/Deflate.js.map +1 -1
  40. package/dist/esm/sevenz/codecs/createBufferingDecoder.js.map +1 -1
  41. package/dist/esm/sevenz/codecs/index.js.map +1 -1
  42. package/dist/esm/sevenz/codecs/streams.js.map +1 -1
  43. package/dist/esm/sevenz/constants.js.map +1 -1
  44. package/dist/esm/sevenz/headers.js.map +1 -1
  45. package/dist/esm/sevenz/index.js.map +1 -1
  46. package/dist/esm/types.js.map +1 -1
  47. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/iterators/7z-iterator/src/sevenz/ArchiveSource.ts"],"sourcesContent":["/**\n * ArchiveSource - Abstraction for reading 7z archive data\n *\n * Provides a common interface for reading archive data from either\n * a file descriptor or an in-memory buffer.\n */\n\nimport { allocBuffer, Readable } from 'extract-base-iterator';\nimport fs from 'fs';\nimport type Stream from 'stream';\n\n// Helper to create a Readable stream compatible with Node 0.8\nfunction createReadableStream(readFn: (stream: Stream.Readable) => void): Stream.Readable {\n const stream = new Readable();\n stream._read = function () {\n readFn(this);\n };\n return stream;\n}\n\n/**\n * Archive source abstraction - allows reading from file descriptor or buffer\n */\nexport interface ArchiveSource {\n read(position: number, length: number): Buffer;\n getSize(): number;\n close(): void;\n /**\n * Create a readable stream for a portion of the archive.\n * Used for streaming decompression.\n */\n createReadStream(offset: number, length: number): Stream.Readable;\n}\n\n/**\n * Buffer-based archive source\n *\n * Used when the entire archive is already in memory.\n */\nexport class BufferSource implements ArchiveSource {\n private buffer: Buffer;\n\n constructor(buffer: Buffer) {\n this.buffer = buffer;\n }\n\n read(position: number, length: number): Buffer {\n return this.buffer.slice(position, position + length);\n }\n\n getSize(): number {\n return this.buffer.length;\n }\n\n close(): void {\n // Nothing to close for buffer\n }\n\n /**\n * Create a readable stream for a portion of the buffer.\n * Streams the data in chunks to avoid blocking.\n */\n createReadStream(offset: number, length: number): Stream.Readable {\n const buffer = this.buffer;\n const end = Math.min(offset + length, buffer.length);\n let currentPos = offset;\n const chunkSize = 65536; // 64KB chunks\n\n return createReadableStream((stream) => {\n if (currentPos >= end) {\n stream.push(null);\n return;\n }\n\n const toRead = Math.min(chunkSize, end - currentPos);\n const chunk = buffer.slice(currentPos, currentPos + toRead);\n currentPos += toRead;\n stream.push(chunk);\n });\n }\n}\n\n/**\n * File descriptor based archive source\n *\n * Used for reading directly from a file on disk.\n * More memory efficient for large archives.\n */\nexport class FileSource implements ArchiveSource {\n private fd: number;\n private size: number;\n\n constructor(fd: number, size: number) {\n this.fd = fd;\n this.size = size;\n }\n\n read(position: number, length: number): Buffer {\n // Handle large reads by chunking to fit 32-bit signed int limit\n const MAX_INT32 = 0x7fffffff; // 2,147,483,647 bytes (~2GB)\n\n if (length <= MAX_INT32) {\n return this.readChunk(position, length);\n }\n\n // For large reads, split into multiple chunks\n const chunks: Buffer[] = [];\n let totalBytesRead = 0;\n let currentPos = position;\n\n while (totalBytesRead < length) {\n const remaining = length - totalBytesRead;\n const chunkSize = Math.min(remaining, MAX_INT32);\n const chunk = this.readChunk(currentPos, chunkSize);\n\n chunks.push(chunk);\n totalBytesRead += chunk.length;\n currentPos += chunk.length;\n\n if (chunk.length < chunkSize) {\n // EOF reached\n break;\n }\n }\n\n return Buffer.concat(chunks);\n }\n\n private readChunk(position: number, length: number): Buffer {\n const buf = allocBuffer(length);\n const bytesRead = fs.readSync(this.fd, buf, 0, length, position);\n if (bytesRead < length) {\n return buf.slice(0, bytesRead);\n }\n return buf;\n }\n\n getSize(): number {\n return this.size;\n }\n\n close(): void {\n try {\n fs.closeSync(this.fd);\n } catch (_e) {\n // Ignore close errors\n }\n }\n\n /**\n * Create a readable stream for a portion of the file.\n * Uses async fs.read() to avoid blocking the event loop.\n */\n createReadStream(offset: number, length: number): Stream.Readable {\n const fd = this.fd;\n let bytesRead = 0;\n let reading = false;\n let finished = false;\n const chunkSize = 65536; // 64KB chunks\n let _streamRef: Stream.Readable | null = null;\n\n const stream = createReadableStream((s) => {\n _streamRef = s;\n if (reading || finished) return; // Prevent re-entrant reads\n\n const toRead = Math.min(chunkSize, length - bytesRead);\n if (toRead <= 0) {\n finished = true;\n s.push(null);\n return;\n }\n\n reading = true;\n const buffer = allocBuffer(toRead);\n const currentOffset = offset + bytesRead;\n\n fs.read(fd, buffer, 0, toRead, currentOffset, (err, n) => {\n reading = false;\n\n if (err) {\n // Emit error for Node 0.8 compatibility (no destroy method)\n s.emit('error', err);\n finished = true;\n s.push(null);\n return;\n }\n\n if (n === 0) {\n finished = true;\n s.push(null);\n } else {\n bytesRead += n;\n s.push(buffer.slice(0, n));\n }\n });\n });\n\n return stream;\n }\n}\n"],"names":["allocBuffer","Readable","fs","createReadableStream","readFn","stream","_read","BufferSource","read","position","length","buffer","slice","getSize","close","createReadStream","offset","end","Math","min","currentPos","chunkSize","push","toRead","chunk","FileSource","MAX_INT32","readChunk","chunks","totalBytesRead","remaining","Buffer","concat","buf","bytesRead","readSync","fd","size","closeSync","_e","reading","finished","_streamRef","s","currentOffset","err","n","emit"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/ArchiveSource.ts"],"sourcesContent":["/**\n * ArchiveSource - Abstraction for reading 7z archive data\n *\n * Provides a common interface for reading archive data from either\n * a file descriptor or an in-memory buffer.\n */\n\nimport { allocBuffer, Readable } from 'extract-base-iterator';\nimport fs from 'fs';\nimport type Stream from 'stream';\n\n// Helper to create a Readable stream compatible with Node 0.8\nfunction createReadableStream(readFn: (stream: Stream.Readable) => void): Stream.Readable {\n const stream = new Readable();\n stream._read = function () {\n readFn(this);\n };\n return stream;\n}\n\n/**\n * Archive source abstraction - allows reading from file descriptor or buffer\n */\nexport interface ArchiveSource {\n read(position: number, length: number): Buffer;\n getSize(): number;\n close(): void;\n /**\n * Create a readable stream for a portion of the archive.\n * Used for streaming decompression.\n */\n createReadStream(offset: number, length: number): Stream.Readable;\n}\n\n/**\n * Buffer-based archive source\n *\n * Used when the entire archive is already in memory.\n */\nexport class BufferSource implements ArchiveSource {\n private buffer: Buffer;\n\n constructor(buffer: Buffer) {\n this.buffer = buffer;\n }\n\n read(position: number, length: number): Buffer {\n return this.buffer.slice(position, position + length);\n }\n\n getSize(): number {\n return this.buffer.length;\n }\n\n close(): void {\n // Nothing to close for buffer\n }\n\n /**\n * Create a readable stream for a portion of the buffer.\n * Streams the data in chunks to avoid blocking.\n */\n createReadStream(offset: number, length: number): Stream.Readable {\n const buffer = this.buffer;\n const end = Math.min(offset + length, buffer.length);\n let currentPos = offset;\n const chunkSize = 65536; // 64KB chunks\n\n return createReadableStream((stream) => {\n if (currentPos >= end) {\n stream.push(null);\n return;\n }\n\n const toRead = Math.min(chunkSize, end - currentPos);\n const chunk = buffer.slice(currentPos, currentPos + toRead);\n currentPos += toRead;\n stream.push(chunk);\n });\n }\n}\n\n/**\n * File descriptor based archive source\n *\n * Used for reading directly from a file on disk.\n * More memory efficient for large archives.\n */\nexport class FileSource implements ArchiveSource {\n private fd: number;\n private size: number;\n\n constructor(fd: number, size: number) {\n this.fd = fd;\n this.size = size;\n }\n\n read(position: number, length: number): Buffer {\n // Handle large reads by chunking to fit 32-bit signed int limit\n const MAX_INT32 = 0x7fffffff; // 2,147,483,647 bytes (~2GB)\n\n if (length <= MAX_INT32) {\n return this.readChunk(position, length);\n }\n\n // For large reads, split into multiple chunks\n const chunks: Buffer[] = [];\n let totalBytesRead = 0;\n let currentPos = position;\n\n while (totalBytesRead < length) {\n const remaining = length - totalBytesRead;\n const chunkSize = Math.min(remaining, MAX_INT32);\n const chunk = this.readChunk(currentPos, chunkSize);\n\n chunks.push(chunk);\n totalBytesRead += chunk.length;\n currentPos += chunk.length;\n\n if (chunk.length < chunkSize) {\n // EOF reached\n break;\n }\n }\n\n return Buffer.concat(chunks);\n }\n\n private readChunk(position: number, length: number): Buffer {\n const buf = allocBuffer(length);\n const bytesRead = fs.readSync(this.fd, buf, 0, length, position);\n if (bytesRead < length) {\n return buf.slice(0, bytesRead);\n }\n return buf;\n }\n\n getSize(): number {\n return this.size;\n }\n\n close(): void {\n try {\n fs.closeSync(this.fd);\n } catch (_e) {\n // Ignore close errors\n }\n }\n\n /**\n * Create a readable stream for a portion of the file.\n * Uses async fs.read() to avoid blocking the event loop.\n */\n createReadStream(offset: number, length: number): Stream.Readable {\n const fd = this.fd;\n let bytesRead = 0;\n let reading = false;\n let finished = false;\n const chunkSize = 65536; // 64KB chunks\n let _streamRef: Stream.Readable | null = null;\n\n const stream = createReadableStream((s) => {\n _streamRef = s;\n if (reading || finished) return; // Prevent re-entrant reads\n\n const toRead = Math.min(chunkSize, length - bytesRead);\n if (toRead <= 0) {\n finished = true;\n s.push(null);\n return;\n }\n\n reading = true;\n const buffer = allocBuffer(toRead);\n const currentOffset = offset + bytesRead;\n\n fs.read(fd, buffer, 0, toRead, currentOffset, (err, n) => {\n reading = false;\n\n if (err) {\n // Emit error for Node 0.8 compatibility (no destroy method)\n s.emit('error', err);\n finished = true;\n s.push(null);\n return;\n }\n\n if (n === 0) {\n finished = true;\n s.push(null);\n } else {\n bytesRead += n;\n s.push(buffer.slice(0, n));\n }\n });\n });\n\n return stream;\n }\n}\n"],"names":["allocBuffer","Readable","fs","createReadableStream","readFn","stream","_read","BufferSource","read","position","length","buffer","slice","getSize","close","createReadStream","offset","end","Math","min","currentPos","chunkSize","push","toRead","chunk","FileSource","MAX_INT32","readChunk","chunks","totalBytesRead","remaining","Buffer","concat","buf","bytesRead","readSync","fd","size","closeSync","_e","reading","finished","_streamRef","s","currentOffset","err","n","emit"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/iterators/7z-iterator/src/sevenz/FolderStreamSplitter.ts"],"sourcesContent":["/**\n * FolderStreamSplitter - Splits a decompressed folder stream into individual file streams\n *\n * For multi-file solid archives, the folder is decompressed as a single stream.\n * This class splits that stream into individual file streams based on known file boundaries.\n *\n * Features:\n * - Lazy stream creation (streams created on first access)\n * - Backpressure propagation (returns false when downstream is full)\n * - Running CRC verification per file\n * - Automatic cleanup of completed streams\n */\n\nimport { crc32, PassThrough } from 'extract-base-iterator';\nimport type Stream from 'stream';\n\nexport interface FolderStreamSplitterOptions {\n /** Sizes of each file in the folder (in order) */\n fileSizes: number[];\n /** Whether to verify CRC for each file */\n verifyCrc?: boolean;\n /** Expected CRCs for each file (parallel to fileSizes) */\n expectedCrcs?: (number | undefined)[];\n}\n\n/**\n * Splits a decompressed folder stream into individual file streams.\n *\n * Usage:\n * ```\n * const splitter = new FolderStreamSplitter({ fileSizes: [1000, 2000, 500] });\n *\n * decompressStream.on('data', (chunk) => {\n * if (!splitter.write(chunk)) {\n * decompressStream.pause();\n * splitter.onDrain(() => decompressStream.resume());\n * }\n * });\n * decompressStream.on('end', () => splitter.end());\n *\n * // Get stream for file at index 1 (created lazily)\n * const fileStream = splitter.getFileStream(1);\n * ```\n */\nexport class FolderStreamSplitter {\n private fileBoundaries: number[]; // Cumulative offsets [0, size1, size1+size2, ...]\n private fileStreams: (Stream.PassThrough | null)[]; // Lazy-created, null after completion\n private fileCrcs: number[]; // Running CRC per file\n private currentFileIndex: number;\n private bytesWritten: number;\n private currentFileEnd: number;\n private verifyCrc: boolean;\n private expectedCrcs: (number | undefined)[];\n private finished: boolean;\n private error: Error | null;\n private drainCallbacks: (() => void)[];\n private _needsDrain: boolean;\n\n constructor(options: FolderStreamSplitterOptions) {\n const fileSizes = options.fileSizes;\n const verifyCrc = options.verifyCrc !== undefined ? options.verifyCrc : true;\n const expectedCrcs = options.expectedCrcs || [];\n\n this.verifyCrc = verifyCrc;\n this.expectedCrcs = expectedCrcs;\n this.currentFileIndex = 0;\n this.bytesWritten = 0;\n this.finished = false;\n this.error = null;\n this.drainCallbacks = [];\n this._needsDrain = false;\n\n // Calculate cumulative boundaries\n this.fileBoundaries = [0];\n for (let i = 0; i < fileSizes.length; i++) {\n this.fileBoundaries.push(this.fileBoundaries[this.fileBoundaries.length - 1] + fileSizes[i]);\n }\n\n // Initialize streams array (lazy creation - all null initially)\n this.fileStreams = [];\n this.fileCrcs = [];\n for (let i = 0; i < fileSizes.length; i++) {\n this.fileStreams.push(null);\n this.fileCrcs.push(0);\n }\n\n // Set first file boundary\n this.currentFileEnd = this.fileBoundaries[1] || 0;\n }\n\n /**\n * Write decompressed data chunk. Data is routed to appropriate file stream(s).\n * Returns false if backpressure should be applied (downstream is full).\n */\n write(chunk: Buffer): boolean {\n if (this.finished || this.error) return true;\n\n let offset = 0;\n let canContinue = true;\n\n while (offset < chunk.length && this.currentFileIndex < this.fileStreams.length) {\n const remaining = chunk.length - offset;\n const neededForFile = this.currentFileEnd - this.bytesWritten;\n const toWrite = Math.min(remaining, neededForFile);\n\n if (toWrite > 0) {\n const fileChunk = chunk.slice(offset, offset + toWrite);\n\n // Ensure stream exists (lazy creation)\n const fileStream = this.ensureFileStream(this.currentFileIndex);\n\n // Update CRC\n if (this.verifyCrc) {\n this.fileCrcs[this.currentFileIndex] = crc32(fileChunk, this.fileCrcs[this.currentFileIndex]);\n }\n\n // Write to file stream, track backpressure\n if (!fileStream.write(fileChunk)) {\n canContinue = false;\n this._needsDrain = true;\n fileStream.once('drain', () => {\n this._needsDrain = false;\n this.notifyDrain();\n });\n }\n }\n\n this.bytesWritten += toWrite;\n offset += toWrite;\n\n // Check if current file is complete\n if (this.bytesWritten >= this.currentFileEnd) {\n this.finishCurrentFile();\n }\n }\n\n return canContinue;\n }\n\n /**\n * Ensure stream exists for file index (lazy creation)\n */\n private ensureFileStream(fileIndex: number): Stream.PassThrough {\n let stream = this.fileStreams[fileIndex];\n if (!stream) {\n stream = new PassThrough();\n this.fileStreams[fileIndex] = stream;\n }\n return stream;\n }\n\n /**\n * Complete current file and move to next\n */\n private finishCurrentFile(): void {\n const fileStream = this.fileStreams[this.currentFileIndex];\n\n // Verify CRC if enabled\n if (this.verifyCrc) {\n const expectedCrc = this.expectedCrcs[this.currentFileIndex];\n if (expectedCrc !== undefined && this.fileCrcs[this.currentFileIndex] !== expectedCrc) {\n const err = new Error(`CRC mismatch for file ${this.currentFileIndex}: expected ${expectedCrc.toString(16)}, got ${this.fileCrcs[this.currentFileIndex].toString(16)}`);\n this.emitError(err);\n return;\n }\n }\n\n // End this file's stream\n if (fileStream) {\n fileStream.end();\n }\n\n // Release reference for GC\n this.fileStreams[this.currentFileIndex] = null;\n\n // Move to next file\n this.currentFileIndex++;\n if (this.currentFileIndex < this.fileBoundaries.length - 1) {\n this.currentFileEnd = this.fileBoundaries[this.currentFileIndex + 1];\n }\n }\n\n /**\n * Signal end of decompressed data\n */\n end(): void {\n if (this.finished) return;\n this.finished = true;\n\n // End any remaining streams\n for (let i = this.currentFileIndex; i < this.fileStreams.length; i++) {\n const stream = this.fileStreams[i];\n if (stream) {\n stream.end();\n }\n this.fileStreams[i] = null;\n }\n }\n\n /**\n * Emit error to all pending file streams\n */\n private emitError(err: Error): void {\n this.error = err;\n for (let i = this.currentFileIndex; i < this.fileStreams.length; i++) {\n const stream = this.fileStreams[i];\n if (stream) {\n stream.emit('error', err);\n stream.end();\n }\n this.fileStreams[i] = null;\n }\n }\n\n /**\n * Get the stream for a specific file by index.\n * Stream is created lazily on first access.\n */\n getFileStream(fileIndex: number): Stream.PassThrough {\n if (fileIndex < 0 || fileIndex >= this.fileBoundaries.length - 1) {\n throw new Error(`Invalid file index: ${fileIndex}`);\n }\n\n // Check if file already completed\n if (fileIndex < this.currentFileIndex) {\n throw new Error(`File ${fileIndex} already completed - streams must be accessed in order`);\n }\n\n return this.ensureFileStream(fileIndex);\n }\n\n /**\n * Register callback for when backpressure clears\n */\n onDrain(callback: () => void): void {\n if (!this._needsDrain) {\n callback();\n } else {\n this.drainCallbacks.push(callback);\n }\n }\n\n /**\n * Notify all drain callbacks\n */\n private notifyDrain(): void {\n const callbacks = this.drainCallbacks;\n this.drainCallbacks = [];\n for (let i = 0; i < callbacks.length; i++) {\n callbacks[i]();\n }\n }\n\n /**\n * Check if a specific file's stream has been fully written\n */\n isFileComplete(fileIndex: number): boolean {\n return fileIndex < this.currentFileIndex;\n }\n\n /**\n * Get total number of files in this folder\n */\n get fileCount(): number {\n return this.fileBoundaries.length - 1;\n }\n\n /**\n * Check if splitter has encountered an error\n */\n getError(): Error | null {\n return this.error;\n }\n}\n"],"names":["crc32","PassThrough","FolderStreamSplitter","write","chunk","finished","error","offset","canContinue","length","currentFileIndex","fileStreams","remaining","neededForFile","currentFileEnd","bytesWritten","toWrite","Math","min","fileChunk","slice","fileStream","ensureFileStream","verifyCrc","fileCrcs","_needsDrain","once","notifyDrain","finishCurrentFile","fileIndex","stream","expectedCrc","expectedCrcs","undefined","err","Error","toString","emitError","end","fileBoundaries","i","emit","getFileStream","onDrain","callback","drainCallbacks","push","callbacks","isFileComplete","fileCount","getError","options","fileSizes"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/FolderStreamSplitter.ts"],"sourcesContent":["/**\n * FolderStreamSplitter - Splits a decompressed folder stream into individual file streams\n *\n * For multi-file solid archives, the folder is decompressed as a single stream.\n * This class splits that stream into individual file streams based on known file boundaries.\n *\n * Features:\n * - Lazy stream creation (streams created on first access)\n * - Backpressure propagation (returns false when downstream is full)\n * - Running CRC verification per file\n * - Automatic cleanup of completed streams\n */\n\nimport { crc32, PassThrough } from 'extract-base-iterator';\nimport type Stream from 'stream';\n\nexport interface FolderStreamSplitterOptions {\n /** Sizes of each file in the folder (in order) */\n fileSizes: number[];\n /** Whether to verify CRC for each file */\n verifyCrc?: boolean;\n /** Expected CRCs for each file (parallel to fileSizes) */\n expectedCrcs?: (number | undefined)[];\n}\n\n/**\n * Splits a decompressed folder stream into individual file streams.\n *\n * Usage:\n * ```\n * const splitter = new FolderStreamSplitter({ fileSizes: [1000, 2000, 500] });\n *\n * decompressStream.on('data', (chunk) => {\n * if (!splitter.write(chunk)) {\n * decompressStream.pause();\n * splitter.onDrain(() => decompressStream.resume());\n * }\n * });\n * decompressStream.on('end', () => splitter.end());\n *\n * // Get stream for file at index 1 (created lazily)\n * const fileStream = splitter.getFileStream(1);\n * ```\n */\nexport class FolderStreamSplitter {\n private fileBoundaries: number[]; // Cumulative offsets [0, size1, size1+size2, ...]\n private fileStreams: (Stream.PassThrough | null)[]; // Lazy-created, null after completion\n private fileCrcs: number[]; // Running CRC per file\n private currentFileIndex: number;\n private bytesWritten: number;\n private currentFileEnd: number;\n private verifyCrc: boolean;\n private expectedCrcs: (number | undefined)[];\n private finished: boolean;\n private error: Error | null;\n private drainCallbacks: (() => void)[];\n private _needsDrain: boolean;\n\n constructor(options: FolderStreamSplitterOptions) {\n const fileSizes = options.fileSizes;\n const verifyCrc = options.verifyCrc !== undefined ? options.verifyCrc : true;\n const expectedCrcs = options.expectedCrcs || [];\n\n this.verifyCrc = verifyCrc;\n this.expectedCrcs = expectedCrcs;\n this.currentFileIndex = 0;\n this.bytesWritten = 0;\n this.finished = false;\n this.error = null;\n this.drainCallbacks = [];\n this._needsDrain = false;\n\n // Calculate cumulative boundaries\n this.fileBoundaries = [0];\n for (let i = 0; i < fileSizes.length; i++) {\n this.fileBoundaries.push(this.fileBoundaries[this.fileBoundaries.length - 1] + fileSizes[i]);\n }\n\n // Initialize streams array (lazy creation - all null initially)\n this.fileStreams = [];\n this.fileCrcs = [];\n for (let i = 0; i < fileSizes.length; i++) {\n this.fileStreams.push(null);\n this.fileCrcs.push(0);\n }\n\n // Set first file boundary\n this.currentFileEnd = this.fileBoundaries[1] || 0;\n }\n\n /**\n * Write decompressed data chunk. Data is routed to appropriate file stream(s).\n * Returns false if backpressure should be applied (downstream is full).\n */\n write(chunk: Buffer): boolean {\n if (this.finished || this.error) return true;\n\n let offset = 0;\n let canContinue = true;\n\n while (offset < chunk.length && this.currentFileIndex < this.fileStreams.length) {\n const remaining = chunk.length - offset;\n const neededForFile = this.currentFileEnd - this.bytesWritten;\n const toWrite = Math.min(remaining, neededForFile);\n\n if (toWrite > 0) {\n const fileChunk = chunk.slice(offset, offset + toWrite);\n\n // Ensure stream exists (lazy creation)\n const fileStream = this.ensureFileStream(this.currentFileIndex);\n\n // Update CRC\n if (this.verifyCrc) {\n this.fileCrcs[this.currentFileIndex] = crc32(fileChunk, this.fileCrcs[this.currentFileIndex]);\n }\n\n // Write to file stream, track backpressure\n if (!fileStream.write(fileChunk)) {\n canContinue = false;\n this._needsDrain = true;\n fileStream.once('drain', () => {\n this._needsDrain = false;\n this.notifyDrain();\n });\n }\n }\n\n this.bytesWritten += toWrite;\n offset += toWrite;\n\n // Check if current file is complete\n if (this.bytesWritten >= this.currentFileEnd) {\n this.finishCurrentFile();\n }\n }\n\n return canContinue;\n }\n\n /**\n * Ensure stream exists for file index (lazy creation)\n */\n private ensureFileStream(fileIndex: number): Stream.PassThrough {\n let stream = this.fileStreams[fileIndex];\n if (!stream) {\n stream = new PassThrough();\n this.fileStreams[fileIndex] = stream;\n }\n return stream;\n }\n\n /**\n * Complete current file and move to next\n */\n private finishCurrentFile(): void {\n const fileStream = this.fileStreams[this.currentFileIndex];\n\n // Verify CRC if enabled\n if (this.verifyCrc) {\n const expectedCrc = this.expectedCrcs[this.currentFileIndex];\n if (expectedCrc !== undefined && this.fileCrcs[this.currentFileIndex] !== expectedCrc) {\n const err = new Error(`CRC mismatch for file ${this.currentFileIndex}: expected ${expectedCrc.toString(16)}, got ${this.fileCrcs[this.currentFileIndex].toString(16)}`);\n this.emitError(err);\n return;\n }\n }\n\n // End this file's stream\n if (fileStream) {\n fileStream.end();\n }\n\n // Release reference for GC\n this.fileStreams[this.currentFileIndex] = null;\n\n // Move to next file\n this.currentFileIndex++;\n if (this.currentFileIndex < this.fileBoundaries.length - 1) {\n this.currentFileEnd = this.fileBoundaries[this.currentFileIndex + 1];\n }\n }\n\n /**\n * Signal end of decompressed data\n */\n end(): void {\n if (this.finished) return;\n this.finished = true;\n\n // End any remaining streams\n for (let i = this.currentFileIndex; i < this.fileStreams.length; i++) {\n const stream = this.fileStreams[i];\n if (stream) {\n stream.end();\n }\n this.fileStreams[i] = null;\n }\n }\n\n /**\n * Emit error to all pending file streams\n */\n private emitError(err: Error): void {\n this.error = err;\n for (let i = this.currentFileIndex; i < this.fileStreams.length; i++) {\n const stream = this.fileStreams[i];\n if (stream) {\n stream.emit('error', err);\n stream.end();\n }\n this.fileStreams[i] = null;\n }\n }\n\n /**\n * Get the stream for a specific file by index.\n * Stream is created lazily on first access.\n */\n getFileStream(fileIndex: number): Stream.PassThrough {\n if (fileIndex < 0 || fileIndex >= this.fileBoundaries.length - 1) {\n throw new Error(`Invalid file index: ${fileIndex}`);\n }\n\n // Check if file already completed\n if (fileIndex < this.currentFileIndex) {\n throw new Error(`File ${fileIndex} already completed - streams must be accessed in order`);\n }\n\n return this.ensureFileStream(fileIndex);\n }\n\n /**\n * Register callback for when backpressure clears\n */\n onDrain(callback: () => void): void {\n if (!this._needsDrain) {\n callback();\n } else {\n this.drainCallbacks.push(callback);\n }\n }\n\n /**\n * Notify all drain callbacks\n */\n private notifyDrain(): void {\n const callbacks = this.drainCallbacks;\n this.drainCallbacks = [];\n for (let i = 0; i < callbacks.length; i++) {\n callbacks[i]();\n }\n }\n\n /**\n * Check if a specific file's stream has been fully written\n */\n isFileComplete(fileIndex: number): boolean {\n return fileIndex < this.currentFileIndex;\n }\n\n /**\n * Get total number of files in this folder\n */\n get fileCount(): number {\n return this.fileBoundaries.length - 1;\n }\n\n /**\n * Check if splitter has encountered an error\n */\n getError(): Error | null {\n return this.error;\n }\n}\n"],"names":["crc32","PassThrough","FolderStreamSplitter","write","chunk","finished","error","offset","canContinue","length","currentFileIndex","fileStreams","remaining","neededForFile","currentFileEnd","bytesWritten","toWrite","Math","min","fileChunk","slice","fileStream","ensureFileStream","verifyCrc","fileCrcs","_needsDrain","once","notifyDrain","finishCurrentFile","fileIndex","stream","expectedCrc","expectedCrcs","undefined","err","Error","toString","emitError","end","fileBoundaries","i","emit","getFileStream","onDrain","callback","drainCallbacks","push","callbacks","isFileComplete","fileCount","getError","options","fileSizes"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/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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"}
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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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/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 once from 'call-once-fn';\nimport { crc32, PassThrough } from 'extract-base-iterator';\nimport type Stream from 'stream';\nimport { defer } from '../lib/defer.ts';\nimport type { ArchiveSource } from './ArchiveSource.ts';\nimport { type Codec, decodeBcj2Multi, getCodec, getCodecName, isBcj2Codec, isCodecSupported } from './codecs/index.ts';\nimport { FolderStreamSplitter } from './FolderStreamSplitter.ts';\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// 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 _canStream: boolean; // Whether this entry's folder supports streaming decompression\n}\n\n/** Callback for operations that don't return data */\nexport type VoidCallback = (error: Error | null) => void;\ntype BufferCallback = (error: Error | null, data?: Buffer) => void;\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 // Splitter cache for multi-file folder streaming (Phase 2)\n private folderSplitters: { [key: number]: FolderStreamSplitter } = {};\n private pendingFolders: { [key: number]: BufferCallback[] } = {};\n\n constructor(source: ArchiveSource) {\n this.source = source;\n }\n\n private decodeWithCodec(codec: Codec, input: Buffer, properties: Buffer | undefined, unpackSize: number | undefined, callback: BufferCallback): void {\n const done = once(callback);\n try {\n codec.decode(input, properties, unpackSize, (err, result) => {\n if (err) return done(err);\n if (!result) return done(createCodedError('Decoder returned no data', ErrorCode.DECOMPRESSION_FAILED));\n done(null, result);\n });\n } catch (err) {\n done(err as Error);\n }\n }\n\n /**\n * Parse the archive structure\n * Must be called before iterating entries\n */\n parse(callback?: VoidCallback): Promise<void> | void {\n if (this.parsed) {\n if (typeof callback === 'function') {\n callback(null);\n return;\n }\n if (typeof Promise === 'undefined') {\n return;\n }\n return Promise.resolve();\n }\n\n const executor = (done: VoidCallback): void => {\n this.parseInternal(done);\n };\n\n if (typeof callback === 'function') {\n executor(callback);\n return;\n }\n\n if (typeof Promise === 'undefined') {\n throw new Error('Promises are not available in this runtime. Please provide a callback to parse().');\n }\n\n return new Promise<void>((resolve, reject) => {\n executor((err) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n });\n });\n }\n\n private parseInternal(callback: VoidCallback): void {\n if (this.parsed) {\n callback(null);\n return;\n }\n\n let signature: SignatureHeader;\n let headerBuf: Buffer;\n\n try {\n const sigBuf = this.source.read(0, SIGNATURE_HEADER_SIZE);\n if (sigBuf.length < SIGNATURE_HEADER_SIZE) {\n callback(createCodedError('Archive too small', ErrorCode.TRUNCATED_ARCHIVE));\n return;\n }\n signature = parseSignatureHeader(sigBuf);\n this.signature = signature;\n\n const headerOffset = SIGNATURE_HEADER_SIZE + signature.nextHeaderOffset;\n headerBuf = this.source.read(headerOffset, signature.nextHeaderSize);\n if (headerBuf.length < signature.nextHeaderSize) {\n callback(createCodedError('Truncated header', ErrorCode.TRUNCATED_ARCHIVE));\n return;\n }\n } catch (err) {\n callback(err as Error);\n return;\n }\n\n const finalize = (): void => {\n try {\n this.buildEntries();\n this.parsed = true;\n callback(null);\n } catch (err) {\n callback(err as Error);\n }\n };\n\n try {\n const headerResult = parseEncodedHeader(headerBuf, this.signature?.nextHeaderCRC ?? 0);\n this.streamsInfo = headerResult.streamsInfo || null;\n this.filesInfo = headerResult.filesInfo;\n finalize();\n } catch (err) {\n const codedErr = err as CodedError;\n if (codedErr && codedErr.code === ErrorCode.COMPRESSED_HEADER) {\n this.handleCompressedHeader(headerBuf, (headerErr) => {\n if (headerErr) {\n callback(headerErr);\n return;\n }\n finalize();\n });\n } else {\n callback(err as Error);\n }\n }\n }\n\n /**\n * Handle compressed header (kEncodedHeader)\n */\n private handleCompressedHeader(headerBuf: Buffer, callback: VoidCallback): void {\n // Parse the encoded header info to get decompression parameters\n let offset = 1; // Skip kEncodedHeader byte\n\n const propertyId = headerBuf[offset++];\n if (propertyId !== PropertyId.kMainStreamsInfo && propertyId !== PropertyId.kPackInfo) {\n callback(createCodedError('Expected StreamsInfo in encoded header', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n let packInfoResult: ReturnType<SevenZipParser['parseEncodedHeaderStreams']>;\n try {\n packInfoResult = this.parseEncodedHeaderStreams(headerBuf, 1);\n } catch (err) {\n callback(err as Error);\n return;\n }\n\n const codec = getCodec(packInfoResult.codecId);\n const candidates: Buffer[] = [];\n\n const compressedStart = SIGNATURE_HEADER_SIZE + packInfoResult.packPos;\n candidates.push(this.source.read(compressedStart, packInfoResult.packSize));\n\n if (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 const scanChunkSize = 4096;\n for (let chunkStart = searchStart; chunkStart >= searchEnd; chunkStart -= scanChunkSize) {\n const chunk = this.source.read(chunkStart, scanChunkSize + packInfoResult.packSize);\n const limit = Math.min(chunk.length, scanChunkSize);\n for (let i = 0; i < limit; i++) {\n if (chunk[i] === 0x00) {\n const end = i + packInfoResult.packSize;\n if (end <= chunk.length) {\n const candidateData = chunk.slice(i, end);\n if (candidateData.length === packInfoResult.packSize) {\n candidates.push(candidateData);\n }\n }\n }\n }\n }\n }\n\n const tryCandidate = (index: number): void => {\n if (index >= candidates.length) {\n callback(createCodedError('Failed to decompress header - could not find valid LZMA data', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n this.decodeWithCodec(codec, candidates[index], packInfoResult.properties, packInfoResult.unpackSize, (err, decompressed) => {\n if (err || !decompressed) {\n tryCandidate(index + 1);\n return;\n }\n if (packInfoResult.unpackCRC !== undefined) {\n const actualCRC = crc32(decompressed);\n if (actualCRC !== packInfoResult.unpackCRC) {\n tryCandidate(index + 1);\n return;\n }\n }\n this.parseDecompressedHeader(decompressed, callback);\n });\n };\n\n tryCandidate(0);\n }\n\n private parseDecompressedHeader(decompressedHeader: Buffer, callback: VoidCallback): void {\n let decompOffset = 0;\n const headerId = decompressedHeader[decompOffset++];\n if (headerId !== PropertyId.kHeader) {\n callback(createCodedError('Expected kHeader in decompressed header', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n try {\n const result = parseHeaderContent(decompressedHeader, decompOffset);\n this.streamsInfo = result.streamsInfo || null;\n this.filesInfo = result.filesInfo;\n callback(null);\n } catch (err) {\n callback(err as Error);\n }\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 // Set _canStream for all entries now that we have complete folder info\n // This must be done after all entries are built because canStreamFolder\n // relies on the folder structure being fully parsed\n for (let i = 0; i < this.entries.length; i++) {\n const entry = this.entries[i];\n if (entry._hasStream && entry._folderIndex >= 0) {\n entry._canStream = this.canStreamFolder(entry._folderIndex);\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 _canStream: false, // Set after parsing completes when canStreamFolder is available\n };\n }\n\n /**\n * Get the list of entries\n */\n getEntries(): SevenZipEntry[] {\n if (!this.parsed) {\n throw new Error('SevenZipParser has not been parsed yet. Call parse(callback) before accessing entries.');\n }\n return this.entries;\n }\n\n /**\n * Get a readable stream for an entry's content.\n * Returns immediately - decompression happens when data is read (proper streaming).\n * Uses true streaming for codecs that support it, buffered for others.\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 // Use true streaming for single-file folders that support it.\n // Multi-file folders use buffered approach because streaming requires\n // accessing files in order, which doesn't work with concurrent extraction.\n const filesInFolder = this.filesPerFolder[entry._folderIndex] || 1;\n if (entry._canStream && filesInFolder === 1) {\n return this._getEntryStreamStreaming(entry);\n }\n return this._getEntryStreamBuffered(entry);\n }\n\n /**\n * True streaming: data flows through without buffering entire folder.\n * Only used for single-file folders with streamable codecs (BZip2, Deflate, LZMA2).\n */\n private _getEntryStreamStreaming(entry: SevenZipEntry): Readable {\n let started = false;\n let destroyed = false;\n let folderStream: ReturnType<typeof this.streamFolder> | null = null;\n\n const stream = new PassThrough();\n\n const originalRead = stream._read.bind(stream);\n stream._read = (size: number) => {\n if (!started && !destroyed) {\n started = true;\n defer(() => {\n if (destroyed) return;\n\n try {\n let crcValue = 0;\n const verifyCrc = entry._crc !== undefined;\n folderStream = this.streamFolder(entry._folderIndex);\n\n folderStream.output.on('data', (chunk: Buffer) => {\n if (destroyed) return;\n if (verifyCrc) {\n crcValue = crc32(chunk, crcValue);\n }\n if (!stream.write(chunk)) {\n folderStream?.pause();\n stream.once('drain', () => folderStream?.resume());\n }\n });\n\n folderStream.output.on('end', () => {\n if (destroyed) return;\n if (verifyCrc && crcValue !== entry._crc) {\n stream.destroy(createCodedError(`CRC mismatch for ${entry.path}: expected ${entry._crc?.toString(16)}, got ${crcValue.toString(16)}`, ErrorCode.CRC_MISMATCH));\n return;\n }\n stream.end();\n this.extractedPerFolder[entry._folderIndex] = (this.extractedPerFolder[entry._folderIndex] || 0) + 1;\n });\n\n folderStream.output.on('error', (err: Error) => {\n if (!destroyed) stream.destroy(err);\n });\n } catch (err) {\n if (!destroyed) {\n stream.destroy(err as Error);\n }\n }\n });\n }\n return originalRead(size);\n };\n\n // Override destroy to clean up folder stream\n // IMPORTANT: Emit error synchronously BEFORE calling original destroy.\n // On older Node, destroy() emits 'finish' and 'end' before 'error',\n // which causes piped streams to complete successfully before the error fires.\n const streamWithDestroy = stream as NodeJS.ReadableStream & { destroy?: (err?: Error) => NodeJS.ReadableStream };\n const originalDestroy = typeof streamWithDestroy.destroy === 'function' ? streamWithDestroy.destroy.bind(stream) : null;\n streamWithDestroy.destroy = (err?: Error) => {\n destroyed = true;\n if (err) stream.emit('error', err);\n if (folderStream) folderStream.destroy();\n if (originalDestroy) return originalDestroy();\n return stream;\n };\n\n return stream;\n }\n\n /**\n * Buffered extraction: decompress entire folder, slice out file.\n * Used for codecs that don't support incremental streaming (LZMA1, BCJ2).\n */\n private _getEntryStreamBuffered(entry: SevenZipEntry): Readable {\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n const streamsInfo = this.streamsInfo;\n const folderIdx = entry._folderIndex;\n let started = false;\n let destroyed = false;\n\n const stream = new PassThrough();\n\n const originalRead = stream._read.bind(stream);\n stream._read = (size: number) => {\n if (!started && !destroyed) {\n started = true;\n defer(() => {\n if (destroyed) return;\n\n this.getDecompressedFolder(folderIdx, (err, data) => {\n if (destroyed) return;\n if (err || !data) {\n stream.destroy(err || createCodedError('Unable to decompress folder', ErrorCode.DECOMPRESSION_FAILED));\n return;\n }\n\n try {\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 if (fileStart + fileSize > data.length) {\n stream.destroy(createCodedError(`File data out of bounds: offset ${fileStart} + size ${fileSize} > decompressed length ${data.length}`, ErrorCode.DECOMPRESSION_FAILED));\n return;\n }\n\n const fileData = data.slice(fileStart, fileStart + fileSize);\n\n if (entry._crc !== undefined) {\n const actualCRC = crc32(fileData);\n if (actualCRC !== entry._crc) {\n stream.destroy(createCodedError(`CRC mismatch for ${entry.path}: expected ${entry._crc.toString(16)}, got ${actualCRC.toString(16)}`, ErrorCode.CRC_MISMATCH));\n return;\n }\n }\n\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 if (!destroyed) {\n stream.push(fileData);\n stream.push(null);\n }\n } catch (decodeErr) {\n stream.destroy(decodeErr as Error);\n }\n });\n });\n }\n return originalRead(size);\n };\n\n // Override destroy to set destroyed flag\n // IMPORTANT: Emit error synchronously BEFORE calling original destroy.\n // On older Node, destroy() emits 'finish' and 'end' before 'error',\n // which causes piped streams to complete successfully before the error fires.\n const streamWithDestroy = stream as NodeJS.ReadableStream & { destroy?: (err?: Error) => NodeJS.ReadableStream };\n const originalDestroy = typeof streamWithDestroy.destroy === 'function' ? streamWithDestroy.destroy.bind(stream) : null;\n streamWithDestroy.destroy = (err?: Error) => {\n destroyed = true;\n if (err) stream.emit('error', err);\n if (originalDestroy) return originalDestroy();\n return stream;\n };\n\n return stream;\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, callback: BufferCallback): void {\n if (this.decompressedCache[folderIndex]) {\n callback(null, this.decompressedCache[folderIndex]);\n return;\n }\n\n if (this.pendingFolders[folderIndex]) {\n this.pendingFolders[folderIndex].push(callback);\n return;\n }\n\n if (!this.streamsInfo) {\n callback(createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n this.pendingFolders[folderIndex] = [callback];\n\n this.decodeFolderData(folderIndex, (err, data) => {\n const waiters = this.pendingFolders[folderIndex] || [];\n delete this.pendingFolders[folderIndex];\n\n if (err || !data) {\n for (let i = 0; i < waiters.length; i++) {\n waiters[i](err || createCodedError('Decoder returned no data', ErrorCode.DECOMPRESSION_FAILED));\n }\n return;\n }\n\n if (this.shouldCacheFolder(folderIndex)) {\n this.decompressedCache[folderIndex] = data;\n }\n\n for (let i = 0; i < waiters.length; i++) {\n waiters[i](null, data);\n }\n });\n }\n\n private shouldCacheFolder(folderIndex: number): boolean {\n const filesInFolder = this.filesPerFolder[folderIndex] || 1;\n const extractedFromFolder = this.extractedPerFolder[folderIndex] || 0;\n return filesInFolder - extractedFromFolder > 1;\n }\n\n private decodeFolderData(folderIndex: number, callback: BufferCallback): void {\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 if (!folder) {\n callback(createCodedError('Invalid folder index', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n if (this.folderHasBcj2(folder)) {\n this.decompressBcj2Folder(folderIndex, callback);\n return;\n }\n\n const packDataResult = this.readPackedData(folderIndex);\n if (packDataResult instanceof Error) {\n callback(packDataResult);\n return;\n }\n\n this.decodeFolderCoders(folder, packDataResult, 0, callback);\n }\n\n private readPackedData(folderIndex: number): Buffer | Error {\n if (!this.streamsInfo) {\n return createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n const folder = this.streamsInfo.folders[folderIndex];\n if (!folder) {\n return createCodedError('Invalid folder index', ErrorCode.CORRUPT_HEADER);\n }\n\n const signedHeaderSize = SIGNATURE_HEADER_SIZE;\n const signedPackPos = this.streamsInfo.packPos;\n let packPos = Math.max(signedHeaderSize, 0) + Math.max(signedPackPos, 0);\n\n let packStreamIndex = 0;\n for (let j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n\n for (let k = 0; k < packStreamIndex; k++) {\n const size = this.streamsInfo.packSizes[k];\n if (packPos + size < packPos) {\n return createCodedError(`Pack position overflow at index ${k}`, ErrorCode.CORRUPT_ARCHIVE);\n }\n packPos += size;\n }\n\n const packSize = this.streamsInfo.packSizes[packStreamIndex];\n if (packSize < 0 || packSize > Number.MAX_SAFE_INTEGER) {\n return createCodedError(`Invalid pack size: ${packSize}`, ErrorCode.CORRUPT_ARCHIVE);\n }\n\n if (packPos < 0 || packPos > Number.MAX_SAFE_INTEGER) {\n return createCodedError(`Invalid pack position: ${packPos}`, ErrorCode.CORRUPT_ARCHIVE);\n }\n\n return this.source.read(packPos, packSize);\n }\n\n private decodeFolderCoders(folder: { coders: { id: number[]; properties?: Buffer }[]; unpackSizes: number[] }, input: Buffer, index: number, callback: BufferCallback): void {\n if (index >= folder.coders.length) {\n callback(null, input);\n return;\n }\n\n const coderInfo = folder.coders[index];\n const codec = getCodec(coderInfo.id);\n const unpackSize = folder.unpackSizes[index];\n if (unpackSize < 0 || unpackSize > Number.MAX_SAFE_INTEGER) {\n callback(createCodedError(`Invalid unpack size: ${unpackSize}`, ErrorCode.CORRUPT_ARCHIVE));\n return;\n }\n\n this.decodeWithCodec(codec, input, coderInfo.properties, unpackSize, (err, output) => {\n if (err || !output) {\n callback(err || createCodedError('Decoder returned no data', ErrorCode.DECOMPRESSION_FAILED));\n return;\n }\n this.decodeFolderCoders(folder, output, index + 1, callback);\n });\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, callback: BufferCallback): void {\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 if (!folder) {\n callback(createCodedError('Invalid folder index', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n let packPos = SIGNATURE_HEADER_SIZE + this.streamsInfo.packPos;\n let packStreamIndex = 0;\n for (let j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n for (let k = 0; k < packStreamIndex; k++) {\n packPos += this.streamsInfo.packSizes[k];\n }\n\n const numPackStreams = folder.packedStreams.length;\n const packStreams: Buffer[] = [];\n let currentPos = packPos;\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 const coderOutputs: { [key: number]: Buffer } = {};\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 if (bcj2CoderIndex === -1) {\n callback(createCodedError('BCJ2 coder not found in folder', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\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 const processOrder = this.getCoderProcessOrder(folder, bcj2CoderIndex);\n\n const processNext = (orderIndex: number): void => {\n if (orderIndex >= processOrder.length) {\n this.finishBcj2Decode(folder, bcj2CoderIndex, coderOutputs, inputToPackStream, packStreams, callback);\n return;\n }\n\n const coderIdx = processOrder[orderIndex];\n if (coderIdx === bcj2CoderIndex) {\n processNext(orderIndex + 1);\n return;\n }\n\n const coder = folder.coders[coderIdx];\n const codec = getCodec(coder.id);\n\n let coderInputStart = 0;\n for (let ci2 = 0; ci2 < coderIdx; ci2++) {\n coderInputStart += folder.coders[ci2].numInStreams;\n }\n const inputIdx = coderInputStart;\n const packStreamIdx = inputToPackStream[inputIdx];\n const inputData = packStreams[packStreamIdx];\n const unpackSize = folder.unpackSizes[coderIdx];\n\n this.decodeWithCodec(codec, inputData, coder.properties, unpackSize, (err, outputData) => {\n if (err || !outputData) {\n callback(err || createCodedError('Decoder returned no data', ErrorCode.DECOMPRESSION_FAILED));\n return;\n }\n\n let coderOutputStart = 0;\n for (let co2 = 0; co2 < coderIdx; co2++) {\n coderOutputStart += folder.coders[co2].numOutStreams;\n }\n coderOutputs[coderOutputStart] = outputData;\n processNext(orderIndex + 1);\n });\n };\n\n processNext(0);\n }\n\n private finishBcj2Decode(\n folder: { coders: { id: number[]; numInStreams: number; numOutStreams: number; properties?: Buffer }[]; bindPairs: { inIndex: number; outIndex: number }[]; unpackSizes: number[] },\n bcj2CoderIndex: number,\n coderOutputs: { [key: number]: Buffer },\n inputToPackStream: { [key: number]: number },\n packStreams: Buffer[],\n callback: BufferCallback\n ): void {\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 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 bcj2Inputs.push(coderOutputs[boundOutput]);\n } else {\n const psIdx = inputToPackStream[globalIdx];\n bcj2Inputs.push(packStreams[psIdx]);\n }\n }\n\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 try {\n const result = decodeBcj2Multi(bcj2Inputs, undefined, bcj2UnpackSize);\n callback(null, result);\n } catch (err) {\n callback(err as Error);\n } finally {\n for (const key in coderOutputs) {\n delete coderOutputs[key];\n }\n packStreams.length = 0;\n }\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 // STREAMING METHODS (Phase 1+)\n // ============================================================\n\n /**\n * Check if a codec supports true streaming decompression.\n *\n * Only codecs that process data incrementally (not buffering entire input) qualify.\n * @param codecId - The codec ID as an array of bytes\n * @returns true if the codec can stream\n */\n private codecSupportsStreaming(codecId: number[]): boolean {\n // Convert to string key for comparison\n const key = codecId.map((b) => b.toString(16).toUpperCase()).join('-');\n\n // BZip2 - unbzip2-stream processes blocks incrementally\n if (key === '4-2-2') return true;\n\n // Copy/Store - PassThrough, obviously streams\n if (key === '0') return true;\n\n // Deflate - now uses zlib.createInflateRaw() which streams\n if (key === '4-1-8') return true;\n\n // Delta - now uses streaming Transform (Phase 2.5)\n if (key === '3') return true;\n\n // BCJ x86 - now uses streaming Transform (Phase 3.5)\n if (key === '3-3-1-3') return true;\n\n // BCJ ARM - now uses streaming Transform (Phase 3.5)\n if (key === '3-3-1-5') return true;\n\n // LZMA2 - now uses streaming Transform (Phase 5)\n if (key === '21') return true;\n\n // LZMA - still buffer-based (TODO: Phase 5 continuation)\n // Other BCJ variants (ARM64, ARMT, IA64, PPC, SPARC) - still buffer-based\n // BCJ2 - multi-stream architecture, never streamable\n return false;\n }\n\n /**\n * Check if a folder can be streamed (vs buffered).\n *\n * Streaming is possible when ALL codecs in the chain support streaming.\n * BCJ2 folders are never streamable due to their 4-stream architecture.\n *\n * @param folderIndex - Index of the folder to check\n * @returns true if the folder can be streamed\n */\n canStreamFolder(folderIndex: number): boolean {\n if (!this.streamsInfo) return false;\n\n const folder = this.streamsInfo.folders[folderIndex];\n if (!folder) return false;\n\n // BCJ2 requires special multi-stream handling - not streamable\n if (this.folderHasBcj2(folder)) {\n return false;\n }\n\n // Check if ALL codecs in chain support streaming\n for (let i = 0; i < folder.coders.length; i++) {\n if (!this.codecSupportsStreaming(folder.coders[i].id)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Stream a folder's decompression.\n *\n * Creates a pipeline: packed data → codec decoders → output stream\n *\n * @param folderIndex - Index of folder to decompress\n * @returns Object with output stream and control methods\n */\n streamFolder(folderIndex: number): {\n output: Readable;\n pause: () => void;\n resume: () => void;\n destroy: (err?: Error) => void;\n } {\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n if (!this.canStreamFolder(folderIndex)) {\n throw createCodedError('Folder does not support streaming', ErrorCode.UNSUPPORTED_CODEC);\n }\n\n const folder = this.streamsInfo.folders[folderIndex];\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 // Create readable stream from packed data\n const packedStream = this.source.createReadStream(packPos, packSize);\n\n // Build codec pipeline\n let stream: Readable = packedStream;\n const decoders: Stream.Transform[] = [];\n\n for (let i = 0; i < folder.coders.length; i++) {\n const coderInfo = folder.coders[i];\n const codec = getCodec(coderInfo.id);\n const unpackSize = folder.unpackSizes[i];\n const decoder = codec.createDecoder(coderInfo.properties, unpackSize);\n decoders.push(decoder);\n stream = stream.pipe(decoder);\n }\n\n return {\n output: stream,\n pause: () => packedStream.pause(),\n resume: () => packedStream.resume(),\n destroy: (err?: Error) => {\n // Check for destroy method existence (not available in Node 4 and earlier)\n const ps = packedStream as NodeJS.ReadableStream & { destroy?: (err?: Error) => void };\n if (typeof ps.destroy === 'function') ps.destroy(err);\n for (let i = 0; i < decoders.length; i++) {\n const d = decoders[i] as NodeJS.ReadableStream & { destroy?: (err?: Error) => void };\n if (typeof d.destroy === 'function') d.destroy(err);\n }\n },\n };\n }\n\n /**\n * Get a streaming entry stream (Promise-based API).\n *\n * For streamable folders: Returns a true streaming decompression\n * For non-streamable folders: Falls back to buffered extraction\n *\n * @param entry - The entry to get stream for\n * @returns Promise resolving to readable stream\n */\n async getEntryStreamStreaming(entry: SevenZipEntry): Promise<Readable> {\n if (!entry._hasStream || entry.type === 'directory') {\n const emptyStream = new PassThrough();\n emptyStream.end();\n return emptyStream;\n }\n\n const folderIndex = entry._folderIndex;\n\n // Fall back to buffered if not streamable\n if (!this.canStreamFolder(folderIndex)) {\n return this.getEntryStream(entry);\n }\n\n const filesInFolder = this.filesPerFolder[folderIndex] || 1;\n\n if (filesInFolder === 1) {\n // Single file - direct streaming\n return this.getEntryStreamDirect(entry);\n }\n // Multi-file folders use FolderStreamSplitter (Phase 2)\n return this.getEntryStreamFromSplitter(entry);\n }\n\n /**\n * Direct streaming for single-file folders.\n * Pipes folder decompression directly to output with CRC verification.\n */\n private getEntryStreamDirect(entry: SevenZipEntry): Promise<Readable> {\n return new Promise((resolve, reject) => {\n const outputStream = new PassThrough();\n let crcValue = 0;\n const verifyCrc = entry._crc !== undefined;\n\n try {\n const folderStream = this.streamFolder(entry._folderIndex);\n\n folderStream.output.on('data', (chunk: Buffer) => {\n if (verifyCrc) {\n crcValue = crc32(chunk, crcValue);\n }\n\n // Handle backpressure\n if (!outputStream.write(chunk)) {\n folderStream.pause();\n outputStream.once('drain', () => folderStream.resume());\n }\n });\n\n folderStream.output.on('end', () => {\n // Verify CRC\n if (verifyCrc && crcValue !== entry._crc) {\n const err = createCodedError(`CRC mismatch for ${entry.path}: expected ${entry._crc?.toString(16)}, got ${crcValue.toString(16)}`, ErrorCode.CRC_MISMATCH);\n outputStream.destroy(err);\n return;\n }\n\n outputStream.end();\n\n // Track extraction\n this.extractedPerFolder[entry._folderIndex] = (this.extractedPerFolder[entry._folderIndex] || 0) + 1;\n });\n\n folderStream.output.on('error', (err: Error) => {\n outputStream.destroy(err);\n });\n\n resolve(outputStream);\n } catch (err) {\n reject(err);\n }\n });\n }\n\n /**\n * Get stream from folder splitter (for multi-file folders).\n * Creates splitter on first access, reuses for subsequent files in same folder.\n */\n private getEntryStreamFromSplitter(entry: SevenZipEntry): Promise<Readable> {\n return new Promise((resolve, reject) => {\n const folderIndex = entry._folderIndex;\n\n // Get or create splitter for this folder\n let splitter = this.folderSplitters[folderIndex];\n\n if (!splitter) {\n // Create new splitter with file sizes and CRCs\n const folderInfo = this.getFolderFileInfo(folderIndex);\n\n splitter = new FolderStreamSplitter({\n fileSizes: folderInfo.fileSizes,\n verifyCrc: true,\n expectedCrcs: folderInfo.expectedCrcs,\n });\n\n this.folderSplitters[folderIndex] = splitter;\n\n // Start streaming the folder\n let folderStream: ReturnType<typeof this.streamFolder>;\n try {\n folderStream = this.streamFolder(folderIndex);\n } catch (err) {\n delete this.folderSplitters[folderIndex];\n reject(err);\n return;\n }\n\n folderStream.output.on('data', (chunk: Buffer) => {\n // Handle backpressure from splitter\n if (!splitter?.write(chunk)) {\n folderStream.pause();\n splitter?.onDrain(() => {\n folderStream.resume();\n });\n }\n });\n\n folderStream.output.on('end', () => {\n splitter?.end();\n delete this.folderSplitters[folderIndex];\n });\n\n folderStream.output.on('error', (_err: Error) => {\n splitter?.end();\n delete this.folderSplitters[folderIndex];\n });\n }\n\n // Get this entry's stream from splitter\n try {\n const fileStream = splitter.getFileStream(entry._streamIndexInFolder);\n\n // Track extraction when stream ends\n fileStream.on('end', () => {\n this.extractedPerFolder[folderIndex] = (this.extractedPerFolder[folderIndex] || 0) + 1;\n });\n\n resolve(fileStream);\n } catch (err) {\n reject(err);\n }\n });\n }\n\n /**\n * Get file sizes and CRCs for all files in a folder (in stream order).\n * Used by FolderStreamSplitter to know file boundaries.\n */\n private getFolderFileInfo(folderIndex: number): {\n fileSizes: number[];\n expectedCrcs: (number | undefined)[];\n } {\n const fileSizes: number[] = [];\n const expectedCrcs: (number | undefined)[] = [];\n\n // Collect entries in this folder, sorted by stream index\n const folderEntries: SevenZipEntry[] = [];\n for (let i = 0; i < this.entries.length; i++) {\n const e = this.entries[i];\n if (e._folderIndex === folderIndex && e._hasStream) {\n folderEntries.push(e);\n }\n }\n\n // Sort by stream index within folder\n folderEntries.sort((a, b) => a._streamIndexInFolder - b._streamIndexInFolder);\n\n for (let i = 0; i < folderEntries.length; i++) {\n const entry = folderEntries[i];\n fileSizes.push(entry.size);\n expectedCrcs.push(entry._crc);\n }\n\n return { fileSizes: fileSizes, expectedCrcs: expectedCrcs };\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":["once","crc32","PassThrough","defer","decodeBcj2Multi","getCodec","getCodecName","isBcj2Codec","isCodecSupported","FolderStreamSplitter","createCodedError","ErrorCode","FileAttribute","PropertyId","SIGNATURE_HEADER_SIZE","parseEncodedHeader","parseHeaderContent","parseSignatureHeader","readNumber","BufferSource","FileSource","SevenZipParser","decodeWithCodec","codec","input","properties","unpackSize","callback","done","decode","err","result","DECOMPRESSION_FAILED","parse","parsed","Promise","resolve","executor","parseInternal","Error","reject","signature","headerBuf","sigBuf","source","read","length","TRUNCATED_ARCHIVE","headerOffset","nextHeaderOffset","nextHeaderSize","finalize","buildEntries","headerResult","nextHeaderCRC","streamsInfo","filesInfo","codedErr","code","COMPRESSED_HEADER","handleCompressedHeader","headerErr","offset","propertyId","kMainStreamsInfo","kPackInfo","CORRUPT_HEADER","packInfoResult","parseEncodedHeaderStreams","codecId","candidates","compressedStart","packPos","push","packSize","packAreaEnd","searchStart","searchEnd","Math","max","scanChunkSize","chunkStart","chunk","limit","min","i","end","candidateData","slice","tryCandidate","index","decompressed","unpackCRC","undefined","actualCRC","parseDecompressedHeader","decompressedHeader","decompOffset","headerId","kHeader","buf","kEnd","packPosResult","value","bytesRead","numPackResult","kSize","sizeResult","kUnpackInfo","kFolder","numFoldersResult","numCodersResult","flags","idSize","hasAttributes","propsLenResult","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","_hasStream","_folderIndex","_canStream","canStreamFolder","type","isDirectory","mode","attributes","UNIX_EXTENSION","name","getBaseName","path","mtime","atime","ctime","isAntiFile","_streamIndexInFolder","getEntries","getEntryStream","emptyStream","folder","folders","coders","coder","id","codecName","UNSUPPORTED_CODEC","filesInFolder","_getEntryStreamStreaming","_getEntryStreamBuffered","started","destroyed","folderStream","stream","originalRead","_read","bind","crcValue","verifyCrc","streamFolder","output","on","write","pause","resume","destroy","toString","CRC_MISMATCH","streamWithDestroy","originalDestroy","emit","folderIdx","getDecompressedFolder","data","fileStart","m","prevStreamGlobalIndex","fileSize","fileData","decompressedCache","decodeErr","folderHasBcj2","pendingFolders","decodeFolderData","waiters","shouldCacheFolder","extractedFromFolder","decompressBcj2Folder","packDataResult","readPackedData","decodeFolderCoders","signedHeaderSize","signedPackPos","packStreamIndex","packedStreams","k","packSizes","CORRUPT_ARCHIVE","Number","MAX_SAFE_INTEGER","coderInfo","numPackStreams","packStreams","currentPos","p","coderOutputs","bcj2CoderIndex","c","inputToPackStream","pi","processOrder","getCoderProcessOrder","processNext","orderIndex","finishBcj2Decode","coderIdx","coderInputStart","ci2","numInStreams","inputIdx","packStreamIdx","inputData","outputData","coderOutputStart","co2","numOutStreams","bcj2InputStart","ci3","bcj2Inputs","bi","globalIdx","boundOutput","bp2","bindPairs","inIndex","outIndex","psIdx","bcj2OutputStart","co3","bcj2UnpackSize","key","excludeIdx","order","processed","changed","inputStart","canProcess","inp","bp","outIdx","outStart","oc","numOut","close","codecSupportsStreaming","map","b","toUpperCase","join","packedStream","createReadStream","decoders","decoder","createDecoder","pipe","ps","d","getEntryStreamStreaming","getEntryStreamDirect","getEntryStreamFromSplitter","outputStream","splitter","folderSplitters","folderInfo","getFolderFileInfo","fileSizes","expectedCrcs","onDrain","_err","fileStream","getFileStream","folderEntries","e","sort","a","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 once from 'call-once-fn';\nimport { crc32, PassThrough } from 'extract-base-iterator';\nimport type Stream from 'stream';\nimport { defer } from '../lib/defer.ts';\nimport type { ArchiveSource } from './ArchiveSource.ts';\nimport { type Codec, decodeBcj2Multi, getCodec, getCodecName, isBcj2Codec, isCodecSupported } from './codecs/index.ts';\nimport { FolderStreamSplitter } from './FolderStreamSplitter.ts';\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// 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 _canStream: boolean; // Whether this entry's folder supports streaming decompression\n}\n\n/** Callback for operations that don't return data */\nexport type VoidCallback = (error: Error | null) => void;\ntype BufferCallback = (error: Error | null, data?: Buffer) => void;\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 // Splitter cache for multi-file folder streaming (Phase 2)\n private folderSplitters: { [key: number]: FolderStreamSplitter } = {};\n private pendingFolders: { [key: number]: BufferCallback[] } = {};\n\n constructor(source: ArchiveSource) {\n this.source = source;\n }\n\n private decodeWithCodec(codec: Codec, input: Buffer, properties: Buffer | undefined, unpackSize: number | undefined, callback: BufferCallback): void {\n const done = once(callback);\n try {\n codec.decode(input, properties, unpackSize, (err, result) => {\n if (err) return done(err);\n if (!result) return done(createCodedError('Decoder returned no data', ErrorCode.DECOMPRESSION_FAILED));\n done(null, result);\n });\n } catch (err) {\n done(err as Error);\n }\n }\n\n /**\n * Parse the archive structure\n * Must be called before iterating entries\n */\n parse(callback?: VoidCallback): Promise<void> | void {\n if (this.parsed) {\n if (typeof callback === 'function') {\n callback(null);\n return;\n }\n if (typeof Promise === 'undefined') {\n return;\n }\n return Promise.resolve();\n }\n\n const executor = (done: VoidCallback): void => {\n this.parseInternal(done);\n };\n\n if (typeof callback === 'function') {\n executor(callback);\n return;\n }\n\n if (typeof Promise === 'undefined') {\n throw new Error('Promises are not available in this runtime. Please provide a callback to parse().');\n }\n\n return new Promise<void>((resolve, reject) => {\n executor((err) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n });\n });\n }\n\n private parseInternal(callback: VoidCallback): void {\n if (this.parsed) {\n callback(null);\n return;\n }\n\n let signature: SignatureHeader;\n let headerBuf: Buffer;\n\n try {\n const sigBuf = this.source.read(0, SIGNATURE_HEADER_SIZE);\n if (sigBuf.length < SIGNATURE_HEADER_SIZE) {\n callback(createCodedError('Archive too small', ErrorCode.TRUNCATED_ARCHIVE));\n return;\n }\n signature = parseSignatureHeader(sigBuf);\n this.signature = signature;\n\n const headerOffset = SIGNATURE_HEADER_SIZE + signature.nextHeaderOffset;\n headerBuf = this.source.read(headerOffset, signature.nextHeaderSize);\n if (headerBuf.length < signature.nextHeaderSize) {\n callback(createCodedError('Truncated header', ErrorCode.TRUNCATED_ARCHIVE));\n return;\n }\n } catch (err) {\n callback(err as Error);\n return;\n }\n\n const finalize = (): void => {\n try {\n this.buildEntries();\n this.parsed = true;\n callback(null);\n } catch (err) {\n callback(err as Error);\n }\n };\n\n try {\n const headerResult = parseEncodedHeader(headerBuf, this.signature?.nextHeaderCRC ?? 0);\n this.streamsInfo = headerResult.streamsInfo || null;\n this.filesInfo = headerResult.filesInfo;\n finalize();\n } catch (err) {\n const codedErr = err as CodedError;\n if (codedErr && codedErr.code === ErrorCode.COMPRESSED_HEADER) {\n this.handleCompressedHeader(headerBuf, (headerErr) => {\n if (headerErr) {\n callback(headerErr);\n return;\n }\n finalize();\n });\n } else {\n callback(err as Error);\n }\n }\n }\n\n /**\n * Handle compressed header (kEncodedHeader)\n */\n private handleCompressedHeader(headerBuf: Buffer, callback: VoidCallback): void {\n // Parse the encoded header info to get decompression parameters\n let offset = 1; // Skip kEncodedHeader byte\n\n const propertyId = headerBuf[offset++];\n if (propertyId !== PropertyId.kMainStreamsInfo && propertyId !== PropertyId.kPackInfo) {\n callback(createCodedError('Expected StreamsInfo in encoded header', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n let packInfoResult: ReturnType<SevenZipParser['parseEncodedHeaderStreams']>;\n try {\n packInfoResult = this.parseEncodedHeaderStreams(headerBuf, 1);\n } catch (err) {\n callback(err as Error);\n return;\n }\n\n const codec = getCodec(packInfoResult.codecId);\n const candidates: Buffer[] = [];\n\n const compressedStart = SIGNATURE_HEADER_SIZE + packInfoResult.packPos;\n candidates.push(this.source.read(compressedStart, packInfoResult.packSize));\n\n if (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 const scanChunkSize = 4096;\n for (let chunkStart = searchStart; chunkStart >= searchEnd; chunkStart -= scanChunkSize) {\n const chunk = this.source.read(chunkStart, scanChunkSize + packInfoResult.packSize);\n const limit = Math.min(chunk.length, scanChunkSize);\n for (let i = 0; i < limit; i++) {\n if (chunk[i] === 0x00) {\n const end = i + packInfoResult.packSize;\n if (end <= chunk.length) {\n const candidateData = chunk.slice(i, end);\n if (candidateData.length === packInfoResult.packSize) {\n candidates.push(candidateData);\n }\n }\n }\n }\n }\n }\n\n const tryCandidate = (index: number): void => {\n if (index >= candidates.length) {\n callback(createCodedError('Failed to decompress header - could not find valid LZMA data', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n this.decodeWithCodec(codec, candidates[index], packInfoResult.properties, packInfoResult.unpackSize, (err, decompressed) => {\n if (err || !decompressed) {\n tryCandidate(index + 1);\n return;\n }\n if (packInfoResult.unpackCRC !== undefined) {\n const actualCRC = crc32(decompressed);\n if (actualCRC !== packInfoResult.unpackCRC) {\n tryCandidate(index + 1);\n return;\n }\n }\n this.parseDecompressedHeader(decompressed, callback);\n });\n };\n\n tryCandidate(0);\n }\n\n private parseDecompressedHeader(decompressedHeader: Buffer, callback: VoidCallback): void {\n let decompOffset = 0;\n const headerId = decompressedHeader[decompOffset++];\n if (headerId !== PropertyId.kHeader) {\n callback(createCodedError('Expected kHeader in decompressed header', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n try {\n const result = parseHeaderContent(decompressedHeader, decompOffset);\n this.streamsInfo = result.streamsInfo || null;\n this.filesInfo = result.filesInfo;\n callback(null);\n } catch (err) {\n callback(err as Error);\n }\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 // Set _canStream for all entries now that we have complete folder info\n // This must be done after all entries are built because canStreamFolder\n // relies on the folder structure being fully parsed\n for (let i = 0; i < this.entries.length; i++) {\n const entry = this.entries[i];\n if (entry._hasStream && entry._folderIndex >= 0) {\n entry._canStream = this.canStreamFolder(entry._folderIndex);\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 _canStream: false, // Set after parsing completes when canStreamFolder is available\n };\n }\n\n /**\n * Get the list of entries\n */\n getEntries(): SevenZipEntry[] {\n if (!this.parsed) {\n throw new Error('SevenZipParser has not been parsed yet. Call parse(callback) before accessing entries.');\n }\n return this.entries;\n }\n\n /**\n * Get a readable stream for an entry's content.\n * Returns immediately - decompression happens when data is read (proper streaming).\n * Uses true streaming for codecs that support it, buffered for others.\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 // Use true streaming for single-file folders that support it.\n // Multi-file folders use buffered approach because streaming requires\n // accessing files in order, which doesn't work with concurrent extraction.\n const filesInFolder = this.filesPerFolder[entry._folderIndex] || 1;\n if (entry._canStream && filesInFolder === 1) {\n return this._getEntryStreamStreaming(entry);\n }\n return this._getEntryStreamBuffered(entry);\n }\n\n /**\n * True streaming: data flows through without buffering entire folder.\n * Only used for single-file folders with streamable codecs (BZip2, Deflate, LZMA2).\n */\n private _getEntryStreamStreaming(entry: SevenZipEntry): Readable {\n let started = false;\n let destroyed = false;\n let folderStream: ReturnType<typeof this.streamFolder> | null = null;\n\n const stream = new PassThrough();\n\n const originalRead = stream._read.bind(stream);\n stream._read = (size: number) => {\n if (!started && !destroyed) {\n started = true;\n defer(() => {\n if (destroyed) return;\n\n try {\n let crcValue = 0;\n const verifyCrc = entry._crc !== undefined;\n folderStream = this.streamFolder(entry._folderIndex);\n\n folderStream.output.on('data', (chunk: Buffer) => {\n if (destroyed) return;\n if (verifyCrc) {\n crcValue = crc32(chunk, crcValue);\n }\n if (!stream.write(chunk)) {\n folderStream?.pause();\n stream.once('drain', () => folderStream?.resume());\n }\n });\n\n folderStream.output.on('end', () => {\n if (destroyed) return;\n if (verifyCrc && crcValue !== entry._crc) {\n stream.destroy(createCodedError(`CRC mismatch for ${entry.path}: expected ${entry._crc?.toString(16)}, got ${crcValue.toString(16)}`, ErrorCode.CRC_MISMATCH));\n return;\n }\n stream.end();\n this.extractedPerFolder[entry._folderIndex] = (this.extractedPerFolder[entry._folderIndex] || 0) + 1;\n });\n\n folderStream.output.on('error', (err: Error) => {\n if (!destroyed) stream.destroy(err);\n });\n } catch (err) {\n if (!destroyed) {\n stream.destroy(err as Error);\n }\n }\n });\n }\n return originalRead(size);\n };\n\n // Override destroy to clean up folder stream\n // IMPORTANT: Emit error synchronously BEFORE calling original destroy.\n // On older Node, destroy() emits 'finish' and 'end' before 'error',\n // which causes piped streams to complete successfully before the error fires.\n const streamWithDestroy = stream as NodeJS.ReadableStream & { destroy?: (err?: Error) => NodeJS.ReadableStream };\n const originalDestroy = typeof streamWithDestroy.destroy === 'function' ? streamWithDestroy.destroy.bind(stream) : null;\n streamWithDestroy.destroy = (err?: Error) => {\n destroyed = true;\n if (err) stream.emit('error', err);\n if (folderStream) folderStream.destroy();\n if (originalDestroy) return originalDestroy();\n return stream;\n };\n\n return stream;\n }\n\n /**\n * Buffered extraction: decompress entire folder, slice out file.\n * Used for codecs that don't support incremental streaming (LZMA1, BCJ2).\n */\n private _getEntryStreamBuffered(entry: SevenZipEntry): Readable {\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n const streamsInfo = this.streamsInfo;\n const folderIdx = entry._folderIndex;\n let started = false;\n let destroyed = false;\n\n const stream = new PassThrough();\n\n const originalRead = stream._read.bind(stream);\n stream._read = (size: number) => {\n if (!started && !destroyed) {\n started = true;\n defer(() => {\n if (destroyed) return;\n\n this.getDecompressedFolder(folderIdx, (err, data) => {\n if (destroyed) return;\n if (err || !data) {\n stream.destroy(err || createCodedError('Unable to decompress folder', ErrorCode.DECOMPRESSION_FAILED));\n return;\n }\n\n try {\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 if (fileStart + fileSize > data.length) {\n stream.destroy(createCodedError(`File data out of bounds: offset ${fileStart} + size ${fileSize} > decompressed length ${data.length}`, ErrorCode.DECOMPRESSION_FAILED));\n return;\n }\n\n const fileData = data.slice(fileStart, fileStart + fileSize);\n\n if (entry._crc !== undefined) {\n const actualCRC = crc32(fileData);\n if (actualCRC !== entry._crc) {\n stream.destroy(createCodedError(`CRC mismatch for ${entry.path}: expected ${entry._crc.toString(16)}, got ${actualCRC.toString(16)}`, ErrorCode.CRC_MISMATCH));\n return;\n }\n }\n\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 if (!destroyed) {\n stream.push(fileData);\n stream.push(null);\n }\n } catch (decodeErr) {\n stream.destroy(decodeErr as Error);\n }\n });\n });\n }\n return originalRead(size);\n };\n\n // Override destroy to set destroyed flag\n // IMPORTANT: Emit error synchronously BEFORE calling original destroy.\n // On older Node, destroy() emits 'finish' and 'end' before 'error',\n // which causes piped streams to complete successfully before the error fires.\n const streamWithDestroy = stream as NodeJS.ReadableStream & { destroy?: (err?: Error) => NodeJS.ReadableStream };\n const originalDestroy = typeof streamWithDestroy.destroy === 'function' ? streamWithDestroy.destroy.bind(stream) : null;\n streamWithDestroy.destroy = (err?: Error) => {\n destroyed = true;\n if (err) stream.emit('error', err);\n if (originalDestroy) return originalDestroy();\n return stream;\n };\n\n return stream;\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, callback: BufferCallback): void {\n if (this.decompressedCache[folderIndex]) {\n callback(null, this.decompressedCache[folderIndex]);\n return;\n }\n\n if (this.pendingFolders[folderIndex]) {\n this.pendingFolders[folderIndex].push(callback);\n return;\n }\n\n if (!this.streamsInfo) {\n callback(createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n this.pendingFolders[folderIndex] = [callback];\n\n this.decodeFolderData(folderIndex, (err, data) => {\n const waiters = this.pendingFolders[folderIndex] || [];\n delete this.pendingFolders[folderIndex];\n\n if (err || !data) {\n for (let i = 0; i < waiters.length; i++) {\n waiters[i](err || createCodedError('Decoder returned no data', ErrorCode.DECOMPRESSION_FAILED));\n }\n return;\n }\n\n if (this.shouldCacheFolder(folderIndex)) {\n this.decompressedCache[folderIndex] = data;\n }\n\n for (let i = 0; i < waiters.length; i++) {\n waiters[i](null, data);\n }\n });\n }\n\n private shouldCacheFolder(folderIndex: number): boolean {\n const filesInFolder = this.filesPerFolder[folderIndex] || 1;\n const extractedFromFolder = this.extractedPerFolder[folderIndex] || 0;\n return filesInFolder - extractedFromFolder > 1;\n }\n\n private decodeFolderData(folderIndex: number, callback: BufferCallback): void {\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 if (!folder) {\n callback(createCodedError('Invalid folder index', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n if (this.folderHasBcj2(folder)) {\n this.decompressBcj2Folder(folderIndex, callback);\n return;\n }\n\n const packDataResult = this.readPackedData(folderIndex);\n if (packDataResult instanceof Error) {\n callback(packDataResult);\n return;\n }\n\n this.decodeFolderCoders(folder, packDataResult, 0, callback);\n }\n\n private readPackedData(folderIndex: number): Buffer | Error {\n if (!this.streamsInfo) {\n return createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n const folder = this.streamsInfo.folders[folderIndex];\n if (!folder) {\n return createCodedError('Invalid folder index', ErrorCode.CORRUPT_HEADER);\n }\n\n const signedHeaderSize = SIGNATURE_HEADER_SIZE;\n const signedPackPos = this.streamsInfo.packPos;\n let packPos = Math.max(signedHeaderSize, 0) + Math.max(signedPackPos, 0);\n\n let packStreamIndex = 0;\n for (let j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n\n for (let k = 0; k < packStreamIndex; k++) {\n const size = this.streamsInfo.packSizes[k];\n if (packPos + size < packPos) {\n return createCodedError(`Pack position overflow at index ${k}`, ErrorCode.CORRUPT_ARCHIVE);\n }\n packPos += size;\n }\n\n const packSize = this.streamsInfo.packSizes[packStreamIndex];\n if (packSize < 0 || packSize > Number.MAX_SAFE_INTEGER) {\n return createCodedError(`Invalid pack size: ${packSize}`, ErrorCode.CORRUPT_ARCHIVE);\n }\n\n if (packPos < 0 || packPos > Number.MAX_SAFE_INTEGER) {\n return createCodedError(`Invalid pack position: ${packPos}`, ErrorCode.CORRUPT_ARCHIVE);\n }\n\n return this.source.read(packPos, packSize);\n }\n\n private decodeFolderCoders(folder: { coders: { id: number[]; properties?: Buffer }[]; unpackSizes: number[] }, input: Buffer, index: number, callback: BufferCallback): void {\n if (index >= folder.coders.length) {\n callback(null, input);\n return;\n }\n\n const coderInfo = folder.coders[index];\n const codec = getCodec(coderInfo.id);\n const unpackSize = folder.unpackSizes[index];\n if (unpackSize < 0 || unpackSize > Number.MAX_SAFE_INTEGER) {\n callback(createCodedError(`Invalid unpack size: ${unpackSize}`, ErrorCode.CORRUPT_ARCHIVE));\n return;\n }\n\n this.decodeWithCodec(codec, input, coderInfo.properties, unpackSize, (err, output) => {\n if (err || !output) {\n callback(err || createCodedError('Decoder returned no data', ErrorCode.DECOMPRESSION_FAILED));\n return;\n }\n this.decodeFolderCoders(folder, output, index + 1, callback);\n });\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, callback: BufferCallback): void {\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 if (!folder) {\n callback(createCodedError('Invalid folder index', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\n let packPos = SIGNATURE_HEADER_SIZE + this.streamsInfo.packPos;\n let packStreamIndex = 0;\n for (let j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n for (let k = 0; k < packStreamIndex; k++) {\n packPos += this.streamsInfo.packSizes[k];\n }\n\n const numPackStreams = folder.packedStreams.length;\n const packStreams: Buffer[] = [];\n let currentPos = packPos;\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 const coderOutputs: { [key: number]: Buffer } = {};\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 if (bcj2CoderIndex === -1) {\n callback(createCodedError('BCJ2 coder not found in folder', ErrorCode.CORRUPT_HEADER));\n return;\n }\n\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 const processOrder = this.getCoderProcessOrder(folder, bcj2CoderIndex);\n\n const processNext = (orderIndex: number): void => {\n if (orderIndex >= processOrder.length) {\n this.finishBcj2Decode(folder, bcj2CoderIndex, coderOutputs, inputToPackStream, packStreams, callback);\n return;\n }\n\n const coderIdx = processOrder[orderIndex];\n if (coderIdx === bcj2CoderIndex) {\n processNext(orderIndex + 1);\n return;\n }\n\n const coder = folder.coders[coderIdx];\n const codec = getCodec(coder.id);\n\n let coderInputStart = 0;\n for (let ci2 = 0; ci2 < coderIdx; ci2++) {\n coderInputStart += folder.coders[ci2].numInStreams;\n }\n const inputIdx = coderInputStart;\n const packStreamIdx = inputToPackStream[inputIdx];\n const inputData = packStreams[packStreamIdx];\n const unpackSize = folder.unpackSizes[coderIdx];\n\n this.decodeWithCodec(codec, inputData, coder.properties, unpackSize, (err, outputData) => {\n if (err || !outputData) {\n callback(err || createCodedError('Decoder returned no data', ErrorCode.DECOMPRESSION_FAILED));\n return;\n }\n\n let coderOutputStart = 0;\n for (let co2 = 0; co2 < coderIdx; co2++) {\n coderOutputStart += folder.coders[co2].numOutStreams;\n }\n coderOutputs[coderOutputStart] = outputData;\n processNext(orderIndex + 1);\n });\n };\n\n processNext(0);\n }\n\n private finishBcj2Decode(\n folder: { coders: { id: number[]; numInStreams: number; numOutStreams: number; properties?: Buffer }[]; bindPairs: { inIndex: number; outIndex: number }[]; unpackSizes: number[] },\n bcj2CoderIndex: number,\n coderOutputs: { [key: number]: Buffer },\n inputToPackStream: { [key: number]: number },\n packStreams: Buffer[],\n callback: BufferCallback\n ): void {\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 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 bcj2Inputs.push(coderOutputs[boundOutput]);\n } else {\n const psIdx = inputToPackStream[globalIdx];\n bcj2Inputs.push(packStreams[psIdx]);\n }\n }\n\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 try {\n const result = decodeBcj2Multi(bcj2Inputs, undefined, bcj2UnpackSize);\n callback(null, result);\n } catch (err) {\n callback(err as Error);\n } finally {\n for (const key in coderOutputs) {\n delete coderOutputs[key];\n }\n packStreams.length = 0;\n }\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 // STREAMING METHODS (Phase 1+)\n // ============================================================\n\n /**\n * Check if a codec supports true streaming decompression.\n *\n * Only codecs that process data incrementally (not buffering entire input) qualify.\n * @param codecId - The codec ID as an array of bytes\n * @returns true if the codec can stream\n */\n private codecSupportsStreaming(codecId: number[]): boolean {\n // Convert to string key for comparison\n const key = codecId.map((b) => b.toString(16).toUpperCase()).join('-');\n\n // BZip2 - unbzip2-stream processes blocks incrementally\n if (key === '4-2-2') return true;\n\n // Copy/Store - PassThrough, obviously streams\n if (key === '0') return true;\n\n // Deflate - now uses zlib.createInflateRaw() which streams\n if (key === '4-1-8') return true;\n\n // Delta - now uses streaming Transform (Phase 2.5)\n if (key === '3') return true;\n\n // BCJ x86 - now uses streaming Transform (Phase 3.5)\n if (key === '3-3-1-3') return true;\n\n // BCJ ARM - now uses streaming Transform (Phase 3.5)\n if (key === '3-3-1-5') return true;\n\n // LZMA2 - now uses streaming Transform (Phase 5)\n if (key === '21') return true;\n\n // LZMA - still buffer-based (TODO: Phase 5 continuation)\n // Other BCJ variants (ARM64, ARMT, IA64, PPC, SPARC) - still buffer-based\n // BCJ2 - multi-stream architecture, never streamable\n return false;\n }\n\n /**\n * Check if a folder can be streamed (vs buffered).\n *\n * Streaming is possible when ALL codecs in the chain support streaming.\n * BCJ2 folders are never streamable due to their 4-stream architecture.\n *\n * @param folderIndex - Index of the folder to check\n * @returns true if the folder can be streamed\n */\n canStreamFolder(folderIndex: number): boolean {\n if (!this.streamsInfo) return false;\n\n const folder = this.streamsInfo.folders[folderIndex];\n if (!folder) return false;\n\n // BCJ2 requires special multi-stream handling - not streamable\n if (this.folderHasBcj2(folder)) {\n return false;\n }\n\n // Check if ALL codecs in chain support streaming\n for (let i = 0; i < folder.coders.length; i++) {\n if (!this.codecSupportsStreaming(folder.coders[i].id)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Stream a folder's decompression.\n *\n * Creates a pipeline: packed data → codec decoders → output stream\n *\n * @param folderIndex - Index of folder to decompress\n * @returns Object with output stream and control methods\n */\n streamFolder(folderIndex: number): {\n output: Readable;\n pause: () => void;\n resume: () => void;\n destroy: (err?: Error) => void;\n } {\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n if (!this.canStreamFolder(folderIndex)) {\n throw createCodedError('Folder does not support streaming', ErrorCode.UNSUPPORTED_CODEC);\n }\n\n const folder = this.streamsInfo.folders[folderIndex];\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 // Create readable stream from packed data\n const packedStream = this.source.createReadStream(packPos, packSize);\n\n // Build codec pipeline\n let stream: Readable = packedStream;\n const decoders: Stream.Transform[] = [];\n\n for (let i = 0; i < folder.coders.length; i++) {\n const coderInfo = folder.coders[i];\n const codec = getCodec(coderInfo.id);\n const unpackSize = folder.unpackSizes[i];\n const decoder = codec.createDecoder(coderInfo.properties, unpackSize);\n decoders.push(decoder);\n stream = stream.pipe(decoder);\n }\n\n return {\n output: stream,\n pause: () => packedStream.pause(),\n resume: () => packedStream.resume(),\n destroy: (err?: Error) => {\n // Check for destroy method existence (not available in Node 4 and earlier)\n const ps = packedStream as NodeJS.ReadableStream & { destroy?: (err?: Error) => void };\n if (typeof ps.destroy === 'function') ps.destroy(err);\n for (let i = 0; i < decoders.length; i++) {\n const d = decoders[i] as NodeJS.ReadableStream & { destroy?: (err?: Error) => void };\n if (typeof d.destroy === 'function') d.destroy(err);\n }\n },\n };\n }\n\n /**\n * Get a streaming entry stream (Promise-based API).\n *\n * For streamable folders: Returns a true streaming decompression\n * For non-streamable folders: Falls back to buffered extraction\n *\n * @param entry - The entry to get stream for\n * @returns Promise resolving to readable stream\n */\n async getEntryStreamStreaming(entry: SevenZipEntry): Promise<Readable> {\n if (!entry._hasStream || entry.type === 'directory') {\n const emptyStream = new PassThrough();\n emptyStream.end();\n return emptyStream;\n }\n\n const folderIndex = entry._folderIndex;\n\n // Fall back to buffered if not streamable\n if (!this.canStreamFolder(folderIndex)) {\n return this.getEntryStream(entry);\n }\n\n const filesInFolder = this.filesPerFolder[folderIndex] || 1;\n\n if (filesInFolder === 1) {\n // Single file - direct streaming\n return this.getEntryStreamDirect(entry);\n }\n // Multi-file folders use FolderStreamSplitter (Phase 2)\n return this.getEntryStreamFromSplitter(entry);\n }\n\n /**\n * Direct streaming for single-file folders.\n * Pipes folder decompression directly to output with CRC verification.\n */\n private getEntryStreamDirect(entry: SevenZipEntry): Promise<Readable> {\n return new Promise((resolve, reject) => {\n const outputStream = new PassThrough();\n let crcValue = 0;\n const verifyCrc = entry._crc !== undefined;\n\n try {\n const folderStream = this.streamFolder(entry._folderIndex);\n\n folderStream.output.on('data', (chunk: Buffer) => {\n if (verifyCrc) {\n crcValue = crc32(chunk, crcValue);\n }\n\n // Handle backpressure\n if (!outputStream.write(chunk)) {\n folderStream.pause();\n outputStream.once('drain', () => folderStream.resume());\n }\n });\n\n folderStream.output.on('end', () => {\n // Verify CRC\n if (verifyCrc && crcValue !== entry._crc) {\n const err = createCodedError(`CRC mismatch for ${entry.path}: expected ${entry._crc?.toString(16)}, got ${crcValue.toString(16)}`, ErrorCode.CRC_MISMATCH);\n outputStream.destroy(err);\n return;\n }\n\n outputStream.end();\n\n // Track extraction\n this.extractedPerFolder[entry._folderIndex] = (this.extractedPerFolder[entry._folderIndex] || 0) + 1;\n });\n\n folderStream.output.on('error', (err: Error) => {\n outputStream.destroy(err);\n });\n\n resolve(outputStream);\n } catch (err) {\n reject(err);\n }\n });\n }\n\n /**\n * Get stream from folder splitter (for multi-file folders).\n * Creates splitter on first access, reuses for subsequent files in same folder.\n */\n private getEntryStreamFromSplitter(entry: SevenZipEntry): Promise<Readable> {\n return new Promise((resolve, reject) => {\n const folderIndex = entry._folderIndex;\n\n // Get or create splitter for this folder\n let splitter = this.folderSplitters[folderIndex];\n\n if (!splitter) {\n // Create new splitter with file sizes and CRCs\n const folderInfo = this.getFolderFileInfo(folderIndex);\n\n splitter = new FolderStreamSplitter({\n fileSizes: folderInfo.fileSizes,\n verifyCrc: true,\n expectedCrcs: folderInfo.expectedCrcs,\n });\n\n this.folderSplitters[folderIndex] = splitter;\n\n // Start streaming the folder\n let folderStream: ReturnType<typeof this.streamFolder>;\n try {\n folderStream = this.streamFolder(folderIndex);\n } catch (err) {\n delete this.folderSplitters[folderIndex];\n reject(err);\n return;\n }\n\n folderStream.output.on('data', (chunk: Buffer) => {\n // Handle backpressure from splitter\n if (!splitter?.write(chunk)) {\n folderStream.pause();\n splitter?.onDrain(() => {\n folderStream.resume();\n });\n }\n });\n\n folderStream.output.on('end', () => {\n splitter?.end();\n delete this.folderSplitters[folderIndex];\n });\n\n folderStream.output.on('error', (_err: Error) => {\n splitter?.end();\n delete this.folderSplitters[folderIndex];\n });\n }\n\n // Get this entry's stream from splitter\n try {\n const fileStream = splitter.getFileStream(entry._streamIndexInFolder);\n\n // Track extraction when stream ends\n fileStream.on('end', () => {\n this.extractedPerFolder[folderIndex] = (this.extractedPerFolder[folderIndex] || 0) + 1;\n });\n\n resolve(fileStream);\n } catch (err) {\n reject(err);\n }\n });\n }\n\n /**\n * Get file sizes and CRCs for all files in a folder (in stream order).\n * Used by FolderStreamSplitter to know file boundaries.\n */\n private getFolderFileInfo(folderIndex: number): {\n fileSizes: number[];\n expectedCrcs: (number | undefined)[];\n } {\n const fileSizes: number[] = [];\n const expectedCrcs: (number | undefined)[] = [];\n\n // Collect entries in this folder, sorted by stream index\n const folderEntries: SevenZipEntry[] = [];\n for (let i = 0; i < this.entries.length; i++) {\n const e = this.entries[i];\n if (e._folderIndex === folderIndex && e._hasStream) {\n folderEntries.push(e);\n }\n }\n\n // Sort by stream index within folder\n folderEntries.sort((a, b) => a._streamIndexInFolder - b._streamIndexInFolder);\n\n for (let i = 0; i < folderEntries.length; i++) {\n const entry = folderEntries[i];\n fileSizes.push(entry.size);\n expectedCrcs.push(entry._crc);\n }\n\n return { fileSizes: fileSizes, expectedCrcs: expectedCrcs };\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":["once","crc32","PassThrough","defer","decodeBcj2Multi","getCodec","getCodecName","isBcj2Codec","isCodecSupported","FolderStreamSplitter","createCodedError","ErrorCode","FileAttribute","PropertyId","SIGNATURE_HEADER_SIZE","parseEncodedHeader","parseHeaderContent","parseSignatureHeader","readNumber","BufferSource","FileSource","SevenZipParser","decodeWithCodec","codec","input","properties","unpackSize","callback","done","decode","err","result","DECOMPRESSION_FAILED","parse","parsed","Promise","resolve","executor","parseInternal","Error","reject","signature","headerBuf","sigBuf","source","read","length","TRUNCATED_ARCHIVE","headerOffset","nextHeaderOffset","nextHeaderSize","finalize","buildEntries","headerResult","nextHeaderCRC","streamsInfo","filesInfo","codedErr","code","COMPRESSED_HEADER","handleCompressedHeader","headerErr","offset","propertyId","kMainStreamsInfo","kPackInfo","CORRUPT_HEADER","packInfoResult","parseEncodedHeaderStreams","codecId","candidates","compressedStart","packPos","push","packSize","packAreaEnd","searchStart","searchEnd","Math","max","scanChunkSize","chunkStart","chunk","limit","min","i","end","candidateData","slice","tryCandidate","index","decompressed","unpackCRC","undefined","actualCRC","parseDecompressedHeader","decompressedHeader","decompOffset","headerId","kHeader","buf","kEnd","packPosResult","value","bytesRead","numPackResult","kSize","sizeResult","kUnpackInfo","kFolder","numFoldersResult","numCodersResult","flags","idSize","hasAttributes","propsLenResult","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","_hasStream","_folderIndex","_canStream","canStreamFolder","type","isDirectory","mode","attributes","UNIX_EXTENSION","name","getBaseName","path","mtime","atime","ctime","isAntiFile","_streamIndexInFolder","getEntries","getEntryStream","emptyStream","folder","folders","coders","coder","id","codecName","UNSUPPORTED_CODEC","filesInFolder","_getEntryStreamStreaming","_getEntryStreamBuffered","started","destroyed","folderStream","stream","originalRead","_read","bind","crcValue","verifyCrc","streamFolder","output","on","write","pause","resume","destroy","toString","CRC_MISMATCH","streamWithDestroy","originalDestroy","emit","folderIdx","getDecompressedFolder","data","fileStart","m","prevStreamGlobalIndex","fileSize","fileData","decompressedCache","decodeErr","folderHasBcj2","pendingFolders","decodeFolderData","waiters","shouldCacheFolder","extractedFromFolder","decompressBcj2Folder","packDataResult","readPackedData","decodeFolderCoders","signedHeaderSize","signedPackPos","packStreamIndex","packedStreams","k","packSizes","CORRUPT_ARCHIVE","Number","MAX_SAFE_INTEGER","coderInfo","numPackStreams","packStreams","currentPos","p","coderOutputs","bcj2CoderIndex","c","inputToPackStream","pi","processOrder","getCoderProcessOrder","processNext","orderIndex","finishBcj2Decode","coderIdx","coderInputStart","ci2","numInStreams","inputIdx","packStreamIdx","inputData","outputData","coderOutputStart","co2","numOutStreams","bcj2InputStart","ci3","bcj2Inputs","bi","globalIdx","boundOutput","bp2","bindPairs","inIndex","outIndex","psIdx","bcj2OutputStart","co3","bcj2UnpackSize","key","excludeIdx","order","processed","changed","inputStart","canProcess","inp","bp","outIdx","outStart","oc","numOut","close","codecSupportsStreaming","map","b","toUpperCase","join","packedStream","createReadStream","decoders","decoder","createDecoder","pipe","ps","d","getEntryStreamStreaming","getEntryStreamDirect","getEntryStreamFromSplitter","outputStream","splitter","folderSplitters","folderInfo","getFolderFileInfo","fileSizes","expectedCrcs","onDrain","_err","fileStream","getFileStream","folderEntries","e","sort","a","lastSlash","lastIndexOf","lastBackslash","lastSep"],"mappings":"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"}