7z-iterator 1.4.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.cts +3 -3
- package/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/index.js +7 -38
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/nextEntry.js +1 -2
- package/dist/cjs/nextEntry.js.map +1 -1
- package/dist/cjs/sevenz/ArchiveSource.d.cts +1 -0
- package/dist/cjs/sevenz/ArchiveSource.d.ts +1 -0
- package/dist/cjs/sevenz/ArchiveSource.js +23 -0
- package/dist/cjs/sevenz/ArchiveSource.js.map +1 -1
- package/dist/cjs/sevenz/SevenZipParser.js +22 -3
- package/dist/cjs/sevenz/SevenZipParser.js.map +1 -1
- package/dist/cjs/sevenz/codecs/index.js +52 -30
- package/dist/cjs/sevenz/codecs/index.js.map +1 -1
- package/dist/cjs/sevenz/constants.d.cts +1 -0
- package/dist/cjs/sevenz/constants.d.ts +1 -0
- package/dist/cjs/sevenz/constants.js +1 -0
- package/dist/cjs/sevenz/constants.js.map +1 -1
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.js +4 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/nextEntry.js +1 -2
- package/dist/esm/nextEntry.js.map +1 -1
- package/dist/esm/sevenz/ArchiveSource.d.ts +1 -0
- package/dist/esm/sevenz/ArchiveSource.js +23 -0
- package/dist/esm/sevenz/ArchiveSource.js.map +1 -1
- package/dist/esm/sevenz/SevenZipParser.js +22 -3
- package/dist/esm/sevenz/SevenZipParser.js.map +1 -1
- package/dist/esm/sevenz/codecs/index.js +32 -10
- package/dist/esm/sevenz/codecs/index.js.map +1 -1
- package/dist/esm/sevenz/constants.d.ts +1 -0
- package/dist/esm/sevenz/constants.js +1 -0
- package/dist/esm/sevenz/constants.js.map +1 -1
- package/package.json +3 -3
- package/dist/cjs/lzma/Lzma2ChunkParser.d.cts +0 -73
- package/dist/cjs/lzma/Lzma2ChunkParser.d.ts +0 -73
- package/dist/cjs/lzma/Lzma2ChunkParser.js +0 -148
- package/dist/cjs/lzma/Lzma2ChunkParser.js.map +0 -1
- package/dist/cjs/lzma/index.d.cts +0 -31
- package/dist/cjs/lzma/index.d.ts +0 -31
- package/dist/cjs/lzma/index.js +0 -83
- package/dist/cjs/lzma/index.js.map +0 -1
- package/dist/cjs/lzma/stream/transforms.d.cts +0 -46
- package/dist/cjs/lzma/stream/transforms.d.ts +0 -46
- package/dist/cjs/lzma/stream/transforms.js +0 -209
- package/dist/cjs/lzma/stream/transforms.js.map +0 -1
- package/dist/cjs/lzma/sync/Lzma2Decoder.d.cts +0 -63
- package/dist/cjs/lzma/sync/Lzma2Decoder.d.ts +0 -63
- package/dist/cjs/lzma/sync/Lzma2Decoder.js +0 -231
- package/dist/cjs/lzma/sync/Lzma2Decoder.js.map +0 -1
- package/dist/cjs/lzma/sync/LzmaDecoder.d.cts +0 -97
- package/dist/cjs/lzma/sync/LzmaDecoder.d.ts +0 -97
- package/dist/cjs/lzma/sync/LzmaDecoder.js +0 -580
- package/dist/cjs/lzma/sync/LzmaDecoder.js.map +0 -1
- package/dist/cjs/lzma/sync/RangeDecoder.d.cts +0 -69
- package/dist/cjs/lzma/sync/RangeDecoder.d.ts +0 -69
- package/dist/cjs/lzma/sync/RangeDecoder.js +0 -162
- package/dist/cjs/lzma/sync/RangeDecoder.js.map +0 -1
- package/dist/cjs/lzma/types.d.cts +0 -117
- package/dist/cjs/lzma/types.d.ts +0 -117
- package/dist/cjs/lzma/types.js +0 -264
- package/dist/cjs/lzma/types.js.map +0 -1
- package/dist/cjs/sevenz/codecs/Bcj.d.cts +0 -16
- package/dist/cjs/sevenz/codecs/Bcj.d.ts +0 -16
- package/dist/cjs/sevenz/codecs/Bcj.js +0 -183
- package/dist/cjs/sevenz/codecs/Bcj.js.map +0 -1
- package/dist/cjs/sevenz/codecs/BcjArm.d.cts +0 -21
- package/dist/cjs/sevenz/codecs/BcjArm.d.ts +0 -21
- package/dist/cjs/sevenz/codecs/BcjArm.js +0 -104
- package/dist/cjs/sevenz/codecs/BcjArm.js.map +0 -1
- package/dist/cjs/sevenz/codecs/BcjArm64.d.cts +0 -21
- package/dist/cjs/sevenz/codecs/BcjArm64.d.ts +0 -21
- package/dist/cjs/sevenz/codecs/BcjArm64.js +0 -65
- package/dist/cjs/sevenz/codecs/BcjArm64.js.map +0 -1
- package/dist/cjs/sevenz/codecs/BcjArmt.d.cts +0 -19
- package/dist/cjs/sevenz/codecs/BcjArmt.d.ts +0 -19
- package/dist/cjs/sevenz/codecs/BcjArmt.js +0 -76
- package/dist/cjs/sevenz/codecs/BcjArmt.js.map +0 -1
- package/dist/cjs/sevenz/codecs/BcjIa64.d.cts +0 -15
- package/dist/cjs/sevenz/codecs/BcjIa64.d.ts +0 -15
- package/dist/cjs/sevenz/codecs/BcjIa64.js +0 -141
- package/dist/cjs/sevenz/codecs/BcjIa64.js.map +0 -1
- package/dist/cjs/sevenz/codecs/BcjPpc.d.cts +0 -20
- package/dist/cjs/sevenz/codecs/BcjPpc.d.ts +0 -20
- package/dist/cjs/sevenz/codecs/BcjPpc.js +0 -64
- package/dist/cjs/sevenz/codecs/BcjPpc.js.map +0 -1
- package/dist/cjs/sevenz/codecs/BcjSparc.d.cts +0 -19
- package/dist/cjs/sevenz/codecs/BcjSparc.d.ts +0 -19
- package/dist/cjs/sevenz/codecs/BcjSparc.js +0 -69
- package/dist/cjs/sevenz/codecs/BcjSparc.js.map +0 -1
- package/dist/cjs/sevenz/codecs/Delta.d.cts +0 -16
- package/dist/cjs/sevenz/codecs/Delta.d.ts +0 -16
- package/dist/cjs/sevenz/codecs/Delta.js +0 -74
- package/dist/cjs/sevenz/codecs/Delta.js.map +0 -1
- package/dist/cjs/sevenz/codecs/Lzma.d.cts +0 -17
- package/dist/cjs/sevenz/codecs/Lzma.d.ts +0 -17
- package/dist/cjs/sevenz/codecs/Lzma.js +0 -40
- package/dist/cjs/sevenz/codecs/Lzma.js.map +0 -1
- package/dist/cjs/sevenz/codecs/Lzma2.d.cts +0 -20
- package/dist/cjs/sevenz/codecs/Lzma2.d.ts +0 -20
- package/dist/cjs/sevenz/codecs/Lzma2.js +0 -42
- package/dist/cjs/sevenz/codecs/Lzma2.js.map +0 -1
- package/dist/cjs/xz/Decoder.d.cts +0 -25
- package/dist/cjs/xz/Decoder.d.ts +0 -25
- package/dist/cjs/xz/Decoder.js +0 -194
- package/dist/cjs/xz/Decoder.js.map +0 -1
- package/dist/esm/lzma/Lzma2ChunkParser.d.ts +0 -73
- package/dist/esm/lzma/Lzma2ChunkParser.js +0 -137
- package/dist/esm/lzma/Lzma2ChunkParser.js.map +0 -1
- package/dist/esm/lzma/index.d.ts +0 -31
- package/dist/esm/lzma/index.js +0 -44
- package/dist/esm/lzma/index.js.map +0 -1
- package/dist/esm/lzma/stream/transforms.d.ts +0 -46
- package/dist/esm/lzma/stream/transforms.js +0 -189
- package/dist/esm/lzma/stream/transforms.js.map +0 -1
- package/dist/esm/lzma/sync/Lzma2Decoder.d.ts +0 -63
- package/dist/esm/lzma/sync/Lzma2Decoder.js +0 -211
- package/dist/esm/lzma/sync/Lzma2Decoder.js.map +0 -1
- package/dist/esm/lzma/sync/LzmaDecoder.d.ts +0 -97
- package/dist/esm/lzma/sync/LzmaDecoder.js +0 -543
- package/dist/esm/lzma/sync/LzmaDecoder.js.map +0 -1
- package/dist/esm/lzma/sync/RangeDecoder.d.ts +0 -69
- package/dist/esm/lzma/sync/RangeDecoder.js +0 -132
- package/dist/esm/lzma/sync/RangeDecoder.js.map +0 -1
- package/dist/esm/lzma/types.d.ts +0 -117
- package/dist/esm/lzma/types.js +0 -154
- package/dist/esm/lzma/types.js.map +0 -1
- package/dist/esm/sevenz/codecs/Bcj.d.ts +0 -16
- package/dist/esm/sevenz/codecs/Bcj.js +0 -175
- package/dist/esm/sevenz/codecs/Bcj.js.map +0 -1
- package/dist/esm/sevenz/codecs/BcjArm.d.ts +0 -21
- package/dist/esm/sevenz/codecs/BcjArm.js +0 -101
- package/dist/esm/sevenz/codecs/BcjArm.js.map +0 -1
- package/dist/esm/sevenz/codecs/BcjArm64.d.ts +0 -21
- package/dist/esm/sevenz/codecs/BcjArm64.js +0 -57
- package/dist/esm/sevenz/codecs/BcjArm64.js.map +0 -1
- package/dist/esm/sevenz/codecs/BcjArmt.d.ts +0 -19
- package/dist/esm/sevenz/codecs/BcjArmt.js +0 -66
- package/dist/esm/sevenz/codecs/BcjArmt.js.map +0 -1
- package/dist/esm/sevenz/codecs/BcjIa64.d.ts +0 -15
- package/dist/esm/sevenz/codecs/BcjIa64.js +0 -127
- package/dist/esm/sevenz/codecs/BcjIa64.js.map +0 -1
- package/dist/esm/sevenz/codecs/BcjPpc.d.ts +0 -20
- package/dist/esm/sevenz/codecs/BcjPpc.js +0 -55
- package/dist/esm/sevenz/codecs/BcjPpc.js.map +0 -1
- package/dist/esm/sevenz/codecs/BcjSparc.d.ts +0 -19
- package/dist/esm/sevenz/codecs/BcjSparc.js +0 -59
- package/dist/esm/sevenz/codecs/BcjSparc.js.map +0 -1
- package/dist/esm/sevenz/codecs/Delta.d.ts +0 -16
- package/dist/esm/sevenz/codecs/Delta.js +0 -66
- package/dist/esm/sevenz/codecs/Delta.js.map +0 -1
- package/dist/esm/sevenz/codecs/Lzma.d.ts +0 -17
- package/dist/esm/sevenz/codecs/Lzma.js +0 -33
- package/dist/esm/sevenz/codecs/Lzma.js.map +0 -1
- package/dist/esm/sevenz/codecs/Lzma2.d.ts +0 -20
- package/dist/esm/sevenz/codecs/Lzma2.js +0 -38
- package/dist/esm/sevenz/codecs/Lzma2.js.map +0 -1
- package/dist/esm/xz/Decoder.d.ts +0 -25
- package/dist/esm/xz/Decoder.js +0 -185
- package/dist/esm/xz/Decoder.js.map +0 -1
package/dist/esm/xz/Decoder.js
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* XZ Decompression Module
|
|
3
|
-
*
|
|
4
|
-
* XZ is a container format that wraps LZMA2 compressed data.
|
|
5
|
-
* This module provides both synchronous and streaming XZ decoders.
|
|
6
|
-
*
|
|
7
|
-
* Pure JavaScript implementation, works on Node.js 0.8+
|
|
8
|
-
*/ import { Transform } from 'extract-base-iterator';
|
|
9
|
-
import { decodeLzma2 } from '../lzma/index.js';
|
|
10
|
-
// XZ magic bytes
|
|
11
|
-
const XZ_MAGIC = [
|
|
12
|
-
0xfd,
|
|
13
|
-
0x37,
|
|
14
|
-
0x7a,
|
|
15
|
-
0x58,
|
|
16
|
-
0x5a,
|
|
17
|
-
0x00
|
|
18
|
-
];
|
|
19
|
-
const XZ_FOOTER_MAGIC = [
|
|
20
|
-
0x59,
|
|
21
|
-
0x5a
|
|
22
|
-
]; // "YZ"
|
|
23
|
-
// Filter IDs
|
|
24
|
-
const FILTER_LZMA2 = 0x21;
|
|
25
|
-
/**
|
|
26
|
-
* Simple buffer comparison
|
|
27
|
-
*/ function bufferEquals(buf, offset, expected) {
|
|
28
|
-
if (offset + expected.length > buf.length) {
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
for(let i = 0; i < expected.length; i++){
|
|
32
|
-
if (buf[offset + i] !== expected[i]) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Decode variable-length integer (XZ multibyte encoding)
|
|
40
|
-
*/ function decodeMultibyte(buf, offset) {
|
|
41
|
-
let value = 0;
|
|
42
|
-
let i = 0;
|
|
43
|
-
let byte;
|
|
44
|
-
do {
|
|
45
|
-
if (offset + i >= buf.length) {
|
|
46
|
-
throw new Error('Truncated multibyte integer');
|
|
47
|
-
}
|
|
48
|
-
byte = buf[offset + i];
|
|
49
|
-
value |= (byte & 0x7f) << i * 7;
|
|
50
|
-
i++;
|
|
51
|
-
if (i > 9) {
|
|
52
|
-
throw new Error('Multibyte integer too large');
|
|
53
|
-
}
|
|
54
|
-
}while (byte & 0x80)
|
|
55
|
-
return {
|
|
56
|
-
value,
|
|
57
|
-
bytesRead: i
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Decompress XZ data synchronously
|
|
62
|
-
* @param input - XZ compressed data
|
|
63
|
-
* @returns Decompressed data
|
|
64
|
-
*/ export function decodeXZ(input) {
|
|
65
|
-
var _checkSizes_checkType;
|
|
66
|
-
// Verify XZ magic
|
|
67
|
-
if (input.length < 12 || !bufferEquals(input, 0, XZ_MAGIC)) {
|
|
68
|
-
throw new Error('Invalid XZ magic bytes');
|
|
69
|
-
}
|
|
70
|
-
// Stream flags at offset 6-7
|
|
71
|
-
const checkType = input[7] & 0x0f;
|
|
72
|
-
// Check sizes based on check type
|
|
73
|
-
const checkSizes = {
|
|
74
|
-
0: 0,
|
|
75
|
-
1: 4,
|
|
76
|
-
4: 8,
|
|
77
|
-
10: 32
|
|
78
|
-
};
|
|
79
|
-
const checkSize = (_checkSizes_checkType = checkSizes[checkType]) !== null && _checkSizes_checkType !== void 0 ? _checkSizes_checkType : 0;
|
|
80
|
-
// Block starts at offset 12
|
|
81
|
-
let offset = 12;
|
|
82
|
-
// Block header size
|
|
83
|
-
const blockHeaderSizeRaw = input[offset];
|
|
84
|
-
if (blockHeaderSizeRaw === 0) {
|
|
85
|
-
throw new Error('Invalid block header size (index indicator found instead of block)');
|
|
86
|
-
}
|
|
87
|
-
const blockHeaderSize = (blockHeaderSizeRaw + 1) * 4;
|
|
88
|
-
// Parse block header to find LZMA2 properties
|
|
89
|
-
const blockHeaderStart = offset;
|
|
90
|
-
offset++; // skip size byte
|
|
91
|
-
const blockFlags = input[offset++];
|
|
92
|
-
const numFilters = (blockFlags & 0x03) + 1;
|
|
93
|
-
const hasCompressedSize = (blockFlags & 0x40) !== 0;
|
|
94
|
-
const hasUncompressedSize = (blockFlags & 0x80) !== 0;
|
|
95
|
-
// Skip optional sizes
|
|
96
|
-
if (hasCompressedSize) {
|
|
97
|
-
const result = decodeMultibyte(input, offset);
|
|
98
|
-
offset += result.bytesRead;
|
|
99
|
-
}
|
|
100
|
-
let _uncompressedSize;
|
|
101
|
-
if (hasUncompressedSize) {
|
|
102
|
-
const result = decodeMultibyte(input, offset);
|
|
103
|
-
_uncompressedSize = result.value;
|
|
104
|
-
offset += result.bytesRead;
|
|
105
|
-
}
|
|
106
|
-
// Parse filter (should be LZMA2)
|
|
107
|
-
let lzma2Props = null;
|
|
108
|
-
for(let i = 0; i < numFilters; i++){
|
|
109
|
-
const filterIdResult = decodeMultibyte(input, offset);
|
|
110
|
-
const filterId = filterIdResult.value;
|
|
111
|
-
offset += filterIdResult.bytesRead;
|
|
112
|
-
const propsSizeResult = decodeMultibyte(input, offset);
|
|
113
|
-
offset += propsSizeResult.bytesRead;
|
|
114
|
-
const filterProps = input.slice(offset, offset + propsSizeResult.value);
|
|
115
|
-
offset += propsSizeResult.value;
|
|
116
|
-
if (filterId === FILTER_LZMA2) {
|
|
117
|
-
lzma2Props = filterProps;
|
|
118
|
-
} else if (filterId !== 0x03 && filterId !== 0x04 && filterId !== 0x05 && filterId !== 0x06 && filterId !== 0x07 && filterId !== 0x08 && filterId !== 0x09 && filterId !== 0x0a) {
|
|
119
|
-
// BCJ filters (0x04-0x0a) and Delta (0x03) are preprocessing filters
|
|
120
|
-
// For now, only support LZMA2 alone
|
|
121
|
-
throw new Error(`Unsupported filter: 0x${filterId.toString(16)}`);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (!lzma2Props) {
|
|
125
|
-
throw new Error('No LZMA2 filter found in XZ block');
|
|
126
|
-
}
|
|
127
|
-
// Skip to end of block header (align to 4 bytes + CRC32)
|
|
128
|
-
const blockDataStart = blockHeaderStart + blockHeaderSize;
|
|
129
|
-
// Find the end of compressed data (look for index from the footer)
|
|
130
|
-
// Footer is last 12 bytes: CRC32(4) + Backward Size(4) + Stream Flags(2) + Magic(2)
|
|
131
|
-
if (input.length < 12) {
|
|
132
|
-
throw new Error('XZ file too small');
|
|
133
|
-
}
|
|
134
|
-
// Verify footer magic
|
|
135
|
-
if (!bufferEquals(input, input.length - 2, XZ_FOOTER_MAGIC)) {
|
|
136
|
-
throw new Error('Invalid XZ footer magic');
|
|
137
|
-
}
|
|
138
|
-
// Get backward size (tells us where index starts)
|
|
139
|
-
// Footer: CRC32(4) at -12, Backward Size(4) at -8, Stream Flags(2) at -4, Magic(2) at -2
|
|
140
|
-
const backwardSize = (input.readUInt32LE(input.length - 8) + 1) * 4;
|
|
141
|
-
const indexStart = input.length - 12 - backwardSize;
|
|
142
|
-
// Extract all data between block header end and index start
|
|
143
|
-
let compressedDataEnd = indexStart;
|
|
144
|
-
// Account for check at end of block
|
|
145
|
-
compressedDataEnd -= checkSize;
|
|
146
|
-
// Account for padding (up to 3 bytes of 0x00)
|
|
147
|
-
while(compressedDataEnd > blockDataStart && input[compressedDataEnd - 1] === 0x00){
|
|
148
|
-
compressedDataEnd--;
|
|
149
|
-
}
|
|
150
|
-
// Add back one 0x00 for LZMA2 end marker
|
|
151
|
-
compressedDataEnd++;
|
|
152
|
-
const compressedData = input.slice(blockDataStart, compressedDataEnd);
|
|
153
|
-
// Decompress LZMA2 data using optimized output stream decoder
|
|
154
|
-
const chunks = [];
|
|
155
|
-
decodeLzma2(compressedData, lzma2Props, undefined, {
|
|
156
|
-
write: (chunk)=>chunks.push(chunk)
|
|
157
|
-
});
|
|
158
|
-
return Buffer.concat(chunks);
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Create an XZ decompression Transform stream
|
|
162
|
-
*
|
|
163
|
-
* Note: XZ buffers all input before decompressing, as it's a single-frame format.
|
|
164
|
-
* For true streaming with better performance on large files, consider using XZ directly
|
|
165
|
-
* with the sync decodeXZ() function.
|
|
166
|
-
*
|
|
167
|
-
* @returns Transform stream that decompresses XZ data
|
|
168
|
-
*/ export function createXZDecoder() {
|
|
169
|
-
const chunks = [];
|
|
170
|
-
return new Transform({
|
|
171
|
-
transform (chunk, _encoding, callback) {
|
|
172
|
-
chunks.push(chunk);
|
|
173
|
-
callback();
|
|
174
|
-
},
|
|
175
|
-
flush (callback) {
|
|
176
|
-
try {
|
|
177
|
-
const input = Buffer.concat(chunks);
|
|
178
|
-
const output = decodeXZ(input);
|
|
179
|
-
callback(null, output);
|
|
180
|
-
} catch (err) {
|
|
181
|
-
callback(err);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/7z-iterator/src/xz/Decoder.ts"],"sourcesContent":["/**\n * XZ Decompression Module\n *\n * XZ is a container format that wraps LZMA2 compressed data.\n * This module provides both synchronous and streaming XZ decoders.\n *\n * Pure JavaScript implementation, works on Node.js 0.8+\n */\n\nimport { Transform } from 'extract-base-iterator';\nimport type { Transform as TransformType } from 'stream';\nimport { decodeLzma2 } from '../lzma/index.ts';\n\n// XZ magic bytes\nconst XZ_MAGIC = [0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00];\nconst XZ_FOOTER_MAGIC = [0x59, 0x5a]; // \"YZ\"\n\n// Filter IDs\nconst FILTER_LZMA2 = 0x21;\n\n/**\n * Simple buffer comparison\n */\nfunction bufferEquals(buf: Buffer, offset: number, expected: number[]): boolean {\n if (offset + expected.length > buf.length) {\n return false;\n }\n for (let i = 0; i < expected.length; i++) {\n if (buf[offset + i] !== expected[i]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Decode variable-length integer (XZ multibyte encoding)\n */\nfunction decodeMultibyte(buf: Buffer, offset: number): { value: number; bytesRead: number } {\n let value = 0;\n let i = 0;\n let byte: number;\n do {\n if (offset + i >= buf.length) {\n throw new Error('Truncated multibyte integer');\n }\n byte = buf[offset + i];\n value |= (byte & 0x7f) << (i * 7);\n i++;\n if (i > 9) {\n throw new Error('Multibyte integer too large');\n }\n } while (byte & 0x80);\n return { value, bytesRead: i };\n}\n\n/**\n * Decompress XZ data synchronously\n * @param input - XZ compressed data\n * @returns Decompressed data\n */\nexport function decodeXZ(input: Buffer): Buffer {\n // Verify XZ magic\n if (input.length < 12 || !bufferEquals(input, 0, XZ_MAGIC)) {\n throw new Error('Invalid XZ magic bytes');\n }\n\n // Stream flags at offset 6-7\n const checkType = input[7] & 0x0f;\n\n // Check sizes based on check type\n const checkSizes: { [key: number]: number } = {\n 0: 0, // None\n 1: 4, // CRC32\n 4: 8, // CRC64\n 10: 32, // SHA-256\n };\n const checkSize = checkSizes[checkType] ?? 0;\n\n // Block starts at offset 12\n let offset = 12;\n\n // Block header size\n const blockHeaderSizeRaw = input[offset];\n if (blockHeaderSizeRaw === 0) {\n throw new Error('Invalid block header size (index indicator found instead of block)');\n }\n const blockHeaderSize = (blockHeaderSizeRaw + 1) * 4;\n\n // Parse block header to find LZMA2 properties\n const blockHeaderStart = offset;\n offset++; // skip size byte\n\n const blockFlags = input[offset++];\n const numFilters = (blockFlags & 0x03) + 1;\n const hasCompressedSize = (blockFlags & 0x40) !== 0;\n const hasUncompressedSize = (blockFlags & 0x80) !== 0;\n\n // Skip optional sizes\n if (hasCompressedSize) {\n const result = decodeMultibyte(input, offset);\n offset += result.bytesRead;\n }\n\n let _uncompressedSize: number | undefined;\n if (hasUncompressedSize) {\n const result = decodeMultibyte(input, offset);\n _uncompressedSize = result.value;\n offset += result.bytesRead;\n }\n\n // Parse filter (should be LZMA2)\n let lzma2Props: Buffer | null = null;\n for (let i = 0; i < numFilters; i++) {\n const filterIdResult = decodeMultibyte(input, offset);\n const filterId = filterIdResult.value;\n offset += filterIdResult.bytesRead;\n\n const propsSizeResult = decodeMultibyte(input, offset);\n offset += propsSizeResult.bytesRead;\n\n const filterProps = input.slice(offset, offset + propsSizeResult.value);\n offset += propsSizeResult.value;\n\n if (filterId === FILTER_LZMA2) {\n lzma2Props = filterProps;\n } else if (filterId !== 0x03 && filterId !== 0x04 && filterId !== 0x05 && filterId !== 0x06 && filterId !== 0x07 && filterId !== 0x08 && filterId !== 0x09 && filterId !== 0x0a) {\n // BCJ filters (0x04-0x0a) and Delta (0x03) are preprocessing filters\n // For now, only support LZMA2 alone\n throw new Error(`Unsupported filter: 0x${filterId.toString(16)}`);\n }\n }\n\n if (!lzma2Props) {\n throw new Error('No LZMA2 filter found in XZ block');\n }\n\n // Skip to end of block header (align to 4 bytes + CRC32)\n const blockDataStart = blockHeaderStart + blockHeaderSize;\n\n // Find the end of compressed data (look for index from the footer)\n // Footer is last 12 bytes: CRC32(4) + Backward Size(4) + Stream Flags(2) + Magic(2)\n if (input.length < 12) {\n throw new Error('XZ file too small');\n }\n\n // Verify footer magic\n if (!bufferEquals(input, input.length - 2, XZ_FOOTER_MAGIC)) {\n throw new Error('Invalid XZ footer magic');\n }\n\n // Get backward size (tells us where index starts)\n // Footer: CRC32(4) at -12, Backward Size(4) at -8, Stream Flags(2) at -4, Magic(2) at -2\n const backwardSize = (input.readUInt32LE(input.length - 8) + 1) * 4;\n const indexStart = input.length - 12 - backwardSize;\n\n // Extract all data between block header end and index start\n let compressedDataEnd = indexStart;\n\n // Account for check at end of block\n compressedDataEnd -= checkSize;\n\n // Account for padding (up to 3 bytes of 0x00)\n while (compressedDataEnd > blockDataStart && input[compressedDataEnd - 1] === 0x00) {\n compressedDataEnd--;\n }\n // Add back one 0x00 for LZMA2 end marker\n compressedDataEnd++;\n\n const compressedData = input.slice(blockDataStart, compressedDataEnd);\n\n // Decompress LZMA2 data using optimized output stream decoder\n const chunks: Buffer[] = [];\n decodeLzma2(compressedData, lzma2Props, undefined, {\n write: (chunk: Buffer) => chunks.push(chunk),\n });\n\n return Buffer.concat(chunks);\n}\n\n/**\n * Create an XZ decompression Transform stream\n *\n * Note: XZ buffers all input before decompressing, as it's a single-frame format.\n * For true streaming with better performance on large files, consider using XZ directly\n * with the sync decodeXZ() function.\n *\n * @returns Transform stream that decompresses XZ data\n */\nexport function createXZDecoder(): TransformType {\n const chunks: Buffer[] = [];\n\n return new Transform({\n transform(chunk: Buffer, _encoding: string, callback: (error?: Error | null, data?: Buffer) => void) {\n chunks.push(chunk);\n callback();\n },\n\n flush(callback: (error?: Error | null, data?: Buffer) => void) {\n try {\n const input = Buffer.concat(chunks);\n const output = decodeXZ(input);\n callback(null, output);\n } catch (err) {\n callback(err as Error);\n }\n },\n });\n}\n"],"names":["Transform","decodeLzma2","XZ_MAGIC","XZ_FOOTER_MAGIC","FILTER_LZMA2","bufferEquals","buf","offset","expected","length","i","decodeMultibyte","value","byte","Error","bytesRead","decodeXZ","input","checkSizes","checkType","checkSize","blockHeaderSizeRaw","blockHeaderSize","blockHeaderStart","blockFlags","numFilters","hasCompressedSize","hasUncompressedSize","result","_uncompressedSize","lzma2Props","filterIdResult","filterId","propsSizeResult","filterProps","slice","toString","blockDataStart","backwardSize","readUInt32LE","indexStart","compressedDataEnd","compressedData","chunks","undefined","write","chunk","push","Buffer","concat","createXZDecoder","transform","_encoding","callback","flush","output","err"],"mappings":"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"}
|