7z-iterator 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/lzma-purejs/LICENSE +11 -0
- package/assets/lzma-purejs/index.js +19 -0
- package/assets/lzma-purejs/lib/LZ/OutWindow.js +78 -0
- package/assets/lzma-purejs/lib/LZ.js +6 -0
- package/assets/lzma-purejs/lib/LZMA/Base.js +48 -0
- package/assets/lzma-purejs/lib/LZMA/Decoder.js +296 -0
- package/assets/lzma-purejs/lib/LZMA.js +6 -0
- package/assets/lzma-purejs/lib/RangeCoder/BitTreeDecoder.js +41 -0
- package/assets/lzma-purejs/lib/RangeCoder/Decoder.js +58 -0
- package/assets/lzma-purejs/lib/RangeCoder/Encoder.js +106 -0
- package/assets/lzma-purejs/lib/RangeCoder.js +10 -0
- package/assets/lzma-purejs/lib/Stream.js +41 -0
- package/assets/lzma-purejs/lib/Util.js +114 -0
- package/assets/lzma-purejs/lib/makeBuffer.js +14 -0
- package/assets/lzma-purejs/package.json +8 -0
- package/dist/cjs/sevenz/SevenZipParser.d.cts +4 -1
- package/dist/cjs/sevenz/SevenZipParser.d.ts +4 -1
- package/dist/cjs/sevenz/SevenZipParser.js +45 -7
- package/dist/cjs/sevenz/SevenZipParser.js.map +1 -1
- package/dist/cjs/sevenz/codecs/Bcj2.js +17 -4
- package/dist/cjs/sevenz/codecs/Bcj2.js.map +1 -1
- package/dist/cjs/sevenz/codecs/Lzma.js +8 -6
- package/dist/cjs/sevenz/codecs/Lzma.js.map +1 -1
- package/dist/cjs/sevenz/codecs/Lzma2.d.cts +2 -2
- package/dist/cjs/sevenz/codecs/Lzma2.d.ts +2 -2
- package/dist/cjs/sevenz/codecs/Lzma2.js +37 -25
- package/dist/cjs/sevenz/codecs/Lzma2.js.map +1 -1
- package/dist/cjs/sevenz/codecs/streams.d.cts +7 -1
- package/dist/cjs/sevenz/codecs/streams.d.ts +7 -1
- package/dist/cjs/sevenz/codecs/streams.js +47 -17
- package/dist/cjs/sevenz/codecs/streams.js.map +1 -1
- package/dist/cjs/sevenz/constants.d.cts +1 -0
- package/dist/cjs/sevenz/constants.d.ts +1 -0
- package/dist/cjs/sevenz/constants.js +2 -1
- package/dist/cjs/sevenz/constants.js.map +1 -1
- package/dist/esm/sevenz/SevenZipParser.d.ts +4 -1
- package/dist/esm/sevenz/SevenZipParser.js +45 -7
- package/dist/esm/sevenz/SevenZipParser.js.map +1 -1
- package/dist/esm/sevenz/codecs/Bcj2.js +17 -4
- package/dist/esm/sevenz/codecs/Bcj2.js.map +1 -1
- package/dist/esm/sevenz/codecs/Lzma.js +8 -6
- package/dist/esm/sevenz/codecs/Lzma.js.map +1 -1
- package/dist/esm/sevenz/codecs/Lzma2.d.ts +2 -2
- package/dist/esm/sevenz/codecs/Lzma2.js +41 -15
- package/dist/esm/sevenz/codecs/Lzma2.js.map +1 -1
- package/dist/esm/sevenz/codecs/streams.d.ts +7 -1
- package/dist/esm/sevenz/codecs/streams.js +53 -17
- package/dist/esm/sevenz/codecs/streams.js.map +1 -1
- package/dist/esm/sevenz/constants.d.ts +1 -0
- package/dist/esm/sevenz/constants.js +2 -1
- package/dist/esm/sevenz/constants.js.map +1 -1
- package/package.json +4 -5
|
@@ -40,8 +40,11 @@ var kTopValue = 1 << 24;
|
|
|
40
40
|
var kNumBitModelTotalBits = 11;
|
|
41
41
|
var kBitModelTotal = 1 << kNumBitModelTotalBits;
|
|
42
42
|
var kNumMoveBits = 5;
|
|
43
|
-
// Number of probability models
|
|
44
|
-
|
|
43
|
+
// Number of probability models:
|
|
44
|
+
// Index 0: conditional jumps (0x0F 0x80-0x8F)
|
|
45
|
+
// Index 1: JMP (0xE9)
|
|
46
|
+
// Indices 2-257: CALL (0xE8), indexed by previous byte
|
|
47
|
+
var kNumProbs = 258;
|
|
45
48
|
/**
|
|
46
49
|
* Initialize range decoder
|
|
47
50
|
*/ function initRangeDecoder(stream) {
|
|
@@ -118,8 +121,10 @@ function decodeBcj2Multi(streams, _properties, unpackSize) {
|
|
|
118
121
|
if (b === 0xe8 || b === 0xe9) {
|
|
119
122
|
// CALL (0xE8) or JMP (0xE9)
|
|
120
123
|
// Use range decoder to check if this should be processed
|
|
121
|
-
|
|
124
|
+
// Probability index: E8 uses 2 + prevByte, E9 uses 1
|
|
125
|
+
var probIndex = b === 0xe8 ? 2 + prevByte : 1;
|
|
122
126
|
var isMatch = decodeBit(rd, probs, probIndex);
|
|
127
|
+
if (outPos >= outSize) break;
|
|
123
128
|
output[outPos++] = b;
|
|
124
129
|
ip++;
|
|
125
130
|
if (isMatch) {
|
|
@@ -129,6 +134,8 @@ function decodeBcj2Multi(streams, _properties, unpackSize) {
|
|
|
129
134
|
if (addrPos + 4 > addrStream.length) {
|
|
130
135
|
break;
|
|
131
136
|
}
|
|
137
|
+
// Check if we have room for 4 address bytes
|
|
138
|
+
if (outPos + 4 > outSize) break;
|
|
132
139
|
// Read as big-endian (BCJ2 stores addresses big-endian)
|
|
133
140
|
var addr = addrStream[addrPos] << 24 | addrStream[addrPos + 1] << 16 | addrStream[addrPos + 2] << 8 | addrStream[addrPos + 3];
|
|
134
141
|
if (b === 0xe8) {
|
|
@@ -150,14 +157,17 @@ function decodeBcj2Multi(streams, _properties, unpackSize) {
|
|
|
150
157
|
}
|
|
151
158
|
} else if (b === 0x0f && mainPos < mainStream.length) {
|
|
152
159
|
// Potential conditional jump (0x0F 0x8x)
|
|
160
|
+
if (outPos >= outSize) break;
|
|
153
161
|
output[outPos++] = b;
|
|
154
162
|
ip++;
|
|
155
163
|
var b2 = mainStream[mainPos];
|
|
156
164
|
if ((b2 & 0xf0) === 0x80) {
|
|
157
165
|
// Conditional jump
|
|
158
166
|
mainPos++;
|
|
159
|
-
|
|
167
|
+
// Probability index 0 for conditional jumps (since b2 != 0xE8 and b2 != 0xE9)
|
|
168
|
+
var probIndex2 = 0;
|
|
160
169
|
var isMatch2 = decodeBit(rd, probs, probIndex2);
|
|
170
|
+
if (outPos >= outSize) break;
|
|
161
171
|
output[outPos++] = b2;
|
|
162
172
|
ip++;
|
|
163
173
|
if (isMatch2) {
|
|
@@ -165,6 +175,8 @@ function decodeBcj2Multi(streams, _properties, unpackSize) {
|
|
|
165
175
|
if (jumpPos + 4 > jumpStream.length) {
|
|
166
176
|
break;
|
|
167
177
|
}
|
|
178
|
+
// Check if we have room for 4 address bytes
|
|
179
|
+
if (outPos + 4 > outSize) break;
|
|
168
180
|
var addr2 = jumpStream[jumpPos] << 24 | jumpStream[jumpPos + 1] << 16 | jumpStream[jumpPos + 2] << 8 | jumpStream[jumpPos + 3];
|
|
169
181
|
jumpPos += 4;
|
|
170
182
|
// Convert absolute to relative
|
|
@@ -184,6 +196,7 @@ function decodeBcj2Multi(streams, _properties, unpackSize) {
|
|
|
184
196
|
}
|
|
185
197
|
} else {
|
|
186
198
|
// Regular byte
|
|
199
|
+
if (outPos >= outSize) break;
|
|
187
200
|
output[outPos++] = b;
|
|
188
201
|
ip++;
|
|
189
202
|
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":["createBcj2Decoder","decodeBcj2","decodeBcj2Multi","kTopValue","kNumBitModelTotalBits","kBitModelTotal","kNumMoveBits","kNumProbs","initRangeDecoder","stream","rd","range","code","pos","i","length","decodeBit","prob","probIndex","ttt","bound","symbol","streams","_properties","unpackSize","Error","mainStream","callStream","jumpStream","rcStream","outSize","output","allocBuffer","outPos","mainPos","callPos","jumpPos","probs","push","prevByte","ip","b","isMatch","addrStream","addrPos","addr","b2","probIndex2","isMatch2","addr2","slice","_input","_unpackSize","createBufferingDecoder"],"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":["createBcj2Decoder","decodeBcj2","decodeBcj2Multi","kTopValue","kNumBitModelTotalBits","kBitModelTotal","kNumMoveBits","kNumProbs","initRangeDecoder","stream","rd","range","code","pos","i","length","decodeBit","prob","probIndex","ttt","bound","symbol","streams","_properties","unpackSize","Error","mainStream","callStream","jumpStream","rcStream","outSize","output","allocBuffer","outPos","mainPos","callPos","jumpPos","probs","push","prevByte","ip","b","isMatch","addrStream","addrPos","addr","b2","probIndex2","isMatch2","addr2","slice","_input","_unpackSize","createBufferingDecoder"],"mappings":"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"}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
// LZMA codec - uses lzma-purejs for raw LZMA decompression
|
|
2
|
-
// LZMA properties in 7z are 5 bytes: 1 byte lc/lp/pb + 4 bytes dictionary size (little-endian)
|
|
3
|
-
// Import lzma-purejs - provides raw LZMA decoder
|
|
4
1
|
"use strict";
|
|
5
2
|
Object.defineProperty(exports, "__esModule", {
|
|
6
3
|
value: true
|
|
@@ -19,7 +16,7 @@ _export(exports, {
|
|
|
19
16
|
return decodeLzma;
|
|
20
17
|
}
|
|
21
18
|
});
|
|
22
|
-
var
|
|
19
|
+
var _module = /*#__PURE__*/ _interop_require_default(require("module"));
|
|
23
20
|
var _createBufferingDecoderts = /*#__PURE__*/ _interop_require_default(require("./createBufferingDecoder.js"));
|
|
24
21
|
var _streamsts = require("./streams.js");
|
|
25
22
|
function _interop_require_default(obj) {
|
|
@@ -27,7 +24,11 @@ function _interop_require_default(obj) {
|
|
|
27
24
|
default: obj
|
|
28
25
|
};
|
|
29
26
|
}
|
|
30
|
-
var
|
|
27
|
+
var _require = typeof require === 'undefined' ? _module.default.createRequire(require("url").pathToFileURL(__filename).toString()) : require;
|
|
28
|
+
// Import vendored lzma-purejs - provides raw LZMA decoder (patched for LZMA2 support)
|
|
29
|
+
// Path accounts for build output in dist/esm/sevenz/codecs/
|
|
30
|
+
var LZMA = _require('../../../../assets/lzma-purejs').LZMA;
|
|
31
|
+
var LzmaDecoder = LZMA.Decoder;
|
|
31
32
|
function decodeLzma(input, properties, unpackSize) {
|
|
32
33
|
if (!properties || properties.length < 5) {
|
|
33
34
|
throw new Error('LZMA requires 5-byte properties');
|
|
@@ -38,9 +39,10 @@ function decodeLzma(input, properties, unpackSize) {
|
|
|
38
39
|
throw new Error('Invalid LZMA properties');
|
|
39
40
|
}
|
|
40
41
|
var inStream = (0, _streamsts.createInputStream)(input, 0, input.length);
|
|
41
|
-
var outStream = (0, _streamsts.createOutputStream)();
|
|
42
42
|
// Use -1 for unknown size (decoder will use end marker)
|
|
43
43
|
var size = typeof unpackSize === 'number' ? unpackSize : -1;
|
|
44
|
+
// Pre-allocate output stream if size is known (memory optimization)
|
|
45
|
+
var outStream = (0, _streamsts.createOutputStream)(size > 0 ? size : undefined);
|
|
44
46
|
var success = decoder.code(inStream, outStream, size);
|
|
45
47
|
if (!success) {
|
|
46
48
|
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\
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/codecs/Lzma.ts"],"sourcesContent":["import Module from 'module';\n\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\n\n// LZMA codec - uses vendored 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\nimport type { Transform } from 'readable-stream';\nimport createBufferingDecoder from './createBufferingDecoder.ts';\nimport { createInputStream, createOutputStream } from './streams.ts';\n\n// Import vendored lzma-purejs - provides raw LZMA decoder (patched for LZMA2 support)\n// Path accounts for build output in dist/esm/sevenz/codecs/\nconst { LZMA } = _require('../../../../assets/lzma-purejs');\nconst LzmaDecoder = 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":["createLzmaDecoder","decodeLzma","_require","require","Module","createRequire","LZMA","LzmaDecoder","Decoder","input","properties","unpackSize","length","Error","decoder","setDecoderProperties","inStream","createInputStream","size","outStream","createOutputStream","undefined","success","code","toBuffer","createBufferingDecoder"],"mappings":";;;;;;;;;;;QAuDgBA;eAAAA;;QA/BAC;eAAAA;;;6DAxBG;+EAQgB;yBACmB;;;;;;AAPtD,IAAMC,WAAW,OAAOC,YAAY,cAAcC,eAAM,CAACC,aAAa,CAAC,uDAAmBF;AAS1F,sFAAsF;AACtF,4DAA4D;AAC5D,IAAM,AAAEG,OAASJ,SAAS,kCAAlBI;AACR,IAAMC,cAAcD,KAAKE,OAAO;AAUzB,SAASP,WAAWQ,KAAa,EAAEC,UAAmB,EAAEC,UAAmB;IAChF,IAAI,CAACD,cAAcA,WAAWE,MAAM,GAAG,GAAG;QACxC,MAAM,IAAIC,MAAM;IAClB;IAEA,IAAIC,UAAU,IAAIP;IAElB,uDAAuD;IACvD,IAAI,CAACO,QAAQC,oBAAoB,CAACL,aAAa;QAC7C,MAAM,IAAIG,MAAM;IAClB;IAEA,IAAIG,WAAWC,IAAAA,4BAAiB,EAACR,OAAO,GAAGA,MAAMG,MAAM;IAEvD,wDAAwD;IACxD,IAAIM,OAAO,OAAOP,eAAe,WAAWA,aAAa,CAAC;IAE1D,oEAAoE;IACpE,IAAIQ,YAAYC,IAAAA,6BAAkB,EAACF,OAAO,IAAIA,OAAOG;IAErD,IAAIC,UAAUR,QAAQS,IAAI,CAACP,UAAUG,WAAWD;IAChD,IAAI,CAACI,SAAS;QACZ,MAAM,IAAIT,MAAM;IAClB;IAEA,OAAOM,UAAUK,QAAQ;AAC3B;AAKO,SAASxB,kBAAkBU,UAAmB,EAAEC,UAAmB;IACxE,OAAOc,IAAAA,iCAAsB,EAACxB,YAAYS,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
|
|
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,
|
|
10
|
+
export declare function decodeLzma2(input: Buffer, properties?: Buffer, unpackSize?: number): Buffer;
|
|
11
11
|
/**
|
|
12
12
|
* Create an LZMA2 decoder Transform stream
|
|
13
13
|
*/
|
|
@@ -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
|
|
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,
|
|
10
|
+
export declare function decodeLzma2(input: Buffer, properties?: Buffer, unpackSize?: number): Buffer;
|
|
11
11
|
/**
|
|
12
12
|
* Create an LZMA2 decoder Transform stream
|
|
13
13
|
*/
|
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
// LZMA2 codec - wrapper around lzma-purejs for LZMA2 decompression
|
|
2
|
-
// LZMA2 is a container format that wraps LZMA chunks with framing
|
|
3
|
-
//
|
|
4
|
-
// LZMA2 format specification:
|
|
5
|
-
// https://github.com/ulikunitz/xz/blob/master/doc/LZMA2.md
|
|
6
|
-
//
|
|
7
|
-
// Control byte values:
|
|
8
|
-
// 0x00 = End of stream
|
|
9
|
-
// 0x01 = Uncompressed chunk, dictionary reset
|
|
10
|
-
// 0x02 = Uncompressed chunk, no dictionary reset
|
|
11
|
-
// 0x80-0xFF = LZMA compressed chunk (bits encode reset flags and size)
|
|
12
|
-
//
|
|
13
|
-
// Note: lzma-purejs is patched via patch-package to support LZMA2 state preservation.
|
|
14
|
-
// The patch adds setSolid(true/false) method to control whether state is preserved
|
|
15
|
-
// across code() calls.
|
|
16
|
-
// Import lzma-purejs - provides raw LZMA decoder (patched for LZMA2 support)
|
|
17
1
|
"use strict";
|
|
18
2
|
Object.defineProperty(exports, "__esModule", {
|
|
19
3
|
value: true
|
|
@@ -32,7 +16,8 @@ _export(exports, {
|
|
|
32
16
|
return decodeLzma2;
|
|
33
17
|
}
|
|
34
18
|
});
|
|
35
|
-
var
|
|
19
|
+
var _module = /*#__PURE__*/ _interop_require_default(require("module"));
|
|
20
|
+
var _extractbaseiterator = require("extract-base-iterator");
|
|
36
21
|
var _createBufferingDecoderts = /*#__PURE__*/ _interop_require_default(require("./createBufferingDecoder.js"));
|
|
37
22
|
var _streamsts = require("./streams.js");
|
|
38
23
|
function _interop_require_default(obj) {
|
|
@@ -40,7 +25,11 @@ function _interop_require_default(obj) {
|
|
|
40
25
|
default: obj
|
|
41
26
|
};
|
|
42
27
|
}
|
|
43
|
-
var
|
|
28
|
+
var _require = typeof require === 'undefined' ? _module.default.createRequire(require("url").pathToFileURL(__filename).toString()) : require;
|
|
29
|
+
// Import vendored lzma-purejs - provides raw LZMA decoder (patched for LZMA2 support)
|
|
30
|
+
// Path accounts for build output in dist/esm/sevenz/codecs/
|
|
31
|
+
var LZMA = _require('../../../../assets/lzma-purejs').LZMA;
|
|
32
|
+
var LzmaDecoder = LZMA.Decoder;
|
|
44
33
|
/**
|
|
45
34
|
* Decode LZMA2 dictionary size from properties byte
|
|
46
35
|
* Properties byte encodes dictionary size as: 2^(dictByte/2 + 12) or similar
|
|
@@ -64,15 +53,22 @@ var LzmaDecoder = _lzmapurejs.default.LZMA.Decoder;
|
|
|
64
53
|
var shift = Math.floor(propByte / 2) + 11;
|
|
65
54
|
return base << shift;
|
|
66
55
|
}
|
|
67
|
-
function decodeLzma2(input, properties,
|
|
56
|
+
function decodeLzma2(input, properties, unpackSize) {
|
|
68
57
|
if (!properties || properties.length < 1) {
|
|
69
58
|
throw new Error('LZMA2 requires properties byte');
|
|
70
59
|
}
|
|
71
60
|
var dictSize = decodeDictionarySize(properties[0]);
|
|
72
|
-
|
|
61
|
+
// Memory optimization: pre-allocate output buffer if size is known
|
|
62
|
+
// This avoids double-memory during Buffer.concat
|
|
63
|
+
var outputBuffer = null;
|
|
64
|
+
var outputPos = 0;
|
|
65
|
+
var outputChunks = [];
|
|
66
|
+
if (unpackSize && unpackSize > 0) {
|
|
67
|
+
outputBuffer = (0, _extractbaseiterator.allocBufferUnsafe)(unpackSize);
|
|
68
|
+
}
|
|
73
69
|
var offset = 0;
|
|
74
70
|
// LZMA decoder instance - reused across chunks
|
|
75
|
-
// The decoder
|
|
71
|
+
// The vendored decoder supports setSolid() for LZMA2 state preservation
|
|
76
72
|
// The decoder also has _nowPos64 which tracks cumulative position for rep0 validation
|
|
77
73
|
// and _prevByte which is used for literal decoder context selection
|
|
78
74
|
var decoder = new LzmaDecoder();
|
|
@@ -107,7 +103,12 @@ function decodeLzma2(input, properties, _unpackSize) {
|
|
|
107
103
|
// Get the uncompressed data
|
|
108
104
|
var uncompData = input.slice(offset, offset + uncompSize);
|
|
109
105
|
// Copy uncompressed data to output
|
|
110
|
-
|
|
106
|
+
if (outputBuffer) {
|
|
107
|
+
uncompData.copy(outputBuffer, outputPos);
|
|
108
|
+
outputPos += uncompData.length;
|
|
109
|
+
} else {
|
|
110
|
+
outputChunks === null || outputChunks === void 0 ? void 0 : outputChunks.push(uncompData);
|
|
111
|
+
}
|
|
111
112
|
// Also update the decoder's internal dictionary so subsequent LZMA chunks can reference it
|
|
112
113
|
// The decoder needs to track this data for LZ77 back-references
|
|
113
114
|
// We write directly to _buffer to avoid flush() which requires _stream to be set
|
|
@@ -182,7 +183,7 @@ function decodeLzma2(input, properties, _unpackSize) {
|
|
|
182
183
|
}
|
|
183
184
|
// Decode LZMA chunk
|
|
184
185
|
var inStream = (0, _streamsts.createInputStream)(input, offset, compSize);
|
|
185
|
-
var outStream = (0, _streamsts.createOutputStream)();
|
|
186
|
+
var outStream = (0, _streamsts.createOutputStream)(uncompSize2); // Pre-allocate for memory efficiency
|
|
186
187
|
// Set solid mode based on control byte - this preserves state across code() calls
|
|
187
188
|
decoder.setSolid(useSolidMode);
|
|
188
189
|
// Decode the chunk
|
|
@@ -190,13 +191,24 @@ function decodeLzma2(input, properties, _unpackSize) {
|
|
|
190
191
|
if (!success) {
|
|
191
192
|
throw new Error('LZMA decompression failed');
|
|
192
193
|
}
|
|
193
|
-
|
|
194
|
+
var chunkOutput = outStream.toBuffer();
|
|
195
|
+
if (outputBuffer) {
|
|
196
|
+
chunkOutput.copy(outputBuffer, outputPos);
|
|
197
|
+
outputPos += chunkOutput.length;
|
|
198
|
+
} else {
|
|
199
|
+
outputChunks === null || outputChunks === void 0 ? void 0 : outputChunks.push(chunkOutput);
|
|
200
|
+
}
|
|
194
201
|
offset += compSize;
|
|
195
202
|
} else {
|
|
196
203
|
throw new Error("Invalid LZMA2 control byte: 0x".concat(control.toString(16)));
|
|
197
204
|
}
|
|
198
205
|
}
|
|
199
|
-
|
|
206
|
+
// Return pre-allocated buffer or concatenated chunks
|
|
207
|
+
if (outputBuffer) {
|
|
208
|
+
// Return only the used portion if we didn't fill the buffer
|
|
209
|
+
return outputPos < outputBuffer.length ? outputBuffer.slice(0, outputPos) : outputBuffer;
|
|
210
|
+
}
|
|
211
|
+
return Buffer.concat(outputChunks);
|
|
200
212
|
}
|
|
201
213
|
function createLzma2Decoder(properties, unpackSize) {
|
|
202
214
|
return (0, _createBufferingDecoderts.default)(decodeLzma2, properties, unpackSize);
|
|
@@ -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":["createLzma2Decoder","decodeLzma2","LzmaDecoder","lzmajs","LZMA","Decoder","decodeDictionarySize","propByte","Error","base","shift","Math","floor","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","createInputStream","outStream","createOutputStream","setSolid","success","code","toBuffer","toString","Buffer","concat","unpackSize","createBufferingDecoder"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/codecs/Lzma2.ts"],"sourcesContent":["import Module from 'module';\n\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\n\n// LZMA2 codec - wrapper around vendored 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: vendored lzma-purejs includes LZMA2 state preservation support.\n// The setSolid(true/false) method controls whether state is preserved across code() calls.\n\nimport { allocBufferUnsafe } from 'extract-base-iterator';\nimport type { Transform } from 'readable-stream';\nimport createBufferingDecoder from './createBufferingDecoder.ts';\nimport { createInputStream, createOutputStream } from './streams.ts';\n\n// Import vendored lzma-purejs - provides raw LZMA decoder (patched for LZMA2 support)\n// Path accounts for build output in dist/esm/sevenz/codecs/\nconst { LZMA } = _require('../../../../assets/lzma-purejs');\nconst LzmaDecoder = 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 vendored decoder supports 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":["createLzma2Decoder","decodeLzma2","_require","require","Module","createRequire","LZMA","LzmaDecoder","Decoder","decodeDictionarySize","propByte","Error","base","shift","Math","floor","input","properties","unpackSize","length","dictSize","outputBuffer","outputPos","outputChunks","allocBufferUnsafe","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","createInputStream","outStream","createOutputStream","setSolid","success","code","chunkOutput","toBuffer","toString","Buffer","concat","createBufferingDecoder"],"mappings":";;;;;;;;;;;QAiRgBA;eAAAA;;QAnNAC;eAAAA;;;6DA9DG;mCAmBe;+EAEC;yBACmB;;;;;;AApBtD,IAAMC,WAAW,OAAOC,YAAY,cAAcC,eAAM,CAACC,aAAa,CAAC,uDAAmBF;AAsB1F,sFAAsF;AACtF,4DAA4D;AAC5D,IAAM,AAAEG,OAASJ,SAAS,kCAAlBI;AACR,IAAMC,cAAcD,KAAKE,OAAO;AAEhC;;;;;;;;;;CAUC,GACD,SAASC,qBAAqBC,QAAgB;IAC5C,IAAIA,WAAW,IAAI;QACjB,MAAM,IAAIC,MAAM,AAAC,2CAAmD,OAATD;IAC7D;IACA,IAAIA,aAAa,IAAI;QACnB,iCAAiC;QACjC,OAAO;IACT;IACA,8DAA8D;IAC9D,IAAIE,OAAO,IAAKF,WAAW;IAC3B,IAAIG,QAAQC,KAAKC,KAAK,CAACL,WAAW,KAAK;IACvC,OAAOE,QAAQC;AACjB;AAUO,SAASZ,YAAYe,KAAa,EAAEC,UAAmB,EAAEC,UAAmB;IACjF,IAAI,CAACD,cAAcA,WAAWE,MAAM,GAAG,GAAG;QACxC,MAAM,IAAIR,MAAM;IAClB;IAEA,IAAIS,WAAWX,qBAAqBQ,UAAU,CAAC,EAAE;IAEjD,mEAAmE;IACnE,iDAAiD;IACjD,IAAII,eAA8B;IAClC,IAAIC,YAAY;IAChB,IAAIC,eAAyB,EAAE;IAE/B,IAAIL,cAAcA,aAAa,GAAG;QAChCG,eAAeG,IAAAA,sCAAiB,EAACN;IACnC;IAEA,IAAIO,SAAS;IAEb,+CAA+C;IAC/C,wEAAwE;IACxE,sFAAsF;IACtF,oEAAoE;IACpE,IAAIC,UAAU,IAAInB;IAKlBmB,QAAQC,iBAAiB,CAACP;IAW1B,IAAIQ,YAAY,AAACF,QAAqDG,UAAU;IAEhF,6CAA6C;IAC7C,IAAIC,WAAW;IAEf,MAAOL,SAAST,MAAMG,MAAM,CAAE;QAC5B,IAAIY,UAAUf,KAAK,CAACS,SAAS;QAE7B,IAAIM,YAAY,MAAM;YAEpB;QACF;QAEA,IAAIA,YAAY,QAAQA,YAAY,MAAM;YACxC,qBAAqB;YACrB,yCAAyC;YACzC,iCAAiC;YAEjC,mCAAmC;YACnC,IAAIA,YAAY,MAAM;gBACpBH,UAAUI,IAAI,GAAG;gBACjBJ,UAAUK,UAAU,GAAG;gBACvBP,QAAQQ,SAAS,GAAG;YACtB;YAEA,IAAIT,SAAS,IAAIT,MAAMG,MAAM,EAAE;gBAC7B,MAAM,IAAIR,MAAM;YAClB;YAEA,wCAAwC;YACxC,IAAIwB,aAAa,AAAC,CAAA,AAACnB,KAAK,CAACS,OAAO,IAAI,IAAKT,KAAK,CAACS,SAAS,EAAE,AAAD,IAAK;YAC9DA,UAAU;YAEV,IAAIA,SAASU,aAAanB,MAAMG,MAAM,EAAE;gBACtC,MAAM,IAAIR,MAAM;YAClB;YAEA,4BAA4B;YAC5B,IAAIyB,aAAapB,MAAMqB,KAAK,CAACZ,QAAQA,SAASU;YAE9C,mCAAmC;YACnC,IAAId,cAAc;gBAChBe,WAAWE,IAAI,CAACjB,cAAcC;gBAC9BA,aAAac,WAAWjB,MAAM;YAChC,OAAO;gBACLI,yBAAAA,mCAAAA,aAAcgB,IAAI,CAACH;YACrB;YAEA,2FAA2F;YAC3F,gEAAgE;YAChE,iFAAiF;YACjF,oFAAoF;YACpF,IAAK,IAAII,IAAI,GAAGA,IAAIJ,WAAWjB,MAAM,EAAEqB,IAAK;gBAC1CZ,UAAUa,OAAO,CAACb,UAAUI,IAAI,GAAG,GAAGI,UAAU,CAACI,EAAE;gBACnD,qCAAqC;gBACrC,IAAIZ,UAAUI,IAAI,IAAIJ,UAAUc,WAAW,EAAE;oBAC3Cd,UAAUI,IAAI,GAAG;gBACnB;YACF;YACA,sEAAsE;YACtE,yCAAyC;YACzCJ,UAAUK,UAAU,GAAGL,UAAUI,IAAI;YAErC,8FAA8F;YAC9FN,QAAQQ,SAAS,IAAIC;YAErB,wEAAwE;YACxET,QAAQiB,SAAS,GAAGP,UAAU,CAACA,WAAWjB,MAAM,GAAG,EAAE;YAErDM,UAAUU;QACZ,OAAO,IAAIJ,WAAW,MAAM;YAC1B,wBAAwB;YACxB,kCAAkC;YAClC,iCAAiC;YACjC,sEAAsE;YACtE,iDAAiD;YAEjD,2CAA2C;YAC3C,kEAAkE;YAClE,mCAAmC;YACnC,+CAA+C;YAC/C,4DAA4D;YAC5D,IAAIa,aAAab,WAAW;YAC5B,IAAIc,WAAWd,WAAW;YAC1B,IAAIe,YAAYf,WAAW;YAC3B,IAAIgB,eAAe,CAACH;YAEpB,sDAAsD;YACtD,IAAIE,WAAW;gBACblB,UAAUI,IAAI,GAAG;gBACjBJ,UAAUK,UAAU,GAAG;YACzB;YAEA,IAAIR,SAAS,IAAIT,MAAMG,MAAM,EAAE;gBAC7B,MAAM,IAAIR,MAAM;YAClB;YAEA,yEAAyE;YACzE,IAAIqC,aAAajB,UAAU;YAC3B,IAAIkB,cAAc,AAAC,CAAA,AAACD,cAAc,KAAOhC,KAAK,CAACS,OAAO,IAAI,IAAKT,KAAK,CAACS,SAAS,EAAE,AAAD,IAAK;YACpFA,UAAU;YAEV,+BAA+B;YAC/B,IAAIyB,WAAW,AAAC,CAAA,AAAClC,KAAK,CAACS,OAAO,IAAI,IAAKT,KAAK,CAACS,SAAS,EAAE,AAAD,IAAK;YAC5DA,UAAU;YAEV,iDAAiD;YACjD,IAAIoB,UAAU;gBACZ,IAAIpB,UAAUT,MAAMG,MAAM,EAAE;oBAC1B,MAAM,IAAIR,MAAM;gBAClB;gBACA,IAAIwC,YAAYnC,KAAK,CAACS,SAAS;gBAE/B,yCAAyC;gBACzC,uCAAuC;gBACvC,IAAI2B,KAAKD,YAAY;gBACrB,IAAIE,YAAYvC,KAAKC,KAAK,CAACoC,YAAY;gBACvC,IAAIG,KAAKD,YAAY;gBACrB,IAAIE,KAAKzC,KAAKC,KAAK,CAACsC,YAAY;gBAEhC,IAAI,CAAC3B,QAAQ8B,SAAS,CAACJ,IAAIE,IAAIC,KAAK;oBAClC,MAAM,IAAI5C,MAAM,AAAC,+BAAuC2C,OAATF,IAAG,QAAeG,OAATD,IAAG,QAAS,OAAHC;gBACnE;gBACAzB,WAAW;YACb;YAEA,IAAI,CAACA,UAAU;gBACb,MAAM,IAAInB,MAAM;YAClB;YAEA,IAAIc,SAASyB,WAAWlC,MAAMG,MAAM,EAAE;gBACpC,MAAM,IAAIR,MAAM;YAClB;YAEA,oBAAoB;YACpB,IAAI8C,WAAWC,IAAAA,4BAAiB,EAAC1C,OAAOS,QAAQyB;YAChD,IAAIS,YAAYC,IAAAA,6BAAkB,EAACX,cAAc,qCAAqC;YAEtF,kFAAkF;YAClFvB,QAAQmC,QAAQ,CAACd;YAEjB,mBAAmB;YACnB,IAAIe,UAAUpC,QAAQqC,IAAI,CAACN,UAAUE,WAAWV;YAChD,IAAI,CAACa,SAAS;gBACZ,MAAM,IAAInD,MAAM;YAClB;YAEA,IAAIqD,cAAcL,UAAUM,QAAQ;YACpC,IAAI5C,cAAc;gBAChB2C,YAAY1B,IAAI,CAACjB,cAAcC;gBAC/BA,aAAa0C,YAAY7C,MAAM;YACjC,OAAO;gBACLI,yBAAAA,mCAAAA,aAAcgB,IAAI,CAACyB;YACrB;YAEAvC,UAAUyB;QACZ,OAAO;YACL,MAAM,IAAIvC,MAAM,AAAC,iCAAqD,OAArBoB,QAAQmC,QAAQ,CAAC;QACpE;IACF;IAEA,qDAAqD;IACrD,IAAI7C,cAAc;QAChB,4DAA4D;QAC5D,OAAOC,YAAYD,aAAaF,MAAM,GAAGE,aAAagB,KAAK,CAAC,GAAGf,aAAaD;IAC9E;IACA,OAAO8C,OAAOC,MAAM,CAAC7C;AACvB;AAKO,SAASvB,mBAAmBiB,UAAmB,EAAEC,UAAmB;IACzE,OAAOmD,IAAAA,iCAAsB,EAACpE,aAAagB,YAAYC;AACzD"}
|
|
@@ -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;
|
|
@@ -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;
|
|
@@ -39,19 +39,47 @@ function createInputStream(buffer, offset, length) {
|
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
function createOutputStream() {
|
|
42
|
+
function createOutputStream(expectedSize) {
|
|
43
|
+
// Pre-allocation mode: single buffer, no concat needed
|
|
44
|
+
// Includes bounds checking for safety on older Node.js versions
|
|
45
|
+
if (expectedSize && expectedSize > 0) {
|
|
46
|
+
var buffer = (0, _extractbaseiterator.allocBufferUnsafe)(expectedSize);
|
|
47
|
+
var bufPos = 0;
|
|
48
|
+
var bufLen = buffer.length;
|
|
49
|
+
return {
|
|
50
|
+
writeByte: function(b) {
|
|
51
|
+
if (bufPos < bufLen) {
|
|
52
|
+
buffer[bufPos++] = b;
|
|
53
|
+
}
|
|
54
|
+
// Silently ignore overflow (should not happen with correct size)
|
|
55
|
+
},
|
|
56
|
+
write: function(buf, bufOffset, len) {
|
|
57
|
+
for(var i = 0; i < len && bufPos < bufLen; i++){
|
|
58
|
+
buffer[bufPos++] = buf[bufOffset + i];
|
|
59
|
+
}
|
|
60
|
+
return len;
|
|
61
|
+
},
|
|
62
|
+
flush: function() {
|
|
63
|
+
// No-op for pre-allocated buffer
|
|
64
|
+
},
|
|
65
|
+
toBuffer: function() {
|
|
66
|
+
// Return only the used portion
|
|
67
|
+
return bufPos < buffer.length ? buffer.slice(0, bufPos) : buffer;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// Chunked mode: accumulate in 64KB chunks (fallback for unknown size)
|
|
43
72
|
var chunks = [];
|
|
44
|
-
var
|
|
45
|
-
var
|
|
73
|
+
var CHUNK_SIZE = 65536; // 64KB chunks for better memory efficiency
|
|
74
|
+
var currentChunk = (0, _extractbaseiterator.allocBufferUnsafe)(CHUNK_SIZE);
|
|
75
|
+
var pos = 0;
|
|
46
76
|
return {
|
|
47
77
|
writeByte: function(b) {
|
|
48
|
-
currentChunk
|
|
49
|
-
if (
|
|
50
|
-
chunks.push(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
currentChunk = [];
|
|
78
|
+
currentChunk[pos++] = b;
|
|
79
|
+
if (pos >= CHUNK_SIZE) {
|
|
80
|
+
chunks.push(currentChunk);
|
|
81
|
+
currentChunk = (0, _extractbaseiterator.allocBufferUnsafe)(CHUNK_SIZE);
|
|
82
|
+
pos = 0;
|
|
55
83
|
}
|
|
56
84
|
},
|
|
57
85
|
write: function write(buf, bufOffset, len) {
|
|
@@ -61,17 +89,19 @@ function createOutputStream() {
|
|
|
61
89
|
return len;
|
|
62
90
|
},
|
|
63
91
|
flush: function() {
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
chunks.push(finalChunk);
|
|
70
|
-
currentChunk = [];
|
|
92
|
+
if (pos > 0) {
|
|
93
|
+
// Only keep the used portion of the current chunk
|
|
94
|
+
chunks.push(currentChunk.slice(0, pos));
|
|
95
|
+
currentChunk = (0, _extractbaseiterator.allocBufferUnsafe)(CHUNK_SIZE);
|
|
96
|
+
pos = 0;
|
|
71
97
|
}
|
|
72
98
|
},
|
|
73
99
|
toBuffer: function toBuffer() {
|
|
74
100
|
this.flush();
|
|
101
|
+
// Optimization: if single chunk, return it directly
|
|
102
|
+
if (chunks.length === 1) {
|
|
103
|
+
return chunks[0];
|
|
104
|
+
}
|
|
75
105
|
return Buffer.concat(chunks);
|
|
76
106
|
}
|
|
77
107
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/codecs/streams.ts"],"sourcesContent":["// Shared stream wrappers for lzma-purejs codec interface\n// These adapters convert between Buffer/lzma-purejs stream interfaces\n\nimport { allocBufferUnsafe } from 'extract-base-iterator';\n\n/**\n * Input stream wrapper for lzma-purejs\n * Wraps a Buffer region as a readable stream interface\n */\nexport function createInputStream(buffer: Buffer, offset: number, length: number) {\n var pos = 0;\n var end = Math.min(offset + length, buffer.length);\n var start = offset;\n\n return {\n readByte: (): number => {\n if (start + pos >= end) return -1;\n return buffer[start + pos++];\n },\n read: (buf: number[], bufOffset: number, len: number): number => {\n var bytesRead = 0;\n while (bytesRead < len && start + pos < end) {\n buf[bufOffset + bytesRead] = buffer[start + pos];\n pos++;\n bytesRead++;\n }\n return bytesRead === 0 ? -1 : bytesRead;\n },\n };\n}\n\n/**\n * Output stream wrapper for lzma-purejs\n * Collects output bytes into Buffer chunks\n */\nexport function createOutputStream() {\n
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/sevenz/codecs/streams.ts"],"sourcesContent":["// Shared stream wrappers for lzma-purejs codec interface\n// These adapters convert between Buffer/lzma-purejs stream interfaces\n\nimport { allocBufferUnsafe } from 'extract-base-iterator';\n\n/**\n * Input stream wrapper for lzma-purejs\n * Wraps a Buffer region as a readable stream interface\n */\nexport function createInputStream(buffer: Buffer, offset: number, length: number) {\n var pos = 0;\n var end = Math.min(offset + length, buffer.length);\n var start = offset;\n\n return {\n readByte: (): number => {\n if (start + pos >= end) return -1;\n return buffer[start + pos++];\n },\n read: (buf: number[], bufOffset: number, len: number): number => {\n var bytesRead = 0;\n while (bytesRead < len && start + pos < end) {\n buf[bufOffset + bytesRead] = buffer[start + pos];\n pos++;\n bytesRead++;\n }\n return bytesRead === 0 ? -1 : bytesRead;\n },\n };\n}\n\n/**\n * Output stream wrapper for lzma-purejs\n * Collects output bytes into Buffer chunks\n * Uses typed arrays for memory efficiency (1 byte per element instead of 8)\n *\n * Memory optimization: If expectedSize is provided, pre-allocates a single buffer\n * to avoid double-memory during Buffer.concat.\n *\n * @param expectedSize - Optional expected output size for pre-allocation\n */\nexport function createOutputStream(expectedSize?: number) {\n // Pre-allocation mode: single buffer, no concat needed\n // Includes bounds checking for safety on older Node.js versions\n if (expectedSize && expectedSize > 0) {\n var buffer = allocBufferUnsafe(expectedSize);\n var bufPos = 0;\n var bufLen = buffer.length;\n\n return {\n writeByte: (b: number): void => {\n if (bufPos < bufLen) {\n buffer[bufPos++] = b;\n }\n // Silently ignore overflow (should not happen with correct size)\n },\n write: (buf: number[], bufOffset: number, len: number): number => {\n for (var i = 0; i < len && bufPos < bufLen; i++) {\n buffer[bufPos++] = buf[bufOffset + i];\n }\n return len;\n },\n flush: (): void => {\n // No-op for pre-allocated buffer\n },\n toBuffer: (): Buffer => {\n // Return only the used portion\n return bufPos < buffer.length ? buffer.slice(0, bufPos) : buffer;\n },\n };\n }\n\n // Chunked mode: accumulate in 64KB chunks (fallback for unknown size)\n var chunks: Buffer[] = [];\n var CHUNK_SIZE = 65536; // 64KB chunks for better memory efficiency\n var currentChunk: Buffer = allocBufferUnsafe(CHUNK_SIZE);\n var pos = 0;\n\n return {\n writeByte: (b: number): void => {\n currentChunk[pos++] = b;\n if (pos >= CHUNK_SIZE) {\n chunks.push(currentChunk);\n currentChunk = allocBufferUnsafe(CHUNK_SIZE);\n pos = 0;\n }\n },\n write: function (buf: number[], bufOffset: number, len: number): number {\n for (var i = 0; i < len; i++) {\n this.writeByte(buf[bufOffset + i]);\n }\n return len;\n },\n flush: (): void => {\n if (pos > 0) {\n // Only keep the used portion of the current chunk\n chunks.push(currentChunk.slice(0, pos));\n currentChunk = allocBufferUnsafe(CHUNK_SIZE);\n pos = 0;\n }\n },\n toBuffer: function (): Buffer {\n this.flush();\n // Optimization: if single chunk, return it directly\n if (chunks.length === 1) {\n return chunks[0];\n }\n return Buffer.concat(chunks);\n },\n };\n}\n"],"names":["createInputStream","createOutputStream","buffer","offset","length","pos","end","Math","min","start","readByte","read","buf","bufOffset","len","bytesRead","expectedSize","allocBufferUnsafe","bufPos","bufLen","writeByte","b","write","i","flush","toBuffer","slice","chunks","CHUNK_SIZE","currentChunk","push","Buffer","concat"],"mappings":"AAAA,yDAAyD;AACzD,sEAAsE;;;;;;;;;;;;QAQtDA;eAAAA;;QAgCAC;eAAAA;;;mCAtCkB;AAM3B,SAASD,kBAAkBE,MAAc,EAAEC,MAAc,EAAEC,MAAc;IAC9E,IAAIC,MAAM;IACV,IAAIC,MAAMC,KAAKC,GAAG,CAACL,SAASC,QAAQF,OAAOE,MAAM;IACjD,IAAIK,QAAQN;IAEZ,OAAO;QACLO,UAAU;YACR,IAAID,QAAQJ,OAAOC,KAAK,OAAO,CAAC;YAChC,OAAOJ,MAAM,CAACO,QAAQJ,MAAM;QAC9B;QACAM,MAAM,SAACC,KAAeC,WAAmBC;YACvC,IAAIC,YAAY;YAChB,MAAOA,YAAYD,OAAOL,QAAQJ,MAAMC,IAAK;gBAC3CM,GAAG,CAACC,YAAYE,UAAU,GAAGb,MAAM,CAACO,QAAQJ,IAAI;gBAChDA;gBACAU;YACF;YACA,OAAOA,cAAc,IAAI,CAAC,IAAIA;QAChC;IACF;AACF;AAYO,SAASd,mBAAmBe,YAAqB;IACtD,uDAAuD;IACvD,gEAAgE;IAChE,IAAIA,gBAAgBA,eAAe,GAAG;QACpC,IAAId,SAASe,IAAAA,sCAAiB,EAACD;QAC/B,IAAIE,SAAS;QACb,IAAIC,SAASjB,OAAOE,MAAM;QAE1B,OAAO;YACLgB,WAAW,SAACC;gBACV,IAAIH,SAASC,QAAQ;oBACnBjB,MAAM,CAACgB,SAAS,GAAGG;gBACrB;YACA,iEAAiE;YACnE;YACAC,OAAO,SAACV,KAAeC,WAAmBC;gBACxC,IAAK,IAAIS,IAAI,GAAGA,IAAIT,OAAOI,SAASC,QAAQI,IAAK;oBAC/CrB,MAAM,CAACgB,SAAS,GAAGN,GAAG,CAACC,YAAYU,EAAE;gBACvC;gBACA,OAAOT;YACT;YACAU,OAAO;YACL,iCAAiC;YACnC;YACAC,UAAU;gBACR,+BAA+B;gBAC/B,OAAOP,SAAShB,OAAOE,MAAM,GAAGF,OAAOwB,KAAK,CAAC,GAAGR,UAAUhB;YAC5D;QACF;IACF;IAEA,sEAAsE;IACtE,IAAIyB,SAAmB,EAAE;IACzB,IAAIC,aAAa,OAAO,2CAA2C;IACnE,IAAIC,eAAuBZ,IAAAA,sCAAiB,EAACW;IAC7C,IAAIvB,MAAM;IAEV,OAAO;QACLe,WAAW,SAACC;YACVQ,YAAY,CAACxB,MAAM,GAAGgB;YACtB,IAAIhB,OAAOuB,YAAY;gBACrBD,OAAOG,IAAI,CAACD;gBACZA,eAAeZ,IAAAA,sCAAiB,EAACW;gBACjCvB,MAAM;YACR;QACF;QACAiB,OAAO,SAAPA,MAAiBV,GAAa,EAAEC,SAAiB,EAAEC,GAAW;YAC5D,IAAK,IAAIS,IAAI,GAAGA,IAAIT,KAAKS,IAAK;gBAC5B,IAAI,CAACH,SAAS,CAACR,GAAG,CAACC,YAAYU,EAAE;YACnC;YACA,OAAOT;QACT;QACAU,OAAO;YACL,IAAInB,MAAM,GAAG;gBACX,kDAAkD;gBAClDsB,OAAOG,IAAI,CAACD,aAAaH,KAAK,CAAC,GAAGrB;gBAClCwB,eAAeZ,IAAAA,sCAAiB,EAACW;gBACjCvB,MAAM;YACR;QACF;QACAoB,UAAU,SAAVA;YACE,IAAI,CAACD,KAAK;YACV,oDAAoD;YACpD,IAAIG,OAAOvB,MAAM,KAAK,GAAG;gBACvB,OAAOuB,MAAM,CAAC,EAAE;YAClB;YACA,OAAOI,OAAOC,MAAM,CAACL;QACvB;IACF;AACF"}
|
|
@@ -158,7 +158,8 @@ var ErrorCode = {
|
|
|
158
158
|
TRUNCATED_ARCHIVE: 'TRUNCATED_ARCHIVE',
|
|
159
159
|
CORRUPT_HEADER: 'CORRUPT_HEADER',
|
|
160
160
|
ENCRYPTED_ARCHIVE: 'ENCRYPTED_ARCHIVE',
|
|
161
|
-
COMPRESSED_HEADER: 'COMPRESSED_HEADER'
|
|
161
|
+
COMPRESSED_HEADER: 'COMPRESSED_HEADER',
|
|
162
|
+
DECOMPRESSION_FAILED: 'DECOMPRESSION_FAILED'
|
|
162
163
|
};
|
|
163
164
|
function createCodedError(message, code) {
|
|
164
165
|
var err = new Error(message);
|