7z-iterator 0.1.5 → 0.1.6

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 (38) hide show
  1. package/dist/cjs/sevenz/SevenZipParser.d.cts +4 -1
  2. package/dist/cjs/sevenz/SevenZipParser.d.ts +4 -1
  3. package/dist/cjs/sevenz/SevenZipParser.js +45 -7
  4. package/dist/cjs/sevenz/SevenZipParser.js.map +1 -1
  5. package/dist/cjs/sevenz/codecs/Bcj2.js +17 -4
  6. package/dist/cjs/sevenz/codecs/Bcj2.js.map +1 -1
  7. package/dist/cjs/sevenz/codecs/Lzma.js +2 -1
  8. package/dist/cjs/sevenz/codecs/Lzma.js.map +1 -1
  9. package/dist/cjs/sevenz/codecs/Lzma2.d.cts +2 -2
  10. package/dist/cjs/sevenz/codecs/Lzma2.d.ts +2 -2
  11. package/dist/cjs/sevenz/codecs/Lzma2.js +30 -6
  12. package/dist/cjs/sevenz/codecs/Lzma2.js.map +1 -1
  13. package/dist/cjs/sevenz/codecs/streams.d.cts +7 -1
  14. package/dist/cjs/sevenz/codecs/streams.d.ts +7 -1
  15. package/dist/cjs/sevenz/codecs/streams.js +47 -17
  16. package/dist/cjs/sevenz/codecs/streams.js.map +1 -1
  17. package/dist/cjs/sevenz/constants.d.cts +1 -0
  18. package/dist/cjs/sevenz/constants.d.ts +1 -0
  19. package/dist/cjs/sevenz/constants.js +2 -1
  20. package/dist/cjs/sevenz/constants.js.map +1 -1
  21. package/dist/esm/sevenz/SevenZipParser.d.ts +4 -1
  22. package/dist/esm/sevenz/SevenZipParser.js +45 -7
  23. package/dist/esm/sevenz/SevenZipParser.js.map +1 -1
  24. package/dist/esm/sevenz/codecs/Bcj2.js +17 -4
  25. package/dist/esm/sevenz/codecs/Bcj2.js.map +1 -1
  26. package/dist/esm/sevenz/codecs/Lzma.js +2 -1
  27. package/dist/esm/sevenz/codecs/Lzma.js.map +1 -1
  28. package/dist/esm/sevenz/codecs/Lzma2.d.ts +2 -2
  29. package/dist/esm/sevenz/codecs/Lzma2.js +31 -7
  30. package/dist/esm/sevenz/codecs/Lzma2.js.map +1 -1
  31. package/dist/esm/sevenz/codecs/streams.d.ts +7 -1
  32. package/dist/esm/sevenz/codecs/streams.js +53 -17
  33. package/dist/esm/sevenz/codecs/streams.js.map +1 -1
  34. package/dist/esm/sevenz/constants.d.ts +1 -0
  35. package/dist/esm/sevenz/constants.js +2 -1
  36. package/dist/esm/sevenz/constants.js.map +1 -1
  37. package/package.json +4 -2
  38. package/patches/lzma-purejs+0.9.3.patch +196 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/SevenZipParser.ts"],"sourcesContent":["// SevenZipParser - Main 7z archive parser\n// Handles reading archive structure and providing file streams\n\nimport { allocBuffer, crc32 } from 'extract-base-iterator';\nimport fs from 'fs';\nimport { PassThrough, type Readable } from 'readable-stream';\nimport { decodeBcj2Multi, getCodec, getCodecName, isBcj2Codec, isCodecSupported } from './codecs/index.ts';\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// 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}\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\n/**\n * Buffer-based archive source\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/**\n * File descriptor based archive source\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 var buf = allocBuffer(length);\n var 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/**\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 // Cache for decompressed solid blocks (folderIndex -> decompressed data)\n private decompressedCache: { [key: number]: Buffer } = {};\n\n constructor(source: ArchiveSource) {\n this.source = source;\n }\n\n /**\n * Parse the archive structure\n * Must be called before iterating entries\n */\n parse(): void {\n if (this.parsed) return;\n\n // Read signature header\n var sigBuf = this.source.read(0, SIGNATURE_HEADER_SIZE);\n if (sigBuf.length < SIGNATURE_HEADER_SIZE) {\n throw createCodedError('Archive too small', ErrorCode.TRUNCATED_ARCHIVE);\n }\n\n this.signature = parseSignatureHeader(sigBuf);\n\n // Read encoded header\n var headerOffset = SIGNATURE_HEADER_SIZE + this.signature.nextHeaderOffset;\n var headerBuf = this.source.read(headerOffset, this.signature.nextHeaderSize);\n\n if (headerBuf.length < this.signature.nextHeaderSize) {\n throw createCodedError('Truncated header', ErrorCode.TRUNCATED_ARCHIVE);\n }\n\n // Parse encoded header (may need decompression)\n try {\n var headerResult = parseEncodedHeader(headerBuf, this.signature.nextHeaderCRC);\n this.streamsInfo = headerResult.streamsInfo || null;\n this.filesInfo = headerResult.filesInfo;\n } catch (err: unknown) {\n var codedErr = err as CodedError;\n if (codedErr && codedErr.code === ErrorCode.COMPRESSED_HEADER) {\n // Header is compressed - need to decompress first\n this.handleCompressedHeader(headerBuf);\n } else {\n throw err;\n }\n }\n\n // Build entries list\n this.buildEntries();\n this.parsed = true;\n }\n\n /**\n * Handle compressed header (kEncodedHeader)\n */\n private handleCompressedHeader(headerBuf: Buffer): void {\n // Parse the encoded header info to get decompression parameters\n var offset = 1; // Skip kEncodedHeader byte\n\n // Should have StreamsInfo for the header itself\n var propertyId = headerBuf[offset++];\n if (propertyId !== PropertyId.kMainStreamsInfo && propertyId !== PropertyId.kPackInfo) {\n throw createCodedError('Expected StreamsInfo in encoded header', ErrorCode.CORRUPT_HEADER);\n }\n\n // For now, we parse the streams info from the encoded header block\n // This tells us how to decompress the actual header\n\n // Read pack info from the encoded header structure\n var packInfoResult = this.parseEncodedHeaderStreams(headerBuf, 1);\n\n // Calculate compressed header position\n // For simple archives: header is at SIGNATURE_HEADER_SIZE + packPos\n // For BCJ2/complex archives: header may be at the END of pack data area\n // The pack data area ends at nextHeaderOffset (where encoded header starts)\n var compressedStart = SIGNATURE_HEADER_SIZE + packInfoResult.packPos;\n var compressedData = this.source.read(compressedStart, packInfoResult.packSize);\n\n // Decompress using the specified codec\n var codec = getCodec(packInfoResult.codecId);\n var decompressedHeader: Buffer | null = null;\n\n // Try decompressing from the calculated position first\n try {\n decompressedHeader = codec.decode(compressedData, packInfoResult.properties, packInfoResult.unpackSize);\n // Verify CRC if present\n if (packInfoResult.unpackCRC !== undefined) {\n var actualCRC = crc32(decompressedHeader);\n if (actualCRC !== packInfoResult.unpackCRC) {\n decompressedHeader = null; // CRC mismatch, need to search\n }\n }\n } catch {\n decompressedHeader = null; // Decompression failed, need to search\n }\n\n // If initial decompression failed, search for the correct position as a fallback\n // This handles edge cases where packPos doesn't point directly to header pack data\n if (decompressedHeader === null && this.signature) {\n var packAreaEnd = SIGNATURE_HEADER_SIZE + this.signature.nextHeaderOffset;\n var searchStart = packAreaEnd - packInfoResult.packSize;\n var searchEnd = Math.max(SIGNATURE_HEADER_SIZE, compressedStart - 100000);\n\n // Scan for LZMA data starting with 0x00 (range coder init)\n // Try each candidate and validate with CRC\n var scanChunkSize = 4096;\n searchLoop: for (var chunkStart = searchStart; chunkStart >= searchEnd; chunkStart -= scanChunkSize) {\n var chunk = this.source.read(chunkStart, scanChunkSize + packInfoResult.packSize);\n for (var i = 0; i < Math.min(chunk.length, scanChunkSize); i++) {\n if (chunk[i] === 0x00) {\n var candidateData = chunk.subarray(i, i + packInfoResult.packSize);\n if (candidateData.length === packInfoResult.packSize) {\n try {\n var candidateDecompressed = codec.decode(candidateData, packInfoResult.properties, packInfoResult.unpackSize);\n if (packInfoResult.unpackCRC !== undefined) {\n var candCRC = crc32(candidateDecompressed);\n if (candCRC === packInfoResult.unpackCRC) {\n decompressedHeader = candidateDecompressed;\n break searchLoop;\n }\n } else {\n decompressedHeader = candidateDecompressed;\n break searchLoop;\n }\n } catch {\n // Decompression failed, continue searching\n }\n }\n }\n }\n }\n }\n\n if (decompressedHeader === null) {\n throw createCodedError('Failed to decompress header - could not find valid LZMA data', ErrorCode.CORRUPT_HEADER);\n }\n\n // Now parse the decompressed header\n // It should start with kHeader\n var decompOffset = 0;\n var headerId = decompressedHeader[decompOffset++];\n if (headerId !== PropertyId.kHeader) {\n throw createCodedError('Expected kHeader in decompressed header', ErrorCode.CORRUPT_HEADER);\n }\n\n // Parse the decompressed header using shared function from headers.ts\n var result = parseHeaderContent(decompressedHeader, decompOffset);\n this.streamsInfo = result.streamsInfo || null;\n this.filesInfo = result.filesInfo;\n }\n\n /**\n * Parse streams info from encoded header block\n * This is a simplified parser for the header's own compression info\n */\n private parseEncodedHeaderStreams(\n buf: Buffer,\n offset: number\n ): {\n packPos: number;\n packSize: number;\n unpackSize: number;\n codecId: number[];\n properties?: Buffer;\n unpackCRC?: number;\n } {\n // This is a simplified parser for the encoded header's own streams info\n var packPos = 0;\n var packSize = 0;\n var unpackSize = 0;\n var codecId: number[] = [];\n var properties: Buffer | undefined;\n var unpackCRC: number | undefined;\n\n while (offset < buf.length) {\n var propertyId = buf[offset++];\n\n if (propertyId === PropertyId.kEnd) {\n break;\n }\n\n switch (propertyId) {\n case PropertyId.kPackInfo: {\n var packPosResult = readNumber(buf, offset);\n packPos = packPosResult.value;\n offset += packPosResult.bytesRead;\n\n var 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 var 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 var numFoldersResult = readNumber(buf, offset);\n offset += numFoldersResult.bytesRead;\n offset++; // external flag\n\n // Parse coder\n var numCodersResult = readNumber(buf, offset);\n offset += numCodersResult.bytesRead;\n\n var flags = buf[offset++];\n var idSize = flags & 0x0f;\n var hasAttributes = (flags & 0x20) !== 0;\n\n codecId = [];\n for (var i = 0; i < idSize; i++) {\n codecId.push(buf[offset++]);\n }\n\n if (hasAttributes) {\n var 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 var unpackSizeResult = readNumber(buf, offset);\n unpackSize = unpackSizeResult.value;\n offset += unpackSizeResult.bytesRead;\n } else if (buf[offset] === PropertyId.kCRC) {\n offset++;\n var 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 (var i = 0; i < this.filesInfo.length; i++) {\n var 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 var streamsPerFolder = this.streamsInfo.numUnpackStreamsPerFolder;\n\n // Now build entries with proper folder/stream tracking\n var streamIndex = 0;\n var folderIndex = 0;\n var streamInFolder = 0;\n var folderStreamCount = streamsPerFolder[0] || 0;\n\n for (var j = 0; j < this.filesInfo.length; j++) {\n var fileInfo = this.filesInfo[j];\n\n // Get size from unpackSizes for files with streams\n var size = 0;\n if (fileInfo.hasStream && streamIndex < this.streamsInfo.unpackSizes.length) {\n size = this.streamsInfo.unpackSizes[streamIndex];\n }\n\n var entry = this.createEntry(fileInfo, size, folderIndex, streamInFolder);\n entry._streamIndex = streamIndex;\n this.entries.push(entry);\n\n // Advance stream tracking for files with streams\n if (fileInfo.hasStream) {\n streamIndex++;\n streamInFolder++;\n\n // Check if we've exhausted streams in this folder\n if (streamInFolder >= folderStreamCount) {\n folderIndex++;\n streamInFolder = 0;\n folderStreamCount = streamsPerFolder[folderIndex] || 0;\n }\n }\n }\n }\n\n /**\n * Create an entry from file info\n */\n private createEntry(file: FileInfo, size: number, folderIndex: number, streamInFolder: number): SevenZipEntry {\n // Determine entry type\n // Note: 7z format doesn't natively support symlinks. p7zip with -snl stores\n // symlinks as regular files with the target path as content.\n var type: 'file' | 'directory' | 'link' = 'file';\n if (file.isDirectory) {\n type = 'directory';\n }\n\n // Calculate mode from Windows attributes\n var mode: number | undefined;\n if (file.attributes !== undefined) {\n // Check for Unix extension bit\n if ((file.attributes & FileAttribute.UNIX_EXTENSION) !== 0) {\n mode = (file.attributes >>> 16) & 0xffff;\n // Check for symlink (S_IFLNK = 0xA000)\n // Note: Most 7z implementations don't preserve symlink mode bits\n if ((mode & 0xf000) === 0xa000) {\n type = 'link';\n }\n } else if (file.isDirectory) {\n mode = 493; // 0o755\n } else {\n mode = 420; // 0o644\n }\n }\n\n return {\n name: getBaseName(file.name),\n path: file.name,\n type: type,\n size: size,\n mtime: file.mtime,\n atime: file.atime,\n ctime: file.ctime,\n mode: mode,\n isAntiFile: file.isAntiFile,\n _folderIndex: folderIndex,\n _streamIndex: 0, // Set by caller\n _streamIndexInFolder: streamInFolder,\n _hasStream: file.hasStream,\n };\n }\n\n /**\n * Get the list of entries\n */\n getEntries(): SevenZipEntry[] {\n if (!this.parsed) {\n this.parse();\n }\n return this.entries;\n }\n\n /**\n * Get a readable stream for an entry's content\n */\n getEntryStream(entry: SevenZipEntry): Readable {\n if (!entry._hasStream || entry.type === 'directory') {\n // Return empty stream for directories and empty files\n var 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 var 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 (var i = 0; i < folder.coders.length; i++) {\n var coder = folder.coders[i];\n if (!isCodecSupported(coder.id)) {\n var codecName = getCodecName(coder.id);\n throw createCodedError(`Unsupported codec: ${codecName}`, ErrorCode.UNSUPPORTED_CODEC);\n }\n }\n\n // Get decompressed data for this folder (with caching for solid archives)\n var data = this.getDecompressedFolder(entry._folderIndex);\n\n // Calculate file offset within the decompressed block\n // For solid archives, multiple files are concatenated in the block\n var fileStart = 0;\n for (var m = 0; m < entry._streamIndexInFolder; m++) {\n // Sum sizes of all streams before this one in the folder\n var prevStreamGlobalIndex = entry._streamIndex - entry._streamIndexInFolder + m;\n fileStart += this.streamsInfo.unpackSizes[prevStreamGlobalIndex];\n }\n\n var fileSize = entry.size;\n\n // Create a PassThrough stream with the file data\n var outputStream = new PassThrough();\n var fileData = data.slice(fileStart, fileStart + fileSize);\n outputStream.end(fileData);\n\n return outputStream;\n }\n\n /**\n * Check if a folder uses BCJ2 codec\n */\n private folderHasBcj2(folder: { coders: { id: number[] }[] }): boolean {\n for (var 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 caching for solid archives\n */\n private getDecompressedFolder(folderIndex: number): Buffer {\n // Check cache first\n if (this.decompressedCache[folderIndex]) {\n return this.decompressedCache[folderIndex];\n }\n\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n var folder = this.streamsInfo.folders[folderIndex];\n\n // Check if this folder uses BCJ2 (requires special multi-stream handling)\n if (this.folderHasBcj2(folder)) {\n var data = this.decompressBcj2Folder(folderIndex);\n this.decompressedCache[folderIndex] = data;\n return data;\n }\n\n // Calculate packed data position\n var packPos = SIGNATURE_HEADER_SIZE + this.streamsInfo.packPos;\n\n // Find which pack stream this folder uses\n var packStreamIndex = 0;\n for (var j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n\n // Calculate position of this pack stream\n for (var k = 0; k < packStreamIndex; k++) {\n packPos += this.streamsInfo.packSizes[k];\n }\n\n var packSize = this.streamsInfo.packSizes[packStreamIndex];\n\n // Read packed data\n var packedData = this.source.read(packPos, packSize);\n\n // Decompress through codec chain\n var data2 = packedData;\n for (var l = 0; l < folder.coders.length; l++) {\n var coderInfo = folder.coders[l];\n var codec = getCodec(coderInfo.id);\n // Get unpack size for this coder (needed by LZMA)\n var unpackSize = folder.unpackSizes[l];\n data2 = codec.decode(data2, coderInfo.properties, unpackSize);\n }\n\n // Cache for solid archives (when multiple files share a folder)\n this.decompressedCache[folderIndex] = data2;\n\n return data2;\n }\n\n /**\n * Decompress a BCJ2 folder with multi-stream handling\n * BCJ2 uses 4 input streams: main, call, jump, range coder\n */\n private decompressBcj2Folder(folderIndex: number): Buffer {\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n var folder = this.streamsInfo.folders[folderIndex];\n\n // Calculate starting pack position\n var packPos = SIGNATURE_HEADER_SIZE + this.streamsInfo.packPos;\n\n // Find which pack stream index this folder starts at\n var packStreamIndex = 0;\n for (var j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n\n // Calculate position\n for (var k = 0; k < packStreamIndex; k++) {\n packPos += this.streamsInfo.packSizes[k];\n }\n\n // Read all pack streams for this folder\n var numPackStreams = folder.packedStreams.length;\n var packStreams: Buffer[] = [];\n var currentPos = packPos;\n\n for (var p = 0; p < numPackStreams; p++) {\n var size = this.streamsInfo.packSizes[packStreamIndex + p];\n packStreams.push(this.source.read(currentPos, size));\n currentPos += size;\n }\n\n // Build a map of coder outputs\n // For BCJ2, typical structure is:\n // Coder 0: LZMA2 (main stream) - 1 in, 1 out\n // Coder 1: LZMA (call stream) - 1 in, 1 out\n // Coder 2: LZMA (jump stream) - 1 in, 1 out\n // Coder 3: BCJ2 - 4 in, 1 out\n // Pack streams map to: coder inputs not bound to other coder outputs\n\n // First, decompress each non-BCJ2 coder\n var coderOutputs: { [key: number]: Buffer } = {};\n\n // Find the BCJ2 coder\n var bcj2CoderIndex = -1;\n for (var c = 0; c < folder.coders.length; c++) {\n if (isBcj2Codec(folder.coders[c].id)) {\n bcj2CoderIndex = c;\n break;\n }\n }\n\n if (bcj2CoderIndex === -1) {\n throw createCodedError('BCJ2 coder not found in folder', ErrorCode.CORRUPT_HEADER);\n }\n\n // Build input stream index -> pack stream mapping\n // folder.packedStreams tells us which input indices are unbound and their order\n var inputToPackStream: { [key: number]: number } = {};\n for (var pi = 0; pi < folder.packedStreams.length; pi++) {\n inputToPackStream[folder.packedStreams[pi]] = pi;\n }\n\n // Build output stream index -> coder mapping\n var outputToCoder: { [key: number]: number } = {};\n var totalOutputs = 0;\n for (var co = 0; co < folder.coders.length; co++) {\n var numOut = folder.coders[co].numOutStreams;\n for (var outp = 0; outp < numOut; outp++) {\n outputToCoder[totalOutputs + outp] = co;\n }\n totalOutputs += numOut;\n }\n\n // Decompress non-BCJ2 coders (LZMA, LZMA2)\n // We need to process in dependency order\n var processed: { [key: number]: boolean } = {};\n\n var processOrder = this.getCoderProcessOrder(folder, bcj2CoderIndex);\n\n for (var po = 0; po < processOrder.length; po++) {\n var coderIdx = processOrder[po];\n if (coderIdx === bcj2CoderIndex) continue;\n\n var coder = folder.coders[coderIdx];\n var codec = getCodec(coder.id);\n\n // Find input for this coder\n var coderInputStart = 0;\n for (var ci2 = 0; ci2 < coderIdx; ci2++) {\n coderInputStart += folder.coders[ci2].numInStreams;\n }\n\n // Get input data (from pack stream)\n var inputIdx = coderInputStart;\n var packStreamIdx = inputToPackStream[inputIdx];\n var inputData = packStreams[packStreamIdx];\n\n // Decompress\n var unpackSize = folder.unpackSizes[coderIdx];\n var outputData = codec.decode(inputData, coder.properties, unpackSize);\n\n // Store in coder outputs\n var coderOutputStart = 0;\n for (var co2 = 0; co2 < coderIdx; co2++) {\n coderOutputStart += folder.coders[co2].numOutStreams;\n }\n coderOutputs[coderOutputStart] = outputData;\n processed[coderIdx] = true;\n }\n\n // Now process BCJ2\n // BCJ2 has 4 inputs, need to map them correctly\n // Standard order: main(LZMA2 output), call(LZMA output), jump(LZMA output), range(raw pack)\n var bcj2InputStart = 0;\n for (var ci3 = 0; ci3 < bcj2CoderIndex; ci3++) {\n bcj2InputStart += folder.coders[ci3].numInStreams;\n }\n\n var bcj2Inputs: Buffer[] = [];\n for (var bi = 0; bi < 4; bi++) {\n var globalIdx = bcj2InputStart + bi;\n\n // Check if this input is bound to a coder output\n var boundOutput = -1;\n for (var bp2 = 0; bp2 < folder.bindPairs.length; bp2++) {\n if (folder.bindPairs[bp2].inIndex === globalIdx) {\n boundOutput = folder.bindPairs[bp2].outIndex;\n break;\n }\n }\n\n if (boundOutput >= 0) {\n // Get from coder outputs\n bcj2Inputs.push(coderOutputs[boundOutput]);\n } else {\n // Get from pack streams\n var psIdx = inputToPackStream[globalIdx];\n bcj2Inputs.push(packStreams[psIdx]);\n }\n }\n\n // Get BCJ2 unpack size\n var bcj2OutputStart = 0;\n for (var co3 = 0; co3 < bcj2CoderIndex; co3++) {\n bcj2OutputStart += folder.coders[co3].numOutStreams;\n }\n var bcj2UnpackSize = folder.unpackSizes[bcj2OutputStart];\n\n // Decode BCJ2\n return decodeBcj2Multi(bcj2Inputs, undefined, bcj2UnpackSize);\n }\n\n /**\n * Get processing order for coders (dependency order)\n */\n private getCoderProcessOrder(folder: { coders: { numInStreams: number; numOutStreams: number }[]; bindPairs: { inIndex: number; outIndex: number }[] }, excludeIdx: number): number[] {\n var order: number[] = [];\n var processed: { [key: number]: boolean } = {};\n\n // Simple approach: process coders that don't depend on unprocessed outputs\n var changed = true;\n while (changed) {\n changed = false;\n for (var c = 0; c < folder.coders.length; c++) {\n if (processed[c] || c === excludeIdx) continue;\n\n // Check if all inputs are satisfied\n var inputStart = 0;\n for (var i = 0; i < c; i++) {\n inputStart += folder.coders[i].numInStreams;\n }\n\n var canProcess = true;\n for (var inp = 0; inp < folder.coders[c].numInStreams; inp++) {\n var globalIdx = inputStart + inp;\n // Check if bound to an unprocessed coder\n for (var bp = 0; bp < folder.bindPairs.length; bp++) {\n if (folder.bindPairs[bp].inIndex === globalIdx) {\n // Find which coder produces this output\n var outIdx = folder.bindPairs[bp].outIndex;\n var outStart = 0;\n for (var oc = 0; oc < folder.coders.length; oc++) {\n var numOut = folder.coders[oc].numOutStreams;\n if (outIdx < outStart + numOut) {\n if (!processed[oc] && oc !== excludeIdx) {\n canProcess = false;\n }\n break;\n }\n outStart += numOut;\n }\n }\n }\n }\n\n if (canProcess) {\n order.push(c);\n processed[c] = true;\n changed = true;\n }\n }\n }\n\n return order;\n }\n\n /**\n * Close the parser and release resources\n */\n close(): void {\n if (this.source) {\n this.source.close();\n }\n }\n}\n\n/**\n * Get base name from a path\n */\nfunction getBaseName(path: string): string {\n var lastSlash = path.lastIndexOf('/');\n var lastBackslash = path.lastIndexOf('\\\\');\n var lastSep = Math.max(lastSlash, lastBackslash);\n return lastSep >= 0 ? path.slice(lastSep + 1) : path;\n}\n"],"names":["allocBuffer","crc32","fs","PassThrough","decodeBcj2Multi","getCodec","getCodecName","isBcj2Codec","isCodecSupported","createCodedError","ErrorCode","FileAttribute","PropertyId","SIGNATURE_HEADER_SIZE","parseEncodedHeader","parseHeaderContent","parseSignatureHeader","readNumber","BufferSource","read","position","length","buffer","slice","getSize","close","FileSource","buf","bytesRead","readSync","fd","size","closeSync","_e","SevenZipParser","parse","parsed","sigBuf","source","TRUNCATED_ARCHIVE","signature","headerOffset","nextHeaderOffset","headerBuf","nextHeaderSize","headerResult","nextHeaderCRC","streamsInfo","filesInfo","err","codedErr","code","COMPRESSED_HEADER","handleCompressedHeader","buildEntries","offset","propertyId","kMainStreamsInfo","kPackInfo","CORRUPT_HEADER","packInfoResult","parseEncodedHeaderStreams","compressedStart","packPos","compressedData","packSize","codec","codecId","decompressedHeader","decode","properties","unpackSize","unpackCRC","undefined","actualCRC","packAreaEnd","searchStart","searchEnd","Math","max","scanChunkSize","searchLoop","chunkStart","chunk","i","min","candidateData","subarray","candidateDecompressed","candCRC","decompOffset","headerId","kHeader","result","kEnd","packPosResult","value","numPackResult","kSize","sizeResult","kUnpackInfo","kFolder","numFoldersResult","numCodersResult","flags","idSize","hasAttributes","push","propsLenResult","kCodersUnpackSize","unpackSizeResult","kCRC","allDefined","readUInt32LE","entries","file","createEntry","streamsPerFolder","numUnpackStreamsPerFolder","streamIndex","folderIndex","streamInFolder","folderStreamCount","j","fileInfo","hasStream","unpackSizes","entry","_streamIndex","type","isDirectory","mode","attributes","UNIX_EXTENSION","name","getBaseName","path","mtime","atime","ctime","isAntiFile","_folderIndex","_streamIndexInFolder","_hasStream","getEntries","getEntryStream","emptyStream","end","folder","folders","coders","coder","id","codecName","UNSUPPORTED_CODEC","data","getDecompressedFolder","fileStart","m","prevStreamGlobalIndex","fileSize","outputStream","fileData","folderHasBcj2","decompressedCache","decompressBcj2Folder","packStreamIndex","packedStreams","k","packSizes","packedData","data2","l","coderInfo","numPackStreams","packStreams","currentPos","p","coderOutputs","bcj2CoderIndex","c","inputToPackStream","pi","outputToCoder","totalOutputs","co","numOut","numOutStreams","outp","processed","processOrder","getCoderProcessOrder","po","coderIdx","coderInputStart","ci2","numInStreams","inputIdx","packStreamIdx","inputData","outputData","coderOutputStart","co2","bcj2InputStart","ci3","bcj2Inputs","bi","globalIdx","boundOutput","bp2","bindPairs","inIndex","outIndex","psIdx","bcj2OutputStart","co3","bcj2UnpackSize","excludeIdx","order","changed","inputStart","canProcess","inp","bp","outIdx","outStart","oc","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":["// SevenZipParser - Main 7z archive parser\n// Handles reading archive structure and providing file streams\n\nimport { allocBuffer, crc32 } from 'extract-base-iterator';\nimport fs from 'fs';\nimport { PassThrough, type Readable } from 'readable-stream';\nimport { decodeBcj2Multi, getCodec, getCodecName, isBcj2Codec, isCodecSupported } from './codecs/index.ts';\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// 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}\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\n/**\n * Buffer-based archive source\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/**\n * File descriptor based archive source\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 var buf = allocBuffer(length);\n var 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/**\n * SevenZipParser - parses 7z archives and provides entry iteration\n */\nexport class SevenZipParser {\n private source: ArchiveSource;\n private signature: SignatureHeader | null = null;\n private streamsInfo: StreamsInfo | null = null;\n private filesInfo: FileInfo[] = [];\n private entries: SevenZipEntry[] = [];\n private parsed = false;\n // Smart cache for decompressed solid blocks\n // Only caches when multiple files share a block, releases when last file extracted\n private decompressedCache: { [key: number]: Buffer } = {};\n // Track files per folder and how many have been extracted\n private filesPerFolder: { [key: number]: number } = {};\n private extractedPerFolder: { [key: number]: number } = {};\n\n constructor(source: ArchiveSource) {\n this.source = source;\n }\n\n /**\n * Parse the archive structure\n * Must be called before iterating entries\n */\n parse(): void {\n if (this.parsed) return;\n\n // Read signature header\n var sigBuf = this.source.read(0, SIGNATURE_HEADER_SIZE);\n if (sigBuf.length < SIGNATURE_HEADER_SIZE) {\n throw createCodedError('Archive too small', ErrorCode.TRUNCATED_ARCHIVE);\n }\n\n this.signature = parseSignatureHeader(sigBuf);\n\n // Read encoded header\n var headerOffset = SIGNATURE_HEADER_SIZE + this.signature.nextHeaderOffset;\n var headerBuf = this.source.read(headerOffset, this.signature.nextHeaderSize);\n\n if (headerBuf.length < this.signature.nextHeaderSize) {\n throw createCodedError('Truncated header', ErrorCode.TRUNCATED_ARCHIVE);\n }\n\n // Parse encoded header (may need decompression)\n try {\n var headerResult = parseEncodedHeader(headerBuf, this.signature.nextHeaderCRC);\n this.streamsInfo = headerResult.streamsInfo || null;\n this.filesInfo = headerResult.filesInfo;\n } catch (err: unknown) {\n var codedErr = err as CodedError;\n if (codedErr && codedErr.code === ErrorCode.COMPRESSED_HEADER) {\n // Header is compressed - need to decompress first\n this.handleCompressedHeader(headerBuf);\n } else {\n throw err;\n }\n }\n\n // Build entries list\n this.buildEntries();\n this.parsed = true;\n }\n\n /**\n * Handle compressed header (kEncodedHeader)\n */\n private handleCompressedHeader(headerBuf: Buffer): void {\n // Parse the encoded header info to get decompression parameters\n var offset = 1; // Skip kEncodedHeader byte\n\n // Should have StreamsInfo for the header itself\n var propertyId = headerBuf[offset++];\n if (propertyId !== PropertyId.kMainStreamsInfo && propertyId !== PropertyId.kPackInfo) {\n throw createCodedError('Expected StreamsInfo in encoded header', ErrorCode.CORRUPT_HEADER);\n }\n\n // For now, we parse the streams info from the encoded header block\n // This tells us how to decompress the actual header\n\n // Read pack info from the encoded header structure\n var packInfoResult = this.parseEncodedHeaderStreams(headerBuf, 1);\n\n // Calculate compressed header position\n // For simple archives: header is at SIGNATURE_HEADER_SIZE + packPos\n // For BCJ2/complex archives: header may be at the END of pack data area\n // The pack data area ends at nextHeaderOffset (where encoded header starts)\n var compressedStart = SIGNATURE_HEADER_SIZE + packInfoResult.packPos;\n var compressedData = this.source.read(compressedStart, packInfoResult.packSize);\n\n // Decompress using the specified codec\n var codec = getCodec(packInfoResult.codecId);\n var decompressedHeader: Buffer | null = null;\n\n // Try decompressing from the calculated position first\n try {\n decompressedHeader = codec.decode(compressedData, packInfoResult.properties, packInfoResult.unpackSize);\n // Verify CRC if present\n if (packInfoResult.unpackCRC !== undefined) {\n var actualCRC = crc32(decompressedHeader);\n if (actualCRC !== packInfoResult.unpackCRC) {\n decompressedHeader = null; // CRC mismatch, need to search\n }\n }\n } catch {\n decompressedHeader = null; // Decompression failed, need to search\n }\n\n // If initial decompression failed, search for the correct position as a fallback\n // This handles edge cases where packPos doesn't point directly to header pack data\n if (decompressedHeader === null && this.signature) {\n var packAreaEnd = SIGNATURE_HEADER_SIZE + this.signature.nextHeaderOffset;\n var searchStart = packAreaEnd - packInfoResult.packSize;\n var searchEnd = Math.max(SIGNATURE_HEADER_SIZE, compressedStart - 100000);\n\n // Scan for LZMA data starting with 0x00 (range coder init)\n // Try each candidate and validate with CRC\n var scanChunkSize = 4096;\n searchLoop: for (var chunkStart = searchStart; chunkStart >= searchEnd; chunkStart -= scanChunkSize) {\n var chunk = this.source.read(chunkStart, scanChunkSize + packInfoResult.packSize);\n for (var i = 0; i < Math.min(chunk.length, scanChunkSize); i++) {\n if (chunk[i] === 0x00) {\n var candidateData = chunk.subarray(i, i + packInfoResult.packSize);\n if (candidateData.length === packInfoResult.packSize) {\n try {\n var candidateDecompressed = codec.decode(candidateData, packInfoResult.properties, packInfoResult.unpackSize);\n if (packInfoResult.unpackCRC !== undefined) {\n var candCRC = crc32(candidateDecompressed);\n if (candCRC === packInfoResult.unpackCRC) {\n decompressedHeader = candidateDecompressed;\n break searchLoop;\n }\n } else {\n decompressedHeader = candidateDecompressed;\n break searchLoop;\n }\n } catch {\n // Decompression failed, continue searching\n }\n }\n }\n }\n }\n }\n\n if (decompressedHeader === null) {\n throw createCodedError('Failed to decompress header - could not find valid LZMA data', ErrorCode.CORRUPT_HEADER);\n }\n\n // Now parse the decompressed header\n // It should start with kHeader\n var decompOffset = 0;\n var headerId = decompressedHeader[decompOffset++];\n if (headerId !== PropertyId.kHeader) {\n throw createCodedError('Expected kHeader in decompressed header', ErrorCode.CORRUPT_HEADER);\n }\n\n // Parse the decompressed header using shared function from headers.ts\n var result = parseHeaderContent(decompressedHeader, decompOffset);\n this.streamsInfo = result.streamsInfo || null;\n this.filesInfo = result.filesInfo;\n }\n\n /**\n * Parse streams info from encoded header block\n * This is a simplified parser for the header's own compression info\n */\n private parseEncodedHeaderStreams(\n buf: Buffer,\n offset: number\n ): {\n packPos: number;\n packSize: number;\n unpackSize: number;\n codecId: number[];\n properties?: Buffer;\n unpackCRC?: number;\n } {\n // This is a simplified parser for the encoded header's own streams info\n var packPos = 0;\n var packSize = 0;\n var unpackSize = 0;\n var codecId: number[] = [];\n var properties: Buffer | undefined;\n var unpackCRC: number | undefined;\n\n while (offset < buf.length) {\n var propertyId = buf[offset++];\n\n if (propertyId === PropertyId.kEnd) {\n break;\n }\n\n switch (propertyId) {\n case PropertyId.kPackInfo: {\n var packPosResult = readNumber(buf, offset);\n packPos = packPosResult.value;\n offset += packPosResult.bytesRead;\n\n var 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 var 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 var numFoldersResult = readNumber(buf, offset);\n offset += numFoldersResult.bytesRead;\n offset++; // external flag\n\n // Parse coder\n var numCodersResult = readNumber(buf, offset);\n offset += numCodersResult.bytesRead;\n\n var flags = buf[offset++];\n var idSize = flags & 0x0f;\n var hasAttributes = (flags & 0x20) !== 0;\n\n codecId = [];\n for (var i = 0; i < idSize; i++) {\n codecId.push(buf[offset++]);\n }\n\n if (hasAttributes) {\n var 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 var unpackSizeResult = readNumber(buf, offset);\n unpackSize = unpackSizeResult.value;\n offset += unpackSizeResult.bytesRead;\n } else if (buf[offset] === PropertyId.kCRC) {\n offset++;\n var 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 (var i = 0; i < this.filesInfo.length; i++) {\n var 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 var streamsPerFolder = this.streamsInfo.numUnpackStreamsPerFolder;\n\n // Initialize files per folder count (for smart caching)\n for (var 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 var streamIndex = 0;\n var folderIndex = 0;\n var streamInFolder = 0;\n var folderStreamCount = streamsPerFolder[0] || 0;\n\n for (var j = 0; j < this.filesInfo.length; j++) {\n var fileInfo = this.filesInfo[j];\n\n // Get size from unpackSizes for files with streams\n var size = 0;\n if (fileInfo.hasStream && streamIndex < this.streamsInfo.unpackSizes.length) {\n size = this.streamsInfo.unpackSizes[streamIndex];\n }\n\n var entry = this.createEntry(fileInfo, size, folderIndex, streamInFolder);\n entry._streamIndex = streamIndex;\n this.entries.push(entry);\n\n // Advance stream tracking for files with streams\n if (fileInfo.hasStream) {\n streamIndex++;\n streamInFolder++;\n\n // Check if we've exhausted streams in this folder\n if (streamInFolder >= folderStreamCount) {\n folderIndex++;\n streamInFolder = 0;\n folderStreamCount = streamsPerFolder[folderIndex] || 0;\n }\n }\n }\n }\n\n /**\n * Create an entry from file info\n */\n private createEntry(file: FileInfo, size: number, folderIndex: number, streamInFolder: number): SevenZipEntry {\n // Determine entry type\n // Note: 7z format doesn't natively support symlinks. p7zip with -snl stores\n // symlinks as regular files with the target path as content.\n var type: 'file' | 'directory' | 'link' = 'file';\n if (file.isDirectory) {\n type = 'directory';\n }\n\n // Calculate mode from Windows attributes\n var mode: number | undefined;\n if (file.attributes !== undefined) {\n // Check for Unix extension bit\n if ((file.attributes & FileAttribute.UNIX_EXTENSION) !== 0) {\n mode = (file.attributes >>> 16) & 0xffff;\n // Check for symlink (S_IFLNK = 0xA000)\n // Note: Most 7z implementations don't preserve symlink mode bits\n if ((mode & 0xf000) === 0xa000) {\n type = 'link';\n }\n } else if (file.isDirectory) {\n mode = 493; // 0o755\n } else {\n mode = 420; // 0o644\n }\n }\n\n return {\n name: getBaseName(file.name),\n path: file.name,\n type: type,\n size: size,\n mtime: file.mtime,\n atime: file.atime,\n ctime: file.ctime,\n mode: mode,\n isAntiFile: file.isAntiFile,\n _folderIndex: folderIndex,\n _streamIndex: 0, // Set by caller\n _streamIndexInFolder: streamInFolder,\n _hasStream: file.hasStream,\n };\n }\n\n /**\n * Get the list of entries\n */\n getEntries(): SevenZipEntry[] {\n if (!this.parsed) {\n this.parse();\n }\n return this.entries;\n }\n\n /**\n * Get a readable stream for an entry's content\n */\n getEntryStream(entry: SevenZipEntry): Readable {\n if (!entry._hasStream || entry.type === 'directory') {\n // Return empty stream for directories and empty files\n var 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 var 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 (var i = 0; i < folder.coders.length; i++) {\n var coder = folder.coders[i];\n if (!isCodecSupported(coder.id)) {\n var codecName = getCodecName(coder.id);\n throw createCodedError(`Unsupported codec: ${codecName}`, ErrorCode.UNSUPPORTED_CODEC);\n }\n }\n\n // Get decompressed data for this folder (with smart caching)\n var folderIdx = entry._folderIndex;\n var data = this.getDecompressedFolder(folderIdx);\n\n // Calculate file offset within the decompressed block\n // For solid archives, multiple files are concatenated in the block\n var fileStart = 0;\n for (var m = 0; m < entry._streamIndexInFolder; m++) {\n // Sum sizes of all streams before this one in the folder\n var prevStreamGlobalIndex = entry._streamIndex - entry._streamIndexInFolder + m;\n fileStart += this.streamsInfo.unpackSizes[prevStreamGlobalIndex];\n }\n\n var fileSize = entry.size;\n\n // Create a PassThrough stream with the file data\n var outputStream = new PassThrough();\n\n // Bounds check to prevent \"oob\" error on older Node versions\n if (fileStart + fileSize > data.length) {\n throw createCodedError(`File data out of bounds: offset ${fileStart} + size ${fileSize} > decompressed length ${data.length}`, ErrorCode.DECOMPRESSION_FAILED);\n }\n\n var fileData = data.slice(fileStart, fileStart + fileSize);\n outputStream.end(fileData);\n\n // Track extraction and release cache when all files from this folder are done\n this.extractedPerFolder[folderIdx] = (this.extractedPerFolder[folderIdx] || 0) + 1;\n if (this.extractedPerFolder[folderIdx] >= this.filesPerFolder[folderIdx]) {\n // All files from this folder extracted, release cache\n delete this.decompressedCache[folderIdx];\n }\n\n return outputStream;\n }\n\n /**\n * Check if a folder uses BCJ2 codec\n */\n private folderHasBcj2(folder: { coders: { id: number[] }[] }): boolean {\n for (var i = 0; i < folder.coders.length; i++) {\n if (isBcj2Codec(folder.coders[i].id)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get decompressed data for a folder, with smart caching for solid archives\n * Only caches when multiple files share a block, releases when last file extracted\n */\n private getDecompressedFolder(folderIndex: number): Buffer {\n // Check cache first\n if (this.decompressedCache[folderIndex]) {\n return this.decompressedCache[folderIndex];\n }\n\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n var folder = this.streamsInfo.folders[folderIndex];\n\n // Check how many files remain in this folder\n var filesInFolder = this.filesPerFolder[folderIndex] || 1;\n var extractedFromFolder = this.extractedPerFolder[folderIndex] || 0;\n var remainingFiles = filesInFolder - extractedFromFolder;\n // Only cache if more than 1 file remains (including the current one being extracted)\n var shouldCache = remainingFiles > 1;\n\n // Check if this folder uses BCJ2 (requires special multi-stream handling)\n if (this.folderHasBcj2(folder)) {\n var data = this.decompressBcj2Folder(folderIndex);\n if (shouldCache) {\n this.decompressedCache[folderIndex] = data;\n }\n return data;\n }\n\n // Calculate packed data position\n var packPos = SIGNATURE_HEADER_SIZE + this.streamsInfo.packPos;\n\n // Find which pack stream this folder uses\n var packStreamIndex = 0;\n for (var j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n\n // Calculate position of this pack stream\n for (var k = 0; k < packStreamIndex; k++) {\n packPos += this.streamsInfo.packSizes[k];\n }\n\n var packSize = this.streamsInfo.packSizes[packStreamIndex];\n\n // Read packed data\n var packedData = this.source.read(packPos, packSize);\n\n // Decompress through codec chain\n var data2 = packedData;\n for (var l = 0; l < folder.coders.length; l++) {\n var coderInfo = folder.coders[l];\n var codec = getCodec(coderInfo.id);\n // Get unpack size for this coder (needed by LZMA)\n var unpackSize = folder.unpackSizes[l];\n data2 = codec.decode(data2, coderInfo.properties, unpackSize);\n }\n\n // Cache only if more files remain in this folder\n if (shouldCache) {\n this.decompressedCache[folderIndex] = data2;\n }\n\n return data2;\n }\n\n /**\n * Decompress a BCJ2 folder with multi-stream handling\n * BCJ2 uses 4 input streams: main, call, jump, range coder\n */\n private decompressBcj2Folder(folderIndex: number): Buffer {\n if (!this.streamsInfo) {\n throw createCodedError('No streams info available', ErrorCode.CORRUPT_HEADER);\n }\n\n var folder = this.streamsInfo.folders[folderIndex];\n\n // Calculate starting pack position\n var packPos = SIGNATURE_HEADER_SIZE + this.streamsInfo.packPos;\n\n // Find which pack stream index this folder starts at\n var packStreamIndex = 0;\n for (var j = 0; j < folderIndex; j++) {\n packStreamIndex += this.streamsInfo.folders[j].packedStreams.length;\n }\n\n // Calculate position\n for (var k = 0; k < packStreamIndex; k++) {\n packPos += this.streamsInfo.packSizes[k];\n }\n\n // Read all pack streams for this folder\n var numPackStreams = folder.packedStreams.length;\n var packStreams: Buffer[] = [];\n var currentPos = packPos;\n\n for (var p = 0; p < numPackStreams; p++) {\n var size = this.streamsInfo.packSizes[packStreamIndex + p];\n packStreams.push(this.source.read(currentPos, size));\n currentPos += size;\n }\n\n // Build a map of coder outputs\n // For BCJ2, typical structure is:\n // Coder 0: LZMA2 (main stream) - 1 in, 1 out\n // Coder 1: LZMA (call stream) - 1 in, 1 out\n // Coder 2: LZMA (jump stream) - 1 in, 1 out\n // Coder 3: BCJ2 - 4 in, 1 out\n // Pack streams map to: coder inputs not bound to other coder outputs\n\n // First, decompress each non-BCJ2 coder\n var coderOutputs: { [key: number]: Buffer } = {};\n\n // Find the BCJ2 coder\n var bcj2CoderIndex = -1;\n for (var c = 0; c < folder.coders.length; c++) {\n if (isBcj2Codec(folder.coders[c].id)) {\n bcj2CoderIndex = c;\n break;\n }\n }\n\n if (bcj2CoderIndex === -1) {\n throw createCodedError('BCJ2 coder not found in folder', ErrorCode.CORRUPT_HEADER);\n }\n\n // Build input stream index -> pack stream mapping\n // folder.packedStreams tells us which input indices are unbound and their order\n var inputToPackStream: { [key: number]: number } = {};\n for (var pi = 0; pi < folder.packedStreams.length; pi++) {\n inputToPackStream[folder.packedStreams[pi]] = pi;\n }\n\n // Build output stream index -> coder mapping\n var outputToCoder: { [key: number]: number } = {};\n var totalOutputs = 0;\n for (var co = 0; co < folder.coders.length; co++) {\n var numOut = folder.coders[co].numOutStreams;\n for (var outp = 0; outp < numOut; outp++) {\n outputToCoder[totalOutputs + outp] = co;\n }\n totalOutputs += numOut;\n }\n\n // Decompress non-BCJ2 coders (LZMA, LZMA2)\n // We need to process in dependency order\n var processed: { [key: number]: boolean } = {};\n\n var processOrder = this.getCoderProcessOrder(folder, bcj2CoderIndex);\n\n for (var po = 0; po < processOrder.length; po++) {\n var coderIdx = processOrder[po];\n if (coderIdx === bcj2CoderIndex) continue;\n\n var coder = folder.coders[coderIdx];\n var codec = getCodec(coder.id);\n\n // Find input for this coder\n var coderInputStart = 0;\n for (var ci2 = 0; ci2 < coderIdx; ci2++) {\n coderInputStart += folder.coders[ci2].numInStreams;\n }\n\n // Get input data (from pack stream)\n var inputIdx = coderInputStart;\n var packStreamIdx = inputToPackStream[inputIdx];\n var inputData = packStreams[packStreamIdx];\n\n // Decompress\n var unpackSize = folder.unpackSizes[coderIdx];\n var outputData = codec.decode(inputData, coder.properties, unpackSize);\n\n // Store in coder outputs\n var coderOutputStart = 0;\n for (var co2 = 0; co2 < coderIdx; co2++) {\n coderOutputStart += folder.coders[co2].numOutStreams;\n }\n coderOutputs[coderOutputStart] = outputData;\n processed[coderIdx] = true;\n }\n\n // Now process BCJ2\n // BCJ2 has 4 inputs, need to map them correctly\n // Standard order: main(LZMA2 output), call(LZMA output), jump(LZMA output), range(raw pack)\n var bcj2InputStart = 0;\n for (var ci3 = 0; ci3 < bcj2CoderIndex; ci3++) {\n bcj2InputStart += folder.coders[ci3].numInStreams;\n }\n\n var bcj2Inputs: Buffer[] = [];\n for (var bi = 0; bi < 4; bi++) {\n var globalIdx = bcj2InputStart + bi;\n\n // Check if this input is bound to a coder output\n var boundOutput = -1;\n for (var bp2 = 0; bp2 < folder.bindPairs.length; bp2++) {\n if (folder.bindPairs[bp2].inIndex === globalIdx) {\n boundOutput = folder.bindPairs[bp2].outIndex;\n break;\n }\n }\n\n if (boundOutput >= 0) {\n // Get from coder outputs\n bcj2Inputs.push(coderOutputs[boundOutput]);\n } else {\n // Get from pack streams\n var psIdx = inputToPackStream[globalIdx];\n bcj2Inputs.push(packStreams[psIdx]);\n }\n }\n\n // Get BCJ2 unpack size\n var bcj2OutputStart = 0;\n for (var co3 = 0; co3 < bcj2CoderIndex; co3++) {\n bcj2OutputStart += folder.coders[co3].numOutStreams;\n }\n var bcj2UnpackSize = folder.unpackSizes[bcj2OutputStart];\n\n // Memory optimization: Clear intermediate buffers to help GC\n // These are no longer needed after bcj2Inputs is built\n for (var key in coderOutputs) {\n delete coderOutputs[key];\n }\n // Clear packStreams array (allows GC to free compressed data)\n packStreams.length = 0;\n\n // Decode BCJ2\n return decodeBcj2Multi(bcj2Inputs, undefined, bcj2UnpackSize);\n }\n\n /**\n * Get processing order for coders (dependency order)\n */\n private getCoderProcessOrder(folder: { coders: { numInStreams: number; numOutStreams: number }[]; bindPairs: { inIndex: number; outIndex: number }[] }, excludeIdx: number): number[] {\n var order: number[] = [];\n var processed: { [key: number]: boolean } = {};\n\n // Simple approach: process coders that don't depend on unprocessed outputs\n var changed = true;\n while (changed) {\n changed = false;\n for (var c = 0; c < folder.coders.length; c++) {\n if (processed[c] || c === excludeIdx) continue;\n\n // Check if all inputs are satisfied\n var inputStart = 0;\n for (var i = 0; i < c; i++) {\n inputStart += folder.coders[i].numInStreams;\n }\n\n var canProcess = true;\n for (var inp = 0; inp < folder.coders[c].numInStreams; inp++) {\n var globalIdx = inputStart + inp;\n // Check if bound to an unprocessed coder\n for (var bp = 0; bp < folder.bindPairs.length; bp++) {\n if (folder.bindPairs[bp].inIndex === globalIdx) {\n // Find which coder produces this output\n var outIdx = folder.bindPairs[bp].outIndex;\n var outStart = 0;\n for (var oc = 0; oc < folder.coders.length; oc++) {\n var numOut = folder.coders[oc].numOutStreams;\n if (outIdx < outStart + numOut) {\n if (!processed[oc] && oc !== excludeIdx) {\n canProcess = false;\n }\n break;\n }\n outStart += numOut;\n }\n }\n }\n }\n\n if (canProcess) {\n order.push(c);\n processed[c] = true;\n changed = true;\n }\n }\n }\n\n return order;\n }\n\n /**\n * Close the parser and release resources\n */\n close(): void {\n if (this.source) {\n this.source.close();\n }\n }\n}\n\n/**\n * Get base name from a path\n */\nfunction getBaseName(path: string): string {\n var lastSlash = path.lastIndexOf('/');\n var lastBackslash = path.lastIndexOf('\\\\');\n var lastSep = Math.max(lastSlash, lastBackslash);\n return lastSep >= 0 ? path.slice(lastSep + 1) : path;\n}\n"],"names":["allocBuffer","crc32","fs","PassThrough","decodeBcj2Multi","getCodec","getCodecName","isBcj2Codec","isCodecSupported","createCodedError","ErrorCode","FileAttribute","PropertyId","SIGNATURE_HEADER_SIZE","parseEncodedHeader","parseHeaderContent","parseSignatureHeader","readNumber","BufferSource","read","position","length","buffer","slice","getSize","close","FileSource","buf","bytesRead","readSync","fd","size","closeSync","_e","SevenZipParser","parse","parsed","sigBuf","source","TRUNCATED_ARCHIVE","signature","headerOffset","nextHeaderOffset","headerBuf","nextHeaderSize","headerResult","nextHeaderCRC","streamsInfo","filesInfo","err","codedErr","code","COMPRESSED_HEADER","handleCompressedHeader","buildEntries","offset","propertyId","kMainStreamsInfo","kPackInfo","CORRUPT_HEADER","packInfoResult","parseEncodedHeaderStreams","compressedStart","packPos","compressedData","packSize","codec","codecId","decompressedHeader","decode","properties","unpackSize","unpackCRC","undefined","actualCRC","packAreaEnd","searchStart","searchEnd","Math","max","scanChunkSize","searchLoop","chunkStart","chunk","i","min","candidateData","subarray","candidateDecompressed","candCRC","decompOffset","headerId","kHeader","result","kEnd","packPosResult","value","numPackResult","kSize","sizeResult","kUnpackInfo","kFolder","numFoldersResult","numCodersResult","flags","idSize","hasAttributes","push","propsLenResult","kCodersUnpackSize","unpackSizeResult","kCRC","allDefined","readUInt32LE","entries","file","createEntry","streamsPerFolder","numUnpackStreamsPerFolder","f","filesPerFolder","extractedPerFolder","streamIndex","folderIndex","streamInFolder","folderStreamCount","j","fileInfo","hasStream","unpackSizes","entry","_streamIndex","type","isDirectory","mode","attributes","UNIX_EXTENSION","name","getBaseName","path","mtime","atime","ctime","isAntiFile","_folderIndex","_streamIndexInFolder","_hasStream","getEntries","getEntryStream","emptyStream","end","folder","folders","coders","coder","id","codecName","UNSUPPORTED_CODEC","folderIdx","data","getDecompressedFolder","fileStart","m","prevStreamGlobalIndex","fileSize","outputStream","DECOMPRESSION_FAILED","fileData","decompressedCache","folderHasBcj2","filesInFolder","extractedFromFolder","remainingFiles","shouldCache","decompressBcj2Folder","packStreamIndex","packedStreams","k","packSizes","packedData","data2","l","coderInfo","numPackStreams","packStreams","currentPos","p","coderOutputs","bcj2CoderIndex","c","inputToPackStream","pi","outputToCoder","totalOutputs","co","numOut","numOutStreams","outp","processed","processOrder","getCoderProcessOrder","po","coderIdx","coderInputStart","ci2","numInStreams","inputIdx","packStreamIdx","inputData","outputData","coderOutputStart","co2","bcj2InputStart","ci3","bcj2Inputs","bi","globalIdx","boundOutput","bp2","bindPairs","inIndex","outIndex","psIdx","bcj2OutputStart","co3","bcj2UnpackSize","key","excludeIdx","order","changed","inputStart","canProcess","inp","bp","outIdx","outStart","oc","lastSlash","lastIndexOf","lastBackslash","lastSep"],"mappings":"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"}
@@ -14,8 +14,11 @@ var kTopValue = 1 << 24;
14
14
  var kNumBitModelTotalBits = 11;
15
15
  var kBitModelTotal = 1 << kNumBitModelTotalBits;
16
16
  var kNumMoveBits = 5;
17
- // Number of probability models (256 for each byte value that can precede a branch)
18
- var kNumProbs = 256 + 2;
17
+ // Number of probability models:
18
+ // Index 0: conditional jumps (0x0F 0x80-0x8F)
19
+ // Index 1: JMP (0xE9)
20
+ // Indices 2-257: CALL (0xE8), indexed by previous byte
21
+ var kNumProbs = 258;
19
22
  /**
20
23
  * Initialize range decoder
21
24
  */ function initRangeDecoder(stream) {
@@ -95,8 +98,10 @@ var kNumProbs = 256 + 2;
95
98
  if (b === 0xe8 || b === 0xe9) {
96
99
  // CALL (0xE8) or JMP (0xE9)
97
100
  // Use range decoder to check if this should be processed
98
- var probIndex = prevByte;
101
+ // Probability index: E8 uses 2 + prevByte, E9 uses 1
102
+ var probIndex = b === 0xe8 ? 2 + prevByte : 1;
99
103
  var isMatch = decodeBit(rd, probs, probIndex);
104
+ if (outPos >= outSize) break;
100
105
  output[outPos++] = b;
101
106
  ip++;
102
107
  if (isMatch) {
@@ -106,6 +111,8 @@ var kNumProbs = 256 + 2;
106
111
  if (addrPos + 4 > addrStream.length) {
107
112
  break;
108
113
  }
114
+ // Check if we have room for 4 address bytes
115
+ if (outPos + 4 > outSize) break;
109
116
  // Read as big-endian (BCJ2 stores addresses big-endian)
110
117
  var addr = addrStream[addrPos] << 24 | addrStream[addrPos + 1] << 16 | addrStream[addrPos + 2] << 8 | addrStream[addrPos + 3];
111
118
  if (b === 0xe8) {
@@ -127,14 +134,17 @@ var kNumProbs = 256 + 2;
127
134
  }
128
135
  } else if (b === 0x0f && mainPos < mainStream.length) {
129
136
  // Potential conditional jump (0x0F 0x8x)
137
+ if (outPos >= outSize) break;
130
138
  output[outPos++] = b;
131
139
  ip++;
132
140
  var b2 = mainStream[mainPos];
133
141
  if ((b2 & 0xf0) === 0x80) {
134
142
  // Conditional jump
135
143
  mainPos++;
136
- var probIndex2 = 256 + (b2 >>> 4 & 1);
144
+ // Probability index 0 for conditional jumps (since b2 != 0xE8 and b2 != 0xE9)
145
+ var probIndex2 = 0;
137
146
  var isMatch2 = decodeBit(rd, probs, probIndex2);
147
+ if (outPos >= outSize) break;
138
148
  output[outPos++] = b2;
139
149
  ip++;
140
150
  if (isMatch2) {
@@ -142,6 +152,8 @@ var kNumProbs = 256 + 2;
142
152
  if (jumpPos + 4 > jumpStream.length) {
143
153
  break;
144
154
  }
155
+ // Check if we have room for 4 address bytes
156
+ if (outPos + 4 > outSize) break;
145
157
  var addr2 = jumpStream[jumpPos] << 24 | jumpStream[jumpPos + 1] << 16 | jumpStream[jumpPos + 2] << 8 | jumpStream[jumpPos + 3];
146
158
  jumpPos += 4;
147
159
  // Convert absolute to relative
@@ -161,6 +173,7 @@ var kNumProbs = 256 + 2;
161
173
  }
162
174
  } else {
163
175
  // Regular byte
176
+ if (outPos >= outSize) break;
164
177
  output[outPos++] = b;
165
178
  ip++;
166
179
  prevByte = b;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/codecs/Bcj2.ts"],"sourcesContent":["// BCJ2 (x86-64) filter codec - advanced branch/call/jump converter\n// BCJ2 uses 4 input streams and arithmetic (range) coding for better compression\n// Reference: LZMA SDK Bcj2.c\n//\n// Stream layout:\n// Stream 0: Main data (contains literals and branch opcode markers)\n// Stream 1: CALL addresses (for 0xE8 instructions)\n// Stream 2: JUMP addresses (for 0xE9 instructions)\n// Stream 3: Range coder data (probability decisions)\n\nimport { allocBuffer } from 'extract-base-iterator';\nimport type { Transform } from 'readable-stream';\nimport createBufferingDecoder from './createBufferingDecoder.ts';\n\n// Range coder constants\nvar kTopValue = 1 << 24;\nvar kNumBitModelTotalBits = 11;\nvar kBitModelTotal = 1 << kNumBitModelTotalBits;\nvar kNumMoveBits = 5;\n\n// Number of probability models (256 for each byte value that can precede a branch)\nvar kNumProbs = 256 + 2;\n\n/**\n * Range decoder state\n */\ninterface RangeDecoder {\n range: number;\n code: number;\n stream: Buffer;\n pos: number;\n}\n\n/**\n * Initialize range decoder\n */\nfunction initRangeDecoder(stream: Buffer): RangeDecoder {\n var rd: RangeDecoder = {\n range: 0xffffffff,\n code: 0,\n stream: stream,\n pos: 0,\n };\n\n // Initialize code from first 5 bytes\n for (var i = 0; i < 5; i++) {\n rd.code = (rd.code << 8) | (rd.pos < stream.length ? stream[rd.pos++] : 0);\n }\n\n return rd;\n}\n\n/**\n * Decode a single bit using probability model\n */\nfunction decodeBit(rd: RangeDecoder, prob: number[], probIndex: number): number {\n var ttt = prob[probIndex];\n var bound = (rd.range >>> kNumBitModelTotalBits) * ttt;\n\n var symbol: number;\n if (rd.code >>> 0 < bound >>> 0) {\n rd.range = bound;\n prob[probIndex] = (ttt + ((kBitModelTotal - ttt) >>> kNumMoveBits)) | 0;\n symbol = 0;\n } else {\n rd.range = (rd.range - bound) >>> 0;\n rd.code = (rd.code - bound) >>> 0;\n prob[probIndex] = (ttt - (ttt >>> kNumMoveBits)) | 0;\n symbol = 1;\n }\n\n // Normalize\n if (rd.range < kTopValue) {\n rd.range = (rd.range << 8) >>> 0;\n rd.code = ((rd.code << 8) | (rd.pos < rd.stream.length ? rd.stream[rd.pos++] : 0)) >>> 0;\n }\n\n return symbol;\n}\n\n/**\n * BCJ2 multi-stream decoder\n * Takes 4 pre-decompressed streams and combines them\n */\nexport function decodeBcj2Multi(streams: Buffer[], _properties?: Buffer, unpackSize?: number): Buffer {\n if (streams.length !== 4) {\n throw new Error(`BCJ2 requires 4 input streams, got ${streams.length}`);\n }\n\n // Stream assignment (based on 7z bind pair convention):\n // streams[0] = main data (after LZMA2)\n // streams[1] = call stream (after LZMA)\n // streams[2] = jump stream (after LZMA)\n // streams[3] = range coder stream (uncompressed)\n var mainStream = streams[0];\n var callStream = streams[1];\n var jumpStream = streams[2];\n var rcStream = streams[3];\n\n // Output buffer\n var outSize = unpackSize || mainStream.length + callStream.length + jumpStream.length;\n var output = allocBuffer(outSize);\n var outPos = 0;\n\n // Stream positions\n var mainPos = 0;\n var callPos = 0;\n var jumpPos = 0;\n\n // Initialize range decoder\n var rd = initRangeDecoder(rcStream);\n\n // Initialize probability models\n var probs: number[] = [];\n for (var i = 0; i < kNumProbs; i++) {\n probs.push(kBitModelTotal >>> 1);\n }\n\n // Track previous byte for probability context\n var prevByte = 0;\n\n // Instruction pointer for address conversion\n var ip = 0;\n\n while (outPos < outSize && mainPos < mainStream.length) {\n var b = mainStream[mainPos++];\n\n // Check for branch opcodes\n if (b === 0xe8 || b === 0xe9) {\n // CALL (0xE8) or JMP (0xE9)\n // Use range decoder to check if this should be processed\n var probIndex = prevByte;\n var isMatch = decodeBit(rd, probs, probIndex);\n\n output[outPos++] = b;\n ip++;\n\n if (isMatch) {\n // Read 4-byte address from appropriate stream\n var addrStream = b === 0xe8 ? callStream : jumpStream;\n var addrPos = b === 0xe8 ? callPos : jumpPos;\n\n if (addrPos + 4 > addrStream.length) {\n // Not enough data, copy remaining\n break;\n }\n\n // Read as big-endian (BCJ2 stores addresses big-endian)\n var addr = (addrStream[addrPos] << 24) | (addrStream[addrPos + 1] << 16) | (addrStream[addrPos + 2] << 8) | addrStream[addrPos + 3];\n\n if (b === 0xe8) {\n callPos += 4;\n } else {\n jumpPos += 4;\n }\n\n // Convert absolute to relative address\n addr = (addr - (ip + 4)) | 0;\n\n // Write as little-endian\n output[outPos++] = addr & 0xff;\n output[outPos++] = (addr >>> 8) & 0xff;\n output[outPos++] = (addr >>> 16) & 0xff;\n output[outPos++] = (addr >>> 24) & 0xff;\n ip += 4;\n\n prevByte = (addr >>> 24) & 0xff;\n } else {\n prevByte = b;\n }\n } else if (b === 0x0f && mainPos < mainStream.length) {\n // Potential conditional jump (0x0F 0x8x)\n output[outPos++] = b;\n ip++;\n\n var b2 = mainStream[mainPos];\n if ((b2 & 0xf0) === 0x80) {\n // Conditional jump\n mainPos++;\n var probIndex2 = 256 + ((b2 >>> 4) & 1);\n var isMatch2 = decodeBit(rd, probs, probIndex2);\n\n output[outPos++] = b2;\n ip++;\n\n if (isMatch2) {\n // Read 4-byte address from jump stream\n if (jumpPos + 4 > jumpStream.length) {\n break;\n }\n\n var addr2 = (jumpStream[jumpPos] << 24) | (jumpStream[jumpPos + 1] << 16) | (jumpStream[jumpPos + 2] << 8) | jumpStream[jumpPos + 3];\n jumpPos += 4;\n\n // Convert absolute to relative\n addr2 = (addr2 - (ip + 4)) | 0;\n\n // Write as little-endian\n output[outPos++] = addr2 & 0xff;\n output[outPos++] = (addr2 >>> 8) & 0xff;\n output[outPos++] = (addr2 >>> 16) & 0xff;\n output[outPos++] = (addr2 >>> 24) & 0xff;\n ip += 4;\n\n prevByte = (addr2 >>> 24) & 0xff;\n } else {\n prevByte = b2;\n }\n } else {\n prevByte = b;\n }\n } else {\n // Regular byte\n output[outPos++] = b;\n ip++;\n prevByte = b;\n }\n }\n\n // Return only the used portion\n return outPos < output.length ? output.slice(0, outPos) : output;\n}\n\n/**\n * Single-buffer decode (for API compatibility)\n * Note: BCJ2 requires multi-stream, this throws\n */\nexport function decodeBcj2(_input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer {\n throw new Error('BCJ2 requires multi-stream decoding - use decodeBcj2Multi');\n}\n\n/**\n * Create a BCJ2 decoder Transform stream\n * Note: BCJ2 requires multi-stream, this is for API compatibility\n */\nexport function createBcj2Decoder(_properties?: Buffer, _unpackSize?: number): Transform {\n return createBufferingDecoder(decodeBcj2, _properties, _unpackSize);\n}\n"],"names":["allocBuffer","createBufferingDecoder","kTopValue","kNumBitModelTotalBits","kBitModelTotal","kNumMoveBits","kNumProbs","initRangeDecoder","stream","rd","range","code","pos","i","length","decodeBit","prob","probIndex","ttt","bound","symbol","decodeBcj2Multi","streams","_properties","unpackSize","Error","mainStream","callStream","jumpStream","rcStream","outSize","output","outPos","mainPos","callPos","jumpPos","probs","push","prevByte","ip","b","isMatch","addrStream","addrPos","addr","b2","probIndex2","isMatch2","addr2","slice","decodeBcj2","_input","_unpackSize","createBcj2Decoder"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/codecs/Bcj2.ts"],"sourcesContent":["// BCJ2 (x86-64) filter codec - advanced branch/call/jump converter\n// BCJ2 uses 4 input streams and arithmetic (range) coding for better compression\n// Reference: LZMA SDK Bcj2.c\n//\n// Stream layout:\n// Stream 0: Main data (contains literals and branch opcode markers)\n// Stream 1: CALL addresses (for 0xE8 instructions)\n// Stream 2: JUMP addresses (for 0xE9 instructions)\n// Stream 3: Range coder data (probability decisions)\n\nimport { allocBuffer } from 'extract-base-iterator';\nimport type { Transform } from 'readable-stream';\nimport createBufferingDecoder from './createBufferingDecoder.ts';\n\n// Range coder constants\nvar kTopValue = 1 << 24;\nvar kNumBitModelTotalBits = 11;\nvar kBitModelTotal = 1 << kNumBitModelTotalBits;\nvar kNumMoveBits = 5;\n\n// Number of probability models:\n// Index 0: conditional jumps (0x0F 0x80-0x8F)\n// Index 1: JMP (0xE9)\n// Indices 2-257: CALL (0xE8), indexed by previous byte\nvar kNumProbs = 258;\n\n/**\n * Range decoder state\n */\ninterface RangeDecoder {\n range: number;\n code: number;\n stream: Buffer;\n pos: number;\n}\n\n/**\n * Initialize range decoder\n */\nfunction initRangeDecoder(stream: Buffer): RangeDecoder {\n var rd: RangeDecoder = {\n range: 0xffffffff,\n code: 0,\n stream: stream,\n pos: 0,\n };\n\n // Initialize code from first 5 bytes\n for (var i = 0; i < 5; i++) {\n rd.code = (rd.code << 8) | (rd.pos < stream.length ? stream[rd.pos++] : 0);\n }\n\n return rd;\n}\n\n/**\n * Decode a single bit using probability model\n */\nfunction decodeBit(rd: RangeDecoder, prob: number[], probIndex: number): number {\n var ttt = prob[probIndex];\n var bound = (rd.range >>> kNumBitModelTotalBits) * ttt;\n\n var symbol: number;\n if (rd.code >>> 0 < bound >>> 0) {\n rd.range = bound;\n prob[probIndex] = (ttt + ((kBitModelTotal - ttt) >>> kNumMoveBits)) | 0;\n symbol = 0;\n } else {\n rd.range = (rd.range - bound) >>> 0;\n rd.code = (rd.code - bound) >>> 0;\n prob[probIndex] = (ttt - (ttt >>> kNumMoveBits)) | 0;\n symbol = 1;\n }\n\n // Normalize\n if (rd.range < kTopValue) {\n rd.range = (rd.range << 8) >>> 0;\n rd.code = ((rd.code << 8) | (rd.pos < rd.stream.length ? rd.stream[rd.pos++] : 0)) >>> 0;\n }\n\n return symbol;\n}\n\n/**\n * BCJ2 multi-stream decoder\n * Takes 4 pre-decompressed streams and combines them\n */\nexport function decodeBcj2Multi(streams: Buffer[], _properties?: Buffer, unpackSize?: number): Buffer {\n if (streams.length !== 4) {\n throw new Error(`BCJ2 requires 4 input streams, got ${streams.length}`);\n }\n\n // Stream assignment (based on 7z bind pair convention):\n // streams[0] = main data (after LZMA2)\n // streams[1] = call stream (after LZMA)\n // streams[2] = jump stream (after LZMA)\n // streams[3] = range coder stream (uncompressed)\n var mainStream = streams[0];\n var callStream = streams[1];\n var jumpStream = streams[2];\n var rcStream = streams[3];\n\n // Output buffer\n var outSize = unpackSize || mainStream.length + callStream.length + jumpStream.length;\n var output = allocBuffer(outSize);\n var outPos = 0;\n\n // Stream positions\n var mainPos = 0;\n var callPos = 0;\n var jumpPos = 0;\n\n // Initialize range decoder\n var rd = initRangeDecoder(rcStream);\n\n // Initialize probability models\n var probs: number[] = [];\n for (var i = 0; i < kNumProbs; i++) {\n probs.push(kBitModelTotal >>> 1);\n }\n\n // Track previous byte for probability context\n var prevByte = 0;\n\n // Instruction pointer for address conversion\n var ip = 0;\n\n while (outPos < outSize && mainPos < mainStream.length) {\n var b = mainStream[mainPos++];\n\n // Check for branch opcodes\n if (b === 0xe8 || b === 0xe9) {\n // CALL (0xE8) or JMP (0xE9)\n // Use range decoder to check if this should be processed\n // Probability index: E8 uses 2 + prevByte, E9 uses 1\n var probIndex = b === 0xe8 ? 2 + prevByte : 1;\n var isMatch = decodeBit(rd, probs, probIndex);\n\n if (outPos >= outSize) break;\n output[outPos++] = b;\n ip++;\n\n if (isMatch) {\n // Read 4-byte address from appropriate stream\n var addrStream = b === 0xe8 ? callStream : jumpStream;\n var addrPos = b === 0xe8 ? callPos : jumpPos;\n\n if (addrPos + 4 > addrStream.length) {\n // Not enough data, copy remaining\n break;\n }\n\n // Check if we have room for 4 address bytes\n if (outPos + 4 > outSize) break;\n\n // Read as big-endian (BCJ2 stores addresses big-endian)\n var addr = (addrStream[addrPos] << 24) | (addrStream[addrPos + 1] << 16) | (addrStream[addrPos + 2] << 8) | addrStream[addrPos + 3];\n\n if (b === 0xe8) {\n callPos += 4;\n } else {\n jumpPos += 4;\n }\n\n // Convert absolute to relative address\n addr = (addr - (ip + 4)) | 0;\n\n // Write as little-endian\n output[outPos++] = addr & 0xff;\n output[outPos++] = (addr >>> 8) & 0xff;\n output[outPos++] = (addr >>> 16) & 0xff;\n output[outPos++] = (addr >>> 24) & 0xff;\n ip += 4;\n\n prevByte = (addr >>> 24) & 0xff;\n } else {\n prevByte = b;\n }\n } else if (b === 0x0f && mainPos < mainStream.length) {\n // Potential conditional jump (0x0F 0x8x)\n if (outPos >= outSize) break;\n output[outPos++] = b;\n ip++;\n\n var b2 = mainStream[mainPos];\n if ((b2 & 0xf0) === 0x80) {\n // Conditional jump\n mainPos++;\n // Probability index 0 for conditional jumps (since b2 != 0xE8 and b2 != 0xE9)\n var probIndex2 = 0;\n var isMatch2 = decodeBit(rd, probs, probIndex2);\n\n if (outPos >= outSize) break;\n output[outPos++] = b2;\n ip++;\n\n if (isMatch2) {\n // Read 4-byte address from jump stream\n if (jumpPos + 4 > jumpStream.length) {\n break;\n }\n\n // Check if we have room for 4 address bytes\n if (outPos + 4 > outSize) break;\n\n var addr2 = (jumpStream[jumpPos] << 24) | (jumpStream[jumpPos + 1] << 16) | (jumpStream[jumpPos + 2] << 8) | jumpStream[jumpPos + 3];\n jumpPos += 4;\n\n // Convert absolute to relative\n addr2 = (addr2 - (ip + 4)) | 0;\n\n // Write as little-endian\n output[outPos++] = addr2 & 0xff;\n output[outPos++] = (addr2 >>> 8) & 0xff;\n output[outPos++] = (addr2 >>> 16) & 0xff;\n output[outPos++] = (addr2 >>> 24) & 0xff;\n ip += 4;\n\n prevByte = (addr2 >>> 24) & 0xff;\n } else {\n prevByte = b2;\n }\n } else {\n prevByte = b;\n }\n } else {\n // Regular byte\n if (outPos >= outSize) break;\n output[outPos++] = b;\n ip++;\n prevByte = b;\n }\n }\n\n // Return only the used portion\n return outPos < output.length ? output.slice(0, outPos) : output;\n}\n\n/**\n * Single-buffer decode (for API compatibility)\n * Note: BCJ2 requires multi-stream, this throws\n */\nexport function decodeBcj2(_input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer {\n throw new Error('BCJ2 requires multi-stream decoding - use decodeBcj2Multi');\n}\n\n/**\n * Create a BCJ2 decoder Transform stream\n * Note: BCJ2 requires multi-stream, this is for API compatibility\n */\nexport function createBcj2Decoder(_properties?: Buffer, _unpackSize?: number): Transform {\n return createBufferingDecoder(decodeBcj2, _properties, _unpackSize);\n}\n"],"names":["allocBuffer","createBufferingDecoder","kTopValue","kNumBitModelTotalBits","kBitModelTotal","kNumMoveBits","kNumProbs","initRangeDecoder","stream","rd","range","code","pos","i","length","decodeBit","prob","probIndex","ttt","bound","symbol","decodeBcj2Multi","streams","_properties","unpackSize","Error","mainStream","callStream","jumpStream","rcStream","outSize","output","outPos","mainPos","callPos","jumpPos","probs","push","prevByte","ip","b","isMatch","addrStream","addrPos","addr","b2","probIndex2","isMatch2","addr2","slice","decodeBcj2","_input","_unpackSize","createBcj2Decoder"],"mappings":"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"}
@@ -22,9 +22,10 @@ var LzmaDecoder = lzmajs.LZMA.Decoder;
22
22
  throw new Error('Invalid LZMA properties');
23
23
  }
24
24
  var inStream = createInputStream(input, 0, input.length);
25
- var outStream = createOutputStream();
26
25
  // Use -1 for unknown size (decoder will use end marker)
27
26
  var size = typeof unpackSize === 'number' ? unpackSize : -1;
27
+ // Pre-allocate output stream if size is known (memory optimization)
28
+ var outStream = createOutputStream(size > 0 ? size : undefined);
28
29
  var success = decoder.code(inStream, outStream, size);
29
30
  if (!success) {
30
31
  throw new Error('LZMA decompression failed');
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/codecs/Lzma.ts"],"sourcesContent":["// LZMA codec - uses lzma-purejs for raw LZMA decompression\n// LZMA properties in 7z are 5 bytes: 1 byte lc/lp/pb + 4 bytes dictionary size (little-endian)\n\n// Import lzma-purejs - provides raw LZMA decoder\nimport lzmajs from 'lzma-purejs';\nimport type { Transform } from 'readable-stream';\nimport createBufferingDecoder from './createBufferingDecoder.ts';\nimport { createInputStream, createOutputStream } from './streams.ts';\n\nvar LzmaDecoder = lzmajs.LZMA.Decoder;\n\n/**\n * Decode LZMA compressed data to buffer\n *\n * @param input - LZMA compressed data\n * @param properties - Properties buffer (5 bytes: lc/lp/pb + dict size)\n * @param unpackSize - Expected output size (optional, -1 for unknown)\n * @returns Decompressed data\n */\nexport function decodeLzma(input: Buffer, properties?: Buffer, unpackSize?: number): Buffer {\n if (!properties || properties.length < 5) {\n throw new Error('LZMA requires 5-byte properties');\n }\n\n var decoder = new LzmaDecoder();\n\n // setDecoderProperties expects array-like with 5 bytes\n if (!decoder.setDecoderProperties(properties)) {\n throw new Error('Invalid LZMA properties');\n }\n\n var inStream = createInputStream(input, 0, input.length);\n var outStream = createOutputStream();\n\n // Use -1 for unknown size (decoder will use end marker)\n var size = typeof unpackSize === 'number' ? unpackSize : -1;\n\n var success = decoder.code(inStream, outStream, size);\n if (!success) {\n throw new Error('LZMA decompression failed');\n }\n\n return outStream.toBuffer();\n}\n\n/**\n * Create an LZMA decoder Transform stream\n */\nexport function createLzmaDecoder(properties?: Buffer, unpackSize?: number): Transform {\n return createBufferingDecoder(decodeLzma, properties, unpackSize);\n}\n"],"names":["lzmajs","createBufferingDecoder","createInputStream","createOutputStream","LzmaDecoder","LZMA","Decoder","decodeLzma","input","properties","unpackSize","length","Error","decoder","setDecoderProperties","inStream","outStream","size","success","code","toBuffer","createLzmaDecoder"],"mappings":"AAAA,2DAA2D;AAC3D,+FAA+F;AAE/F,iDAAiD;AACjD,OAAOA,YAAY,cAAc;AAEjC,OAAOC,4BAA4B,8BAA8B;AACjE,SAASC,iBAAiB,EAAEC,kBAAkB,QAAQ,eAAe;AAErE,IAAIC,cAAcJ,OAAOK,IAAI,CAACC,OAAO;AAErC;;;;;;;CAOC,GACD,OAAO,SAASC,WAAWC,KAAa,EAAEC,UAAmB,EAAEC,UAAmB;IAChF,IAAI,CAACD,cAAcA,WAAWE,MAAM,GAAG,GAAG;QACxC,MAAM,IAAIC,MAAM;IAClB;IAEA,IAAIC,UAAU,IAAIT;IAElB,uDAAuD;IACvD,IAAI,CAACS,QAAQC,oBAAoB,CAACL,aAAa;QAC7C,MAAM,IAAIG,MAAM;IAClB;IAEA,IAAIG,WAAWb,kBAAkBM,OAAO,GAAGA,MAAMG,MAAM;IACvD,IAAIK,YAAYb;IAEhB,wDAAwD;IACxD,IAAIc,OAAO,OAAOP,eAAe,WAAWA,aAAa,CAAC;IAE1D,IAAIQ,UAAUL,QAAQM,IAAI,CAACJ,UAAUC,WAAWC;IAChD,IAAI,CAACC,SAAS;QACZ,MAAM,IAAIN,MAAM;IAClB;IAEA,OAAOI,UAAUI,QAAQ;AAC3B;AAEA;;CAEC,GACD,OAAO,SAASC,kBAAkBZ,UAAmB,EAAEC,UAAmB;IACxE,OAAOT,uBAAuBM,YAAYE,YAAYC;AACxD"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/codecs/Lzma.ts"],"sourcesContent":["// LZMA codec - uses lzma-purejs for raw LZMA decompression\n// LZMA properties in 7z are 5 bytes: 1 byte lc/lp/pb + 4 bytes dictionary size (little-endian)\n\n// Import lzma-purejs - provides raw LZMA decoder\nimport lzmajs from 'lzma-purejs';\nimport type { Transform } from 'readable-stream';\nimport createBufferingDecoder from './createBufferingDecoder.ts';\nimport { createInputStream, createOutputStream } from './streams.ts';\n\nvar LzmaDecoder = lzmajs.LZMA.Decoder;\n\n/**\n * Decode LZMA compressed data to buffer\n *\n * @param input - LZMA compressed data\n * @param properties - Properties buffer (5 bytes: lc/lp/pb + dict size)\n * @param unpackSize - Expected output size (optional, -1 for unknown)\n * @returns Decompressed data\n */\nexport function decodeLzma(input: Buffer, properties?: Buffer, unpackSize?: number): Buffer {\n if (!properties || properties.length < 5) {\n throw new Error('LZMA requires 5-byte properties');\n }\n\n var decoder = new LzmaDecoder();\n\n // setDecoderProperties expects array-like with 5 bytes\n if (!decoder.setDecoderProperties(properties)) {\n throw new Error('Invalid LZMA properties');\n }\n\n var inStream = createInputStream(input, 0, input.length);\n\n // Use -1 for unknown size (decoder will use end marker)\n var size = typeof unpackSize === 'number' ? unpackSize : -1;\n\n // Pre-allocate output stream if size is known (memory optimization)\n var outStream = createOutputStream(size > 0 ? size : undefined);\n\n var success = decoder.code(inStream, outStream, size);\n if (!success) {\n throw new Error('LZMA decompression failed');\n }\n\n return outStream.toBuffer();\n}\n\n/**\n * Create an LZMA decoder Transform stream\n */\nexport function createLzmaDecoder(properties?: Buffer, unpackSize?: number): Transform {\n return createBufferingDecoder(decodeLzma, properties, unpackSize);\n}\n"],"names":["lzmajs","createBufferingDecoder","createInputStream","createOutputStream","LzmaDecoder","LZMA","Decoder","decodeLzma","input","properties","unpackSize","length","Error","decoder","setDecoderProperties","inStream","size","outStream","undefined","success","code","toBuffer","createLzmaDecoder"],"mappings":"AAAA,2DAA2D;AAC3D,+FAA+F;AAE/F,iDAAiD;AACjD,OAAOA,YAAY,cAAc;AAEjC,OAAOC,4BAA4B,8BAA8B;AACjE,SAASC,iBAAiB,EAAEC,kBAAkB,QAAQ,eAAe;AAErE,IAAIC,cAAcJ,OAAOK,IAAI,CAACC,OAAO;AAErC;;;;;;;CAOC,GACD,OAAO,SAASC,WAAWC,KAAa,EAAEC,UAAmB,EAAEC,UAAmB;IAChF,IAAI,CAACD,cAAcA,WAAWE,MAAM,GAAG,GAAG;QACxC,MAAM,IAAIC,MAAM;IAClB;IAEA,IAAIC,UAAU,IAAIT;IAElB,uDAAuD;IACvD,IAAI,CAACS,QAAQC,oBAAoB,CAACL,aAAa;QAC7C,MAAM,IAAIG,MAAM;IAClB;IAEA,IAAIG,WAAWb,kBAAkBM,OAAO,GAAGA,MAAMG,MAAM;IAEvD,wDAAwD;IACxD,IAAIK,OAAO,OAAON,eAAe,WAAWA,aAAa,CAAC;IAE1D,oEAAoE;IACpE,IAAIO,YAAYd,mBAAmBa,OAAO,IAAIA,OAAOE;IAErD,IAAIC,UAAUN,QAAQO,IAAI,CAACL,UAAUE,WAAWD;IAChD,IAAI,CAACG,SAAS;QACZ,MAAM,IAAIP,MAAM;IAClB;IAEA,OAAOK,UAAUI,QAAQ;AAC3B;AAEA;;CAEC,GACD,OAAO,SAASC,kBAAkBb,UAAmB,EAAEC,UAAmB;IACxE,OAAOT,uBAAuBM,YAAYE,YAAYC;AACxD"}
@@ -4,10 +4,10 @@ import type { Transform } from 'readable-stream';
4
4
  *
5
5
  * @param input - LZMA2 compressed data
6
6
  * @param properties - Properties buffer (1 byte: dictionary size)
7
- * @param _unpackSize - Unused (LZMA2 has internal size markers)
7
+ * @param unpackSize - Expected output size (used for pre-allocation to reduce memory)
8
8
  * @returns Decompressed data
9
9
  */
10
- export declare function decodeLzma2(input: Buffer, properties?: Buffer, _unpackSize?: number): Buffer;
10
+ export declare function decodeLzma2(input: Buffer, properties?: Buffer, unpackSize?: number): Buffer;
11
11
  /**
12
12
  * Create an LZMA2 decoder Transform stream
13
13
  */
@@ -14,6 +14,7 @@
14
14
  // The patch adds setSolid(true/false) method to control whether state is preserved
15
15
  // across code() calls.
16
16
  // Import lzma-purejs - provides raw LZMA decoder (patched for LZMA2 support)
17
+ import { allocBufferUnsafe } from 'extract-base-iterator';
17
18
  import lzmajs from 'lzma-purejs';
18
19
  import createBufferingDecoder from './createBufferingDecoder.js';
19
20
  import { createInputStream, createOutputStream } from './streams.js';
@@ -46,14 +47,21 @@ var LzmaDecoder = lzmajs.LZMA.Decoder;
46
47
  *
47
48
  * @param input - LZMA2 compressed data
48
49
  * @param properties - Properties buffer (1 byte: dictionary size)
49
- * @param _unpackSize - Unused (LZMA2 has internal size markers)
50
+ * @param unpackSize - Expected output size (used for pre-allocation to reduce memory)
50
51
  * @returns Decompressed data
51
- */ export function decodeLzma2(input, properties, _unpackSize) {
52
+ */ export function decodeLzma2(input, properties, unpackSize) {
52
53
  if (!properties || properties.length < 1) {
53
54
  throw new Error('LZMA2 requires properties byte');
54
55
  }
55
56
  var dictSize = decodeDictionarySize(properties[0]);
56
- var output = [];
57
+ // Memory optimization: pre-allocate output buffer if size is known
58
+ // This avoids double-memory during Buffer.concat
59
+ var outputBuffer = null;
60
+ var outputPos = 0;
61
+ var outputChunks = [];
62
+ if (unpackSize && unpackSize > 0) {
63
+ outputBuffer = allocBufferUnsafe(unpackSize);
64
+ }
57
65
  var offset = 0;
58
66
  // LZMA decoder instance - reused across chunks
59
67
  // The decoder is patched via patch-package to support setSolid() for LZMA2 state preservation
@@ -91,7 +99,12 @@ var LzmaDecoder = lzmajs.LZMA.Decoder;
91
99
  // Get the uncompressed data
92
100
  var uncompData = input.slice(offset, offset + uncompSize);
93
101
  // Copy uncompressed data to output
94
- output.push(uncompData);
102
+ if (outputBuffer) {
103
+ uncompData.copy(outputBuffer, outputPos);
104
+ outputPos += uncompData.length;
105
+ } else {
106
+ outputChunks === null || outputChunks === void 0 ? void 0 : outputChunks.push(uncompData);
107
+ }
95
108
  // Also update the decoder's internal dictionary so subsequent LZMA chunks can reference it
96
109
  // The decoder needs to track this data for LZ77 back-references
97
110
  // We write directly to _buffer to avoid flush() which requires _stream to be set
@@ -166,7 +179,7 @@ var LzmaDecoder = lzmajs.LZMA.Decoder;
166
179
  }
167
180
  // Decode LZMA chunk
168
181
  var inStream = createInputStream(input, offset, compSize);
169
- var outStream = createOutputStream();
182
+ var outStream = createOutputStream(uncompSize2); // Pre-allocate for memory efficiency
170
183
  // Set solid mode based on control byte - this preserves state across code() calls
171
184
  decoder.setSolid(useSolidMode);
172
185
  // Decode the chunk
@@ -174,13 +187,24 @@ var LzmaDecoder = lzmajs.LZMA.Decoder;
174
187
  if (!success) {
175
188
  throw new Error('LZMA decompression failed');
176
189
  }
177
- output.push(outStream.toBuffer());
190
+ var chunkOutput = outStream.toBuffer();
191
+ if (outputBuffer) {
192
+ chunkOutput.copy(outputBuffer, outputPos);
193
+ outputPos += chunkOutput.length;
194
+ } else {
195
+ outputChunks === null || outputChunks === void 0 ? void 0 : outputChunks.push(chunkOutput);
196
+ }
178
197
  offset += compSize;
179
198
  } else {
180
199
  throw new Error(`Invalid LZMA2 control byte: 0x${control.toString(16)}`);
181
200
  }
182
201
  }
183
- return Buffer.concat(output);
202
+ // Return pre-allocated buffer or concatenated chunks
203
+ if (outputBuffer) {
204
+ // Return only the used portion if we didn't fill the buffer
205
+ return outputPos < outputBuffer.length ? outputBuffer.slice(0, outputPos) : outputBuffer;
206
+ }
207
+ return Buffer.concat(outputChunks);
184
208
  }
185
209
  /**
186
210
  * Create an LZMA2 decoder Transform stream
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/codecs/Lzma2.ts"],"sourcesContent":["// LZMA2 codec - wrapper around lzma-purejs for LZMA2 decompression\n// LZMA2 is a container format that wraps LZMA chunks with framing\n//\n// LZMA2 format specification:\n// https://github.com/ulikunitz/xz/blob/master/doc/LZMA2.md\n//\n// Control byte values:\n// 0x00 = End of stream\n// 0x01 = Uncompressed chunk, dictionary reset\n// 0x02 = Uncompressed chunk, no dictionary reset\n// 0x80-0xFF = LZMA compressed chunk (bits encode reset flags and size)\n//\n// Note: lzma-purejs is patched via patch-package to support LZMA2 state preservation.\n// The patch adds setSolid(true/false) method to control whether state is preserved\n// across code() calls.\n\n// Import lzma-purejs - provides raw LZMA decoder (patched for LZMA2 support)\nimport lzmajs from 'lzma-purejs';\nimport type { Transform } from 'readable-stream';\nimport createBufferingDecoder from './createBufferingDecoder.ts';\nimport { createInputStream, createOutputStream } from './streams.ts';\n\nvar LzmaDecoder = lzmajs.LZMA.Decoder;\n\n/**\n * Decode LZMA2 dictionary size from properties byte\n * Properties byte encodes dictionary size as: 2^(dictByte/2 + 12) or similar\n *\n * Per XZ spec, dictionary sizes are:\n * 0x00 = 4 KiB (2^12)\n * 0x01 = 6 KiB\n * 0x02 = 8 KiB (2^13)\n * ...\n * 0x28 = 1.5 GiB\n */\nfunction decodeDictionarySize(propByte: number): number {\n if (propByte > 40) {\n throw new Error(`Invalid LZMA2 dictionary size property: ${propByte}`);\n }\n if (propByte === 40) {\n // Max dictionary size: 4 GiB - 1\n return 0xffffffff;\n }\n // Dictionary size = 2 | (propByte & 1) << (propByte / 2 + 11)\n var base = 2 | (propByte & 1);\n var shift = Math.floor(propByte / 2) + 11;\n return base << shift;\n}\n\n/**\n * Decode LZMA2 compressed data to buffer\n *\n * @param input - LZMA2 compressed data\n * @param properties - Properties buffer (1 byte: dictionary size)\n * @param _unpackSize - Unused (LZMA2 has internal size markers)\n * @returns Decompressed data\n */\nexport function decodeLzma2(input: Buffer, properties?: Buffer, _unpackSize?: number): Buffer {\n if (!properties || properties.length < 1) {\n throw new Error('LZMA2 requires properties byte');\n }\n\n var dictSize = decodeDictionarySize(properties[0]);\n var output: Buffer[] = [];\n var offset = 0;\n\n // LZMA decoder instance - reused across chunks\n // The decoder is patched via patch-package to support setSolid() for LZMA2 state preservation\n // The decoder also has _nowPos64 which tracks cumulative position for rep0 validation\n // and _prevByte which is used for literal decoder context selection\n var decoder = new LzmaDecoder() as InstanceType<typeof LzmaDecoder> & {\n setSolid: (solid: boolean) => void;\n _nowPos64: number;\n _prevByte: number;\n };\n decoder.setDictionarySize(dictSize);\n\n // Access internal _outWindow for dictionary management\n // We need to preserve dictionary state across LZMA2 chunks\n type OutWindowType = {\n _buffer: Buffer;\n _pos: number;\n _streamPos: number;\n _windowSize: number;\n init: (solid: boolean) => void;\n };\n var outWindow = (decoder as unknown as { _outWindow: OutWindowType })._outWindow;\n\n // Track current LZMA properties (lc, lp, pb)\n var propsSet = false;\n\n while (offset < input.length) {\n var control = input[offset++];\n\n if (control === 0x00) {\n // End of LZMA2 stream\n break;\n }\n\n if (control === 0x01 || control === 0x02) {\n // Uncompressed chunk\n // 0x01 = dictionary reset + uncompressed\n // 0x02 = uncompressed (no reset)\n\n // Handle dictionary reset for 0x01\n if (control === 0x01) {\n outWindow._pos = 0;\n outWindow._streamPos = 0;\n decoder._nowPos64 = 0;\n }\n\n if (offset + 2 > input.length) {\n throw new Error('Truncated LZMA2 uncompressed chunk header');\n }\n\n // Size is big-endian, 16-bit, value + 1\n var uncompSize = ((input[offset] << 8) | input[offset + 1]) + 1;\n offset += 2;\n\n if (offset + uncompSize > input.length) {\n throw new Error('Truncated LZMA2 uncompressed data');\n }\n\n // Get the uncompressed data\n var uncompData = input.slice(offset, offset + uncompSize);\n\n // Copy uncompressed data to output\n output.push(uncompData);\n\n // Also update the decoder's internal dictionary so subsequent LZMA chunks can reference it\n // The decoder needs to track this data for LZ77 back-references\n // We write directly to _buffer to avoid flush() which requires _stream to be set\n // We must also update _streamPos to match _pos so that flush() doesn't try to write\n for (var i = 0; i < uncompData.length; i++) {\n outWindow._buffer[outWindow._pos++] = uncompData[i];\n // Handle circular buffer wrap-around\n if (outWindow._pos >= outWindow._windowSize) {\n outWindow._pos = 0;\n }\n }\n // Keep _streamPos in sync so flush() doesn't try to write these bytes\n // (they're already in our output buffer)\n outWindow._streamPos = outWindow._pos;\n\n // Update decoder's cumulative position so subsequent LZMA chunks have correct rep0 validation\n decoder._nowPos64 += uncompSize;\n\n // Update prevByte for literal decoder context in subsequent LZMA chunks\n decoder._prevByte = uncompData[uncompData.length - 1];\n\n offset += uncompSize;\n } else if (control >= 0x80) {\n // LZMA compressed chunk\n // Control byte format (bits 7-0):\n // Bit 7: always 1 for LZMA chunk\n // Bits 6-5: reset mode (00=nothing, 01=state, 10=state+props, 11=all)\n // Bits 4-0: high 5 bits of uncompressed size - 1\n\n // Control byte ranges (based on bits 6-5):\n // 0x80-0x9F (00): no reset - continue existing state (solid mode)\n // 0xA0-0xBF (01): reset state only\n // 0xC0-0xDF (10): reset state + new properties\n // 0xE0-0xFF (11): reset dictionary + state + new properties\n var resetState = control >= 0xa0;\n var newProps = control >= 0xc0;\n var dictReset = control >= 0xe0;\n var useSolidMode = !resetState;\n\n // Handle dictionary reset for control bytes 0xE0-0xFF\n if (dictReset) {\n outWindow._pos = 0;\n outWindow._streamPos = 0;\n }\n\n if (offset + 4 > input.length) {\n throw new Error('Truncated LZMA2 LZMA chunk header');\n }\n\n // Uncompressed size: 5 bits from control + 16 bits from next 2 bytes + 1\n var uncompHigh = control & 0x1f;\n var uncompSize2 = ((uncompHigh << 16) | (input[offset] << 8) | input[offset + 1]) + 1;\n offset += 2;\n\n // Compressed size: 16 bits + 1\n var compSize = ((input[offset] << 8) | input[offset + 1]) + 1;\n offset += 2;\n\n // If new properties, read 1-byte LZMA properties\n if (newProps) {\n if (offset >= input.length) {\n throw new Error('Truncated LZMA2 properties byte');\n }\n var propsByte = input[offset++];\n\n // Properties byte: pb * 45 + lp * 9 + lc\n // where pb, lp, lc are LZMA parameters\n var lc = propsByte % 9;\n var remainder = Math.floor(propsByte / 9);\n var lp = remainder % 5;\n var pb = Math.floor(remainder / 5);\n\n if (!decoder.setLcLpPb(lc, lp, pb)) {\n throw new Error(`Invalid LZMA properties: lc=${lc} lp=${lp} pb=${pb}`);\n }\n propsSet = true;\n }\n\n if (!propsSet) {\n throw new Error('LZMA chunk without properties');\n }\n\n if (offset + compSize > input.length) {\n throw new Error('Truncated LZMA2 compressed data');\n }\n\n // Decode LZMA chunk\n var inStream = createInputStream(input, offset, compSize);\n var outStream = createOutputStream();\n\n // Set solid mode based on control byte - this preserves state across code() calls\n decoder.setSolid(useSolidMode);\n\n // Decode the chunk\n var success = decoder.code(inStream, outStream, uncompSize2);\n if (!success) {\n throw new Error('LZMA decompression failed');\n }\n\n output.push(outStream.toBuffer());\n\n offset += compSize;\n } else {\n throw new Error(`Invalid LZMA2 control byte: 0x${control.toString(16)}`);\n }\n }\n\n return Buffer.concat(output);\n}\n\n/**\n * Create an LZMA2 decoder Transform stream\n */\nexport function createLzma2Decoder(properties?: Buffer, unpackSize?: number): Transform {\n return createBufferingDecoder(decodeLzma2, properties, unpackSize);\n}\n"],"names":["lzmajs","createBufferingDecoder","createInputStream","createOutputStream","LzmaDecoder","LZMA","Decoder","decodeDictionarySize","propByte","Error","base","shift","Math","floor","decodeLzma2","input","properties","_unpackSize","length","dictSize","output","offset","decoder","setDictionarySize","outWindow","_outWindow","propsSet","control","_pos","_streamPos","_nowPos64","uncompSize","uncompData","slice","push","i","_buffer","_windowSize","_prevByte","resetState","newProps","dictReset","useSolidMode","uncompHigh","uncompSize2","compSize","propsByte","lc","remainder","lp","pb","setLcLpPb","inStream","outStream","setSolid","success","code","toBuffer","toString","Buffer","concat","createLzma2Decoder","unpackSize"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/codecs/Lzma2.ts"],"sourcesContent":["// LZMA2 codec - wrapper around lzma-purejs for LZMA2 decompression\n// LZMA2 is a container format that wraps LZMA chunks with framing\n//\n// LZMA2 format specification:\n// https://github.com/ulikunitz/xz/blob/master/doc/LZMA2.md\n//\n// Control byte values:\n// 0x00 = End of stream\n// 0x01 = Uncompressed chunk, dictionary reset\n// 0x02 = Uncompressed chunk, no dictionary reset\n// 0x80-0xFF = LZMA compressed chunk (bits encode reset flags and size)\n//\n// Note: lzma-purejs is patched via patch-package to support LZMA2 state preservation.\n// The patch adds setSolid(true/false) method to control whether state is preserved\n// across code() calls.\n\n// Import lzma-purejs - provides raw LZMA decoder (patched for LZMA2 support)\nimport { allocBufferUnsafe } from 'extract-base-iterator';\nimport lzmajs from 'lzma-purejs';\nimport type { Transform } from 'readable-stream';\nimport createBufferingDecoder from './createBufferingDecoder.ts';\nimport { createInputStream, createOutputStream } from './streams.ts';\n\nvar LzmaDecoder = lzmajs.LZMA.Decoder;\n\n/**\n * Decode LZMA2 dictionary size from properties byte\n * Properties byte encodes dictionary size as: 2^(dictByte/2 + 12) or similar\n *\n * Per XZ spec, dictionary sizes are:\n * 0x00 = 4 KiB (2^12)\n * 0x01 = 6 KiB\n * 0x02 = 8 KiB (2^13)\n * ...\n * 0x28 = 1.5 GiB\n */\nfunction decodeDictionarySize(propByte: number): number {\n if (propByte > 40) {\n throw new Error(`Invalid LZMA2 dictionary size property: ${propByte}`);\n }\n if (propByte === 40) {\n // Max dictionary size: 4 GiB - 1\n return 0xffffffff;\n }\n // Dictionary size = 2 | (propByte & 1) << (propByte / 2 + 11)\n var base = 2 | (propByte & 1);\n var shift = Math.floor(propByte / 2) + 11;\n return base << shift;\n}\n\n/**\n * Decode LZMA2 compressed data to buffer\n *\n * @param input - LZMA2 compressed data\n * @param properties - Properties buffer (1 byte: dictionary size)\n * @param unpackSize - Expected output size (used for pre-allocation to reduce memory)\n * @returns Decompressed data\n */\nexport function decodeLzma2(input: Buffer, properties?: Buffer, unpackSize?: number): Buffer {\n if (!properties || properties.length < 1) {\n throw new Error('LZMA2 requires properties byte');\n }\n\n var dictSize = decodeDictionarySize(properties[0]);\n\n // Memory optimization: pre-allocate output buffer if size is known\n // This avoids double-memory during Buffer.concat\n var outputBuffer: Buffer | null = null;\n var outputPos = 0;\n var outputChunks: Buffer[] = [];\n\n if (unpackSize && unpackSize > 0) {\n outputBuffer = allocBufferUnsafe(unpackSize);\n }\n\n var offset = 0;\n\n // LZMA decoder instance - reused across chunks\n // The decoder is patched via patch-package to support setSolid() for LZMA2 state preservation\n // The decoder also has _nowPos64 which tracks cumulative position for rep0 validation\n // and _prevByte which is used for literal decoder context selection\n var decoder = new LzmaDecoder() as InstanceType<typeof LzmaDecoder> & {\n setSolid: (solid: boolean) => void;\n _nowPos64: number;\n _prevByte: number;\n };\n decoder.setDictionarySize(dictSize);\n\n // Access internal _outWindow for dictionary management\n // We need to preserve dictionary state across LZMA2 chunks\n type OutWindowType = {\n _buffer: Buffer;\n _pos: number;\n _streamPos: number;\n _windowSize: number;\n init: (solid: boolean) => void;\n };\n var outWindow = (decoder as unknown as { _outWindow: OutWindowType })._outWindow;\n\n // Track current LZMA properties (lc, lp, pb)\n var propsSet = false;\n\n while (offset < input.length) {\n var control = input[offset++];\n\n if (control === 0x00) {\n // End of LZMA2 stream\n break;\n }\n\n if (control === 0x01 || control === 0x02) {\n // Uncompressed chunk\n // 0x01 = dictionary reset + uncompressed\n // 0x02 = uncompressed (no reset)\n\n // Handle dictionary reset for 0x01\n if (control === 0x01) {\n outWindow._pos = 0;\n outWindow._streamPos = 0;\n decoder._nowPos64 = 0;\n }\n\n if (offset + 2 > input.length) {\n throw new Error('Truncated LZMA2 uncompressed chunk header');\n }\n\n // Size is big-endian, 16-bit, value + 1\n var uncompSize = ((input[offset] << 8) | input[offset + 1]) + 1;\n offset += 2;\n\n if (offset + uncompSize > input.length) {\n throw new Error('Truncated LZMA2 uncompressed data');\n }\n\n // Get the uncompressed data\n var uncompData = input.slice(offset, offset + uncompSize);\n\n // Copy uncompressed data to output\n if (outputBuffer) {\n uncompData.copy(outputBuffer, outputPos);\n outputPos += uncompData.length;\n } else {\n outputChunks?.push(uncompData);\n }\n\n // Also update the decoder's internal dictionary so subsequent LZMA chunks can reference it\n // The decoder needs to track this data for LZ77 back-references\n // We write directly to _buffer to avoid flush() which requires _stream to be set\n // We must also update _streamPos to match _pos so that flush() doesn't try to write\n for (var i = 0; i < uncompData.length; i++) {\n outWindow._buffer[outWindow._pos++] = uncompData[i];\n // Handle circular buffer wrap-around\n if (outWindow._pos >= outWindow._windowSize) {\n outWindow._pos = 0;\n }\n }\n // Keep _streamPos in sync so flush() doesn't try to write these bytes\n // (they're already in our output buffer)\n outWindow._streamPos = outWindow._pos;\n\n // Update decoder's cumulative position so subsequent LZMA chunks have correct rep0 validation\n decoder._nowPos64 += uncompSize;\n\n // Update prevByte for literal decoder context in subsequent LZMA chunks\n decoder._prevByte = uncompData[uncompData.length - 1];\n\n offset += uncompSize;\n } else if (control >= 0x80) {\n // LZMA compressed chunk\n // Control byte format (bits 7-0):\n // Bit 7: always 1 for LZMA chunk\n // Bits 6-5: reset mode (00=nothing, 01=state, 10=state+props, 11=all)\n // Bits 4-0: high 5 bits of uncompressed size - 1\n\n // Control byte ranges (based on bits 6-5):\n // 0x80-0x9F (00): no reset - continue existing state (solid mode)\n // 0xA0-0xBF (01): reset state only\n // 0xC0-0xDF (10): reset state + new properties\n // 0xE0-0xFF (11): reset dictionary + state + new properties\n var resetState = control >= 0xa0;\n var newProps = control >= 0xc0;\n var dictReset = control >= 0xe0;\n var useSolidMode = !resetState;\n\n // Handle dictionary reset for control bytes 0xE0-0xFF\n if (dictReset) {\n outWindow._pos = 0;\n outWindow._streamPos = 0;\n }\n\n if (offset + 4 > input.length) {\n throw new Error('Truncated LZMA2 LZMA chunk header');\n }\n\n // Uncompressed size: 5 bits from control + 16 bits from next 2 bytes + 1\n var uncompHigh = control & 0x1f;\n var uncompSize2 = ((uncompHigh << 16) | (input[offset] << 8) | input[offset + 1]) + 1;\n offset += 2;\n\n // Compressed size: 16 bits + 1\n var compSize = ((input[offset] << 8) | input[offset + 1]) + 1;\n offset += 2;\n\n // If new properties, read 1-byte LZMA properties\n if (newProps) {\n if (offset >= input.length) {\n throw new Error('Truncated LZMA2 properties byte');\n }\n var propsByte = input[offset++];\n\n // Properties byte: pb * 45 + lp * 9 + lc\n // where pb, lp, lc are LZMA parameters\n var lc = propsByte % 9;\n var remainder = Math.floor(propsByte / 9);\n var lp = remainder % 5;\n var pb = Math.floor(remainder / 5);\n\n if (!decoder.setLcLpPb(lc, lp, pb)) {\n throw new Error(`Invalid LZMA properties: lc=${lc} lp=${lp} pb=${pb}`);\n }\n propsSet = true;\n }\n\n if (!propsSet) {\n throw new Error('LZMA chunk without properties');\n }\n\n if (offset + compSize > input.length) {\n throw new Error('Truncated LZMA2 compressed data');\n }\n\n // Decode LZMA chunk\n var inStream = createInputStream(input, offset, compSize);\n var outStream = createOutputStream(uncompSize2); // Pre-allocate for memory efficiency\n\n // Set solid mode based on control byte - this preserves state across code() calls\n decoder.setSolid(useSolidMode);\n\n // Decode the chunk\n var success = decoder.code(inStream, outStream, uncompSize2);\n if (!success) {\n throw new Error('LZMA decompression failed');\n }\n\n var chunkOutput = outStream.toBuffer();\n if (outputBuffer) {\n chunkOutput.copy(outputBuffer, outputPos);\n outputPos += chunkOutput.length;\n } else {\n outputChunks?.push(chunkOutput);\n }\n\n offset += compSize;\n } else {\n throw new Error(`Invalid LZMA2 control byte: 0x${control.toString(16)}`);\n }\n }\n\n // Return pre-allocated buffer or concatenated chunks\n if (outputBuffer) {\n // Return only the used portion if we didn't fill the buffer\n return outputPos < outputBuffer.length ? outputBuffer.slice(0, outputPos) : outputBuffer;\n }\n return Buffer.concat(outputChunks);\n}\n\n/**\n * Create an LZMA2 decoder Transform stream\n */\nexport function createLzma2Decoder(properties?: Buffer, unpackSize?: number): Transform {\n return createBufferingDecoder(decodeLzma2, properties, unpackSize);\n}\n"],"names":["allocBufferUnsafe","lzmajs","createBufferingDecoder","createInputStream","createOutputStream","LzmaDecoder","LZMA","Decoder","decodeDictionarySize","propByte","Error","base","shift","Math","floor","decodeLzma2","input","properties","unpackSize","length","dictSize","outputBuffer","outputPos","outputChunks","offset","decoder","setDictionarySize","outWindow","_outWindow","propsSet","control","_pos","_streamPos","_nowPos64","uncompSize","uncompData","slice","copy","push","i","_buffer","_windowSize","_prevByte","resetState","newProps","dictReset","useSolidMode","uncompHigh","uncompSize2","compSize","propsByte","lc","remainder","lp","pb","setLcLpPb","inStream","outStream","setSolid","success","code","chunkOutput","toBuffer","toString","Buffer","concat","createLzma2Decoder"],"mappings":"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"}
@@ -9,8 +9,14 @@ export declare function createInputStream(buffer: Buffer, offset: number, length
9
9
  /**
10
10
  * Output stream wrapper for lzma-purejs
11
11
  * Collects output bytes into Buffer chunks
12
+ * Uses typed arrays for memory efficiency (1 byte per element instead of 8)
13
+ *
14
+ * Memory optimization: If expectedSize is provided, pre-allocates a single buffer
15
+ * to avoid double-memory during Buffer.concat.
16
+ *
17
+ * @param expectedSize - Optional expected output size for pre-allocation
12
18
  */
13
- export declare function createOutputStream(): {
19
+ export declare function createOutputStream(expectedSize?: number): {
14
20
  writeByte: (b: number) => void;
15
21
  write: (buf: number[], bufOffset: number, len: number) => number;
16
22
  flush: () => void;