xz-compat 1.2.5 → 1.2.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/dist/cjs/filters/bcj/Bcj.js +1 -1
- package/dist/cjs/filters/bcj/Bcj.js.map +1 -1
- package/dist/cjs/filters/bcj/BcjArm.js +1 -1
- package/dist/cjs/filters/bcj/BcjArm.js.map +1 -1
- package/dist/cjs/filters/delta/Delta.js +1 -1
- package/dist/cjs/filters/delta/Delta.js.map +1 -1
- package/dist/cjs/lzma/stream/transforms.js +2 -2
- package/dist/cjs/lzma/stream/transforms.js.map +1 -1
- package/dist/cjs/native.js +3 -3
- package/dist/cjs/native.js.map +1 -1
- package/dist/cjs/sevenz.js +4 -4
- package/dist/cjs/sevenz.js.map +1 -1
- package/dist/cjs/utils/createBufferingDecoder.js +1 -1
- package/dist/cjs/utils/createBufferingDecoder.js.map +1 -1
- package/dist/cjs/xz/Decoder.js +6 -9
- package/dist/cjs/xz/Decoder.js.map +1 -1
- package/dist/esm/xz/Decoder.js +1 -4
- package/dist/esm/xz/Decoder.js.map +1 -1
- package/package.json +2 -1
|
@@ -146,7 +146,7 @@ function createBcjDecoder(_properties, _unpackSize) {
|
|
|
146
146
|
var globalPos = 0; // Position in the overall stream
|
|
147
147
|
var pending = null; // Bytes pending from previous chunk
|
|
148
148
|
var transform = new _extractbaseiterator.Transform({
|
|
149
|
-
transform: function(chunk, _encoding, callback) {
|
|
149
|
+
transform: function transform(chunk, _encoding, callback) {
|
|
150
150
|
// Combine pending bytes with new chunk
|
|
151
151
|
var data;
|
|
152
152
|
if (pending && pending.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/filters/bcj/Bcj.ts"],"sourcesContent":["// BCJ (x86) filter codec - converts x86 CALL/JMP relative addresses\n// This is a simple filter that makes executables more compressible by LZMA\n//\n// BCJ transforms relative addresses in x86 CALL (0xE8) and JMP (0xE9) instructions\n// to absolute addresses, which creates more repetitive patterns for compression.\n//\n// Reference: https://github.com/tukaani-project/xz/blob/master/src/liblzma/simple/x86.c\n//\n// This implementation uses true streaming - processes data chunk by chunk\n// while buffering incomplete instructions across chunk boundaries.\n\nimport { allocBuffer, bufferFrom, Transform } from 'extract-base-iterator';\n\n// Test if byte is 0x00 or 0xFF (valid MSB for converted addresses)\nfunction Test86MSByte(b: number): boolean {\n return b === 0 || b === 0xff;\n}\n\n// Lookup table for mask to bit number conversion (used in false positive prevention)\nconst MASK_TO_BIT_NUMBER = [0, 1, 2, 2, 3];\n\n/**\n * BCJ x86 filter state\n */\ninterface BcjX86State {\n prevMask: number;\n prevPos: number;\n}\n\n/**\n * Core x86 BCJ conversion function (matches reference x86_code)\n * Works for both encoding and decoding based on isEncoder flag\n *\n * @param state - Filter state (prevMask and prevPos)\n * @param nowPos - Current position in the overall stream\n * @param isEncoder - true for encoding, false for decoding\n * @param buffer - Buffer to process (modified in place)\n * @param size - Size of buffer\n * @returns Number of bytes processed\n */\nfunction x86Code(state: BcjX86State, nowPos: number, isEncoder: boolean, buffer: Buffer, size: number): number {\n let prevMask = state.prevMask;\n let prevPos = state.prevPos;\n\n if (size < 5) {\n return 0;\n }\n\n // Decay prev_pos if too far from current position\n if (nowPos - prevPos > 5) {\n prevPos = nowPos - 5;\n }\n\n const limit = size - 5;\n let bufferPos = 0;\n\n while (bufferPos <= limit) {\n const opcode = buffer[bufferPos];\n\n // Check for CALL (0xE8) or JMP (0xE9) opcode\n if (opcode !== 0xe8 && opcode !== 0xe9) {\n bufferPos++;\n continue;\n }\n\n // Calculate offset from previous position\n const offset = nowPos + bufferPos - prevPos;\n prevPos = nowPos + bufferPos;\n\n // Update mask based on offset\n if (offset > 5) {\n prevMask = 0;\n } else {\n for (let i = 0; i < offset; i++) {\n prevMask &= 0x77;\n prevMask <<= 1;\n }\n }\n\n // Get the high byte of the address\n let b = buffer[bufferPos + 4];\n\n // Check if this looks like a valid address to convert\n if (Test86MSByte(b) && prevMask >> 1 <= 4 && prevMask >> 1 !== 3) {\n // Read 32-bit address (big-endian style: high byte first in src)\n let src = (b << 24) | (buffer[bufferPos + 3] << 16) | (buffer[bufferPos + 2] << 8) | buffer[bufferPos + 1];\n\n // Make src unsigned 32-bit\n src = src >>> 0;\n\n let dest: number;\n\n // Conversion loop with false positive correction\n while (true) {\n if (isEncoder) {\n dest = (src + (nowPos + bufferPos + 5)) >>> 0;\n } else {\n dest = (src - (nowPos + bufferPos + 5)) >>> 0;\n }\n\n if (prevMask === 0) {\n break;\n }\n\n const i = MASK_TO_BIT_NUMBER[prevMask >> 1];\n b = (dest >>> (24 - i * 8)) & 0xff;\n\n if (!Test86MSByte(b)) {\n break;\n }\n\n // XOR correction for false positive prevention\n src = (dest ^ ((1 << (32 - i * 8)) - 1)) >>> 0;\n }\n\n // Write back the converted address\n // High byte: ~(((dest >> 24) & 1) - 1) produces 0x00 or 0xFF\n buffer[bufferPos + 4] = ~(((dest >>> 24) & 1) - 1) & 0xff;\n buffer[bufferPos + 3] = (dest >>> 16) & 0xff;\n buffer[bufferPos + 2] = (dest >>> 8) & 0xff;\n buffer[bufferPos + 1] = dest & 0xff;\n\n bufferPos += 5;\n prevMask = 0;\n } else {\n bufferPos++;\n prevMask |= 1;\n if (Test86MSByte(b)) {\n prevMask |= 0x10;\n }\n }\n }\n\n // Save state\n state.prevMask = prevMask;\n state.prevPos = prevPos;\n\n return bufferPos;\n}\n\n/**\n * Decode BCJ (x86) filtered data (synchronous, for buffered use)\n * Reverses the BCJ transformation by converting absolute addresses back to relative\n *\n * @param input - BCJ filtered data\n * @param _properties - Unused for BCJ\n * @param _unpackSize - Unused for BCJ\n * @returns Unfiltered data\n */\nexport function decodeBcj(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer {\n const output = bufferFrom(input); // Copy since we modify in place\n\n const state: BcjX86State = {\n prevMask: 0,\n prevPos: 0xfffffffb, // (uint32_t)(-5) in C\n };\n\n x86Code(state, 0, false, output, output.length);\n\n return output;\n}\n\n/**\n * Create a streaming BCJ decoder Transform.\n * Processes data chunk by chunk, buffering incomplete instructions.\n */\nexport function createBcjDecoder(_properties?: Buffer, _unpackSize?: number): InstanceType<typeof Transform> {\n // State that persists across chunks\n const state: BcjX86State = {\n prevMask: 0,\n prevPos: 0xfffffffb, // (uint32_t)(-5) in C\n };\n let globalPos = 0; // Position in the overall stream\n let pending: Buffer | null = null; // Bytes pending from previous chunk\n\n const transform = new Transform({\n transform: (chunk: Buffer, _encoding: string, callback: (err?: Error | null, data?: Buffer) => void) => {\n // Combine pending bytes with new chunk\n let data: Buffer;\n if (pending && pending.length > 0) {\n data = Buffer.concat([pending, chunk]);\n } else {\n data = chunk;\n }\n\n // We need at least 5 bytes to process an instruction\n if (data.length < 5) {\n pending = data;\n callback(null, allocBuffer(0));\n return;\n }\n\n // Process the buffer\n const output = bufferFrom(data);\n const processed = x86Code(state, globalPos, false, output, output.length);\n\n if (processed === 0) {\n // Not enough data to process\n pending = data;\n callback(null, allocBuffer(0));\n return;\n }\n\n // Output processed bytes, keep unprocessed as pending\n const result = output.slice(0, processed);\n pending = output.slice(processed);\n globalPos += processed;\n\n callback(null, result);\n },\n flush: function (this: InstanceType<typeof Transform>, callback: (err?: Error | null) => void) {\n // Output any remaining pending bytes\n if (pending && pending.length > 0) {\n // Process final bytes - can't convert incomplete instructions\n this.push(pending);\n }\n callback(null);\n },\n });\n\n return transform;\n}\n"],"names":["createBcjDecoder","decodeBcj","Test86MSByte","b","MASK_TO_BIT_NUMBER","x86Code","state","nowPos","isEncoder","buffer","size","prevMask","prevPos","limit","bufferPos","opcode","offset","i","src","dest","input","_properties","_unpackSize","output","bufferFrom","length","globalPos","pending","transform","Transform","chunk","_encoding","callback","data","Buffer","concat","allocBuffer","processed","result","slice","flush","push"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/filters/bcj/Bcj.ts"],"sourcesContent":["// BCJ (x86) filter codec - converts x86 CALL/JMP relative addresses\n// This is a simple filter that makes executables more compressible by LZMA\n//\n// BCJ transforms relative addresses in x86 CALL (0xE8) and JMP (0xE9) instructions\n// to absolute addresses, which creates more repetitive patterns for compression.\n//\n// Reference: https://github.com/tukaani-project/xz/blob/master/src/liblzma/simple/x86.c\n//\n// This implementation uses true streaming - processes data chunk by chunk\n// while buffering incomplete instructions across chunk boundaries.\n\nimport { allocBuffer, bufferFrom, Transform } from 'extract-base-iterator';\n\n// Test if byte is 0x00 or 0xFF (valid MSB for converted addresses)\nfunction Test86MSByte(b: number): boolean {\n return b === 0 || b === 0xff;\n}\n\n// Lookup table for mask to bit number conversion (used in false positive prevention)\nconst MASK_TO_BIT_NUMBER = [0, 1, 2, 2, 3];\n\n/**\n * BCJ x86 filter state\n */\ninterface BcjX86State {\n prevMask: number;\n prevPos: number;\n}\n\n/**\n * Core x86 BCJ conversion function (matches reference x86_code)\n * Works for both encoding and decoding based on isEncoder flag\n *\n * @param state - Filter state (prevMask and prevPos)\n * @param nowPos - Current position in the overall stream\n * @param isEncoder - true for encoding, false for decoding\n * @param buffer - Buffer to process (modified in place)\n * @param size - Size of buffer\n * @returns Number of bytes processed\n */\nfunction x86Code(state: BcjX86State, nowPos: number, isEncoder: boolean, buffer: Buffer, size: number): number {\n let prevMask = state.prevMask;\n let prevPos = state.prevPos;\n\n if (size < 5) {\n return 0;\n }\n\n // Decay prev_pos if too far from current position\n if (nowPos - prevPos > 5) {\n prevPos = nowPos - 5;\n }\n\n const limit = size - 5;\n let bufferPos = 0;\n\n while (bufferPos <= limit) {\n const opcode = buffer[bufferPos];\n\n // Check for CALL (0xE8) or JMP (0xE9) opcode\n if (opcode !== 0xe8 && opcode !== 0xe9) {\n bufferPos++;\n continue;\n }\n\n // Calculate offset from previous position\n const offset = nowPos + bufferPos - prevPos;\n prevPos = nowPos + bufferPos;\n\n // Update mask based on offset\n if (offset > 5) {\n prevMask = 0;\n } else {\n for (let i = 0; i < offset; i++) {\n prevMask &= 0x77;\n prevMask <<= 1;\n }\n }\n\n // Get the high byte of the address\n let b = buffer[bufferPos + 4];\n\n // Check if this looks like a valid address to convert\n if (Test86MSByte(b) && prevMask >> 1 <= 4 && prevMask >> 1 !== 3) {\n // Read 32-bit address (big-endian style: high byte first in src)\n let src = (b << 24) | (buffer[bufferPos + 3] << 16) | (buffer[bufferPos + 2] << 8) | buffer[bufferPos + 1];\n\n // Make src unsigned 32-bit\n src = src >>> 0;\n\n let dest: number;\n\n // Conversion loop with false positive correction\n while (true) {\n if (isEncoder) {\n dest = (src + (nowPos + bufferPos + 5)) >>> 0;\n } else {\n dest = (src - (nowPos + bufferPos + 5)) >>> 0;\n }\n\n if (prevMask === 0) {\n break;\n }\n\n const i = MASK_TO_BIT_NUMBER[prevMask >> 1];\n b = (dest >>> (24 - i * 8)) & 0xff;\n\n if (!Test86MSByte(b)) {\n break;\n }\n\n // XOR correction for false positive prevention\n src = (dest ^ ((1 << (32 - i * 8)) - 1)) >>> 0;\n }\n\n // Write back the converted address\n // High byte: ~(((dest >> 24) & 1) - 1) produces 0x00 or 0xFF\n buffer[bufferPos + 4] = ~(((dest >>> 24) & 1) - 1) & 0xff;\n buffer[bufferPos + 3] = (dest >>> 16) & 0xff;\n buffer[bufferPos + 2] = (dest >>> 8) & 0xff;\n buffer[bufferPos + 1] = dest & 0xff;\n\n bufferPos += 5;\n prevMask = 0;\n } else {\n bufferPos++;\n prevMask |= 1;\n if (Test86MSByte(b)) {\n prevMask |= 0x10;\n }\n }\n }\n\n // Save state\n state.prevMask = prevMask;\n state.prevPos = prevPos;\n\n return bufferPos;\n}\n\n/**\n * Decode BCJ (x86) filtered data (synchronous, for buffered use)\n * Reverses the BCJ transformation by converting absolute addresses back to relative\n *\n * @param input - BCJ filtered data\n * @param _properties - Unused for BCJ\n * @param _unpackSize - Unused for BCJ\n * @returns Unfiltered data\n */\nexport function decodeBcj(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer {\n const output = bufferFrom(input); // Copy since we modify in place\n\n const state: BcjX86State = {\n prevMask: 0,\n prevPos: 0xfffffffb, // (uint32_t)(-5) in C\n };\n\n x86Code(state, 0, false, output, output.length);\n\n return output;\n}\n\n/**\n * Create a streaming BCJ decoder Transform.\n * Processes data chunk by chunk, buffering incomplete instructions.\n */\nexport function createBcjDecoder(_properties?: Buffer, _unpackSize?: number): InstanceType<typeof Transform> {\n // State that persists across chunks\n const state: BcjX86State = {\n prevMask: 0,\n prevPos: 0xfffffffb, // (uint32_t)(-5) in C\n };\n let globalPos = 0; // Position in the overall stream\n let pending: Buffer | null = null; // Bytes pending from previous chunk\n\n const transform = new Transform({\n transform: (chunk: Buffer, _encoding: string, callback: (err?: Error | null, data?: Buffer) => void) => {\n // Combine pending bytes with new chunk\n let data: Buffer;\n if (pending && pending.length > 0) {\n data = Buffer.concat([pending, chunk]);\n } else {\n data = chunk;\n }\n\n // We need at least 5 bytes to process an instruction\n if (data.length < 5) {\n pending = data;\n callback(null, allocBuffer(0));\n return;\n }\n\n // Process the buffer\n const output = bufferFrom(data);\n const processed = x86Code(state, globalPos, false, output, output.length);\n\n if (processed === 0) {\n // Not enough data to process\n pending = data;\n callback(null, allocBuffer(0));\n return;\n }\n\n // Output processed bytes, keep unprocessed as pending\n const result = output.slice(0, processed);\n pending = output.slice(processed);\n globalPos += processed;\n\n callback(null, result);\n },\n flush: function (this: InstanceType<typeof Transform>, callback: (err?: Error | null) => void) {\n // Output any remaining pending bytes\n if (pending && pending.length > 0) {\n // Process final bytes - can't convert incomplete instructions\n this.push(pending);\n }\n callback(null);\n },\n });\n\n return transform;\n}\n"],"names":["createBcjDecoder","decodeBcj","Test86MSByte","b","MASK_TO_BIT_NUMBER","x86Code","state","nowPos","isEncoder","buffer","size","prevMask","prevPos","limit","bufferPos","opcode","offset","i","src","dest","input","_properties","_unpackSize","output","bufferFrom","length","globalPos","pending","transform","Transform","chunk","_encoding","callback","data","Buffer","concat","allocBuffer","processed","result","slice","flush","push"],"mappings":"AAAA,oEAAoE;AACpE,2EAA2E;AAC3E,EAAE;AACF,mFAAmF;AACnF,iFAAiF;AACjF,EAAE;AACF,wFAAwF;AACxF,EAAE;AACF,0EAA0E;AAC1E,mEAAmE;;;;;;;;;;;;QA6JnDA;eAAAA;;QAjBAC;eAAAA;;;mCA1ImC;AAEnD,mEAAmE;AACnE,SAASC,aAAaC,CAAS;IAC7B,OAAOA,MAAM,KAAKA,MAAM;AAC1B;AAEA,qFAAqF;AACrF,IAAMC,qBAAqB;IAAC;IAAG;IAAG;IAAG;IAAG;CAAE;AAU1C;;;;;;;;;;CAUC,GACD,SAASC,QAAQC,KAAkB,EAAEC,MAAc,EAAEC,SAAkB,EAAEC,MAAc,EAAEC,IAAY;IACnG,IAAIC,WAAWL,MAAMK,QAAQ;IAC7B,IAAIC,UAAUN,MAAMM,OAAO;IAE3B,IAAIF,OAAO,GAAG;QACZ,OAAO;IACT;IAEA,kDAAkD;IAClD,IAAIH,SAASK,UAAU,GAAG;QACxBA,UAAUL,SAAS;IACrB;IAEA,IAAMM,QAAQH,OAAO;IACrB,IAAII,YAAY;IAEhB,MAAOA,aAAaD,MAAO;QACzB,IAAME,SAASN,MAAM,CAACK,UAAU;QAEhC,6CAA6C;QAC7C,IAAIC,WAAW,QAAQA,WAAW,MAAM;YACtCD;YACA;QACF;QAEA,0CAA0C;QAC1C,IAAME,SAAST,SAASO,YAAYF;QACpCA,UAAUL,SAASO;QAEnB,8BAA8B;QAC9B,IAAIE,SAAS,GAAG;YACdL,WAAW;QACb,OAAO;YACL,IAAK,IAAIM,IAAI,GAAGA,IAAID,QAAQC,IAAK;gBAC/BN,YAAY;gBACZA,aAAa;YACf;QACF;QAEA,mCAAmC;QACnC,IAAIR,IAAIM,MAAM,CAACK,YAAY,EAAE;QAE7B,sDAAsD;QACtD,IAAIZ,aAAaC,MAAMQ,YAAY,KAAK,KAAKA,YAAY,MAAM,GAAG;YAChE,iEAAiE;YACjE,IAAIO,MAAM,AAACf,KAAK,KAAOM,MAAM,CAACK,YAAY,EAAE,IAAI,KAAOL,MAAM,CAACK,YAAY,EAAE,IAAI,IAAKL,MAAM,CAACK,YAAY,EAAE;YAE1G,2BAA2B;YAC3BI,MAAMA,QAAQ;YAEd,IAAIC,OAAAA,KAAAA;YAEJ,iDAAiD;YACjD,MAAO,KAAM;gBACX,IAAIX,WAAW;oBACbW,OAAO,AAACD,MAAOX,CAAAA,SAASO,YAAY,CAAA,MAAQ;gBAC9C,OAAO;oBACLK,OAAO,AAACD,MAAOX,CAAAA,SAASO,YAAY,CAAA,MAAQ;gBAC9C;gBAEA,IAAIH,aAAa,GAAG;oBAClB;gBACF;gBAEA,IAAMM,KAAIb,kBAAkB,CAACO,YAAY,EAAE;gBAC3CR,IAAI,AAACgB,SAAU,KAAKF,KAAI,IAAM;gBAE9B,IAAI,CAACf,aAAaC,IAAI;oBACpB;gBACF;gBAEA,+CAA+C;gBAC/Ce,MAAM,AAACC,CAAAA,OAAQ,AAAC,CAAA,KAAM,KAAKF,KAAI,CAAC,IAAK,CAAC,MAAO;YAC/C;YAEA,mCAAmC;YACnC,6DAA6D;YAC7DR,MAAM,CAACK,YAAY,EAAE,GAAG,CAAE,CAAA,AAAC,CAAA,AAACK,SAAS,KAAM,CAAA,IAAK,CAAA,IAAK;YACrDV,MAAM,CAACK,YAAY,EAAE,GAAG,AAACK,SAAS,KAAM;YACxCV,MAAM,CAACK,YAAY,EAAE,GAAG,AAACK,SAAS,IAAK;YACvCV,MAAM,CAACK,YAAY,EAAE,GAAGK,OAAO;YAE/BL,aAAa;YACbH,WAAW;QACb,OAAO;YACLG;YACAH,YAAY;YACZ,IAAIT,aAAaC,IAAI;gBACnBQ,YAAY;YACd;QACF;IACF;IAEA,aAAa;IACbL,MAAMK,QAAQ,GAAGA;IACjBL,MAAMM,OAAO,GAAGA;IAEhB,OAAOE;AACT;AAWO,SAASb,UAAUmB,KAAa,EAAEC,WAAoB,EAAEC,WAAoB;IACjF,IAAMC,SAASC,IAAAA,+BAAU,EAACJ,QAAQ,gCAAgC;IAElE,IAAMd,QAAqB;QACzBK,UAAU;QACVC,SAAS;IACX;IAEAP,QAAQC,OAAO,GAAG,OAAOiB,QAAQA,OAAOE,MAAM;IAE9C,OAAOF;AACT;AAMO,SAASvB,iBAAiBqB,WAAoB,EAAEC,WAAoB;IACzE,oCAAoC;IACpC,IAAMhB,QAAqB;QACzBK,UAAU;QACVC,SAAS;IACX;IACA,IAAIc,YAAY,GAAG,iCAAiC;IACpD,IAAIC,UAAyB,MAAM,oCAAoC;IAEvE,IAAMC,YAAY,IAAIC,8BAAS,CAAC;QAC9BD,WAAW,SAAXA,UAAYE,OAAeC,WAAmBC;YAC5C,uCAAuC;YACvC,IAAIC;YACJ,IAAIN,WAAWA,QAAQF,MAAM,GAAG,GAAG;gBACjCQ,OAAOC,OAAOC,MAAM,CAAC;oBAACR;oBAASG;iBAAM;YACvC,OAAO;gBACLG,OAAOH;YACT;YAEA,qDAAqD;YACrD,IAAIG,KAAKR,MAAM,GAAG,GAAG;gBACnBE,UAAUM;gBACVD,SAAS,MAAMI,IAAAA,gCAAW,EAAC;gBAC3B;YACF;YAEA,qBAAqB;YACrB,IAAMb,SAASC,IAAAA,+BAAU,EAACS;YAC1B,IAAMI,YAAYhC,QAAQC,OAAOoB,WAAW,OAAOH,QAAQA,OAAOE,MAAM;YAExE,IAAIY,cAAc,GAAG;gBACnB,6BAA6B;gBAC7BV,UAAUM;gBACVD,SAAS,MAAMI,IAAAA,gCAAW,EAAC;gBAC3B;YACF;YAEA,sDAAsD;YACtD,IAAME,SAASf,OAAOgB,KAAK,CAAC,GAAGF;YAC/BV,UAAUJ,OAAOgB,KAAK,CAACF;YACvBX,aAAaW;YAEbL,SAAS,MAAMM;QACjB;QACAE,OAAO,SAAPA,MAAuDR,QAAsC;YAC3F,qCAAqC;YACrC,IAAIL,WAAWA,QAAQF,MAAM,GAAG,GAAG;gBACjC,8DAA8D;gBAC9D,IAAI,CAACgB,IAAI,CAACd;YACZ;YACAK,SAAS;QACX;IACF;IAEA,OAAOJ;AACT"}
|
|
@@ -86,7 +86,7 @@ function createBcjArmDecoder(_properties, _unpackSize) {
|
|
|
86
86
|
var globalPos = 0; // Position in the overall stream (in bytes)
|
|
87
87
|
var pending = null; // Incomplete 4-byte group
|
|
88
88
|
var transform = new _extractbaseiterator.Transform({
|
|
89
|
-
transform: function(chunk, _encoding, callback) {
|
|
89
|
+
transform: function transform(chunk, _encoding, callback) {
|
|
90
90
|
// Combine pending bytes with new chunk
|
|
91
91
|
var data;
|
|
92
92
|
if (pending && pending.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/filters/bcj/BcjArm.ts"],"sourcesContent":["// BCJ (ARM 32-bit) filter codec - converts ARM branch instruction addresses\n// This filter makes ARM executables more compressible by LZMA\n//\n// ARM branch instructions (BL) use relative addressing. The filter converts\n// these to absolute addresses during compression, and back during decompression.\n//\n// Reference: https://github.com/tukaani-project/xz/blob/master/src/liblzma/simple/arm.c\n//\n// This implementation uses true streaming - processes data chunk by chunk.\n\nimport { allocBuffer, bufferFrom, Transform } from 'extract-base-iterator';\n\n/**\n * Core ARM BCJ conversion function (matches reference arm_code)\n * Works for both encoding and decoding based on isEncoder flag\n *\n * ARM BL instruction format:\n * - 4 bytes aligned\n * - Byte pattern: XX XX XX EB (where EB = 0xEB opcode for BL)\n * - Lower 24 bits are signed offset (in words, not bytes)\n * - ARM pipeline adds +8 to the effective address\n *\n * @param nowPos - Current position in the overall stream\n * @param isEncoder - true for encoding, false for decoding\n * @param buffer - Buffer to process (modified in place)\n * @param size - Size of buffer\n * @returns Number of bytes processed\n */\nfunction armCode(nowPos: number, isEncoder: boolean, buffer: Buffer, size: number): number {\n // Only process complete 4-byte groups\n size = size & ~3;\n\n let i = 0;\n for (; i < size; i += 4) {\n // Check for BL instruction: byte 3 is 0xEB\n if (buffer[i + 3] === 0xeb) {\n // Read 24-bit value (little-endian in bytes 0-2)\n let src = (buffer[i + 2] << 16) | (buffer[i + 1] << 8) | buffer[i + 0];\n\n // Left shift by 2 (convert from words to bytes)\n src <<= 2;\n\n // Sign-extend from 26-bit to 32-bit\n if (src & 0x02000000) {\n src |= 0xfc000000;\n }\n src = src | 0; // Make signed 32-bit\n\n let dest: number;\n if (isEncoder) {\n // Encoding: relative to absolute\n // dest = now_pos + i + 8 + src\n dest = nowPos + i + 8 + src;\n } else {\n // Decoding: absolute to relative\n // dest = src - (now_pos + i + 8)\n dest = src - (nowPos + i + 8);\n }\n\n // Right shift by 2 (convert back from bytes to words)\n dest >>>= 2;\n\n // Write back lower 24 bits (little-endian)\n buffer[i + 2] = (dest >>> 16) & 0xff;\n buffer[i + 1] = (dest >>> 8) & 0xff;\n buffer[i + 0] = dest & 0xff;\n }\n }\n\n return i;\n}\n\n/**\n * Decode ARM BCJ filtered data (synchronous, for buffered use)\n * Reverses the BCJ transformation by converting absolute addresses back to relative\n *\n * @param input - ARM BCJ filtered data\n * @param _properties - Unused for ARM BCJ\n * @param _unpackSize - Unused for ARM BCJ\n * @returns Unfiltered data\n */\nexport function decodeBcjArm(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer {\n const output = bufferFrom(input); // Copy since we modify in place\n\n armCode(0, false, output, output.length);\n\n return output;\n}\n\n/**\n * Create a streaming ARM BCJ decoder Transform.\n * Processes data in 4-byte aligned chunks.\n */\nexport function createBcjArmDecoder(_properties?: Buffer, _unpackSize?: number): InstanceType<typeof Transform> {\n let globalPos = 0; // Position in the overall stream (in bytes)\n let pending: Buffer | null = null; // Incomplete 4-byte group\n\n const transform = new Transform({\n transform: (chunk: Buffer, _encoding: string, callback: (err?: Error | null, data?: Buffer) => void) => {\n // Combine pending bytes with new chunk\n let data: Buffer;\n if (pending && pending.length > 0) {\n data = Buffer.concat([pending, chunk]);\n } else {\n data = chunk;\n }\n\n // Process only complete 4-byte groups\n const completeBytes = data.length & ~3;\n if (completeBytes === 0) {\n pending = data;\n callback(null, allocBuffer(0));\n return;\n }\n\n const output = bufferFrom(data.slice(0, completeBytes));\n pending = data.length > completeBytes ? data.slice(completeBytes) : null;\n\n armCode(globalPos, false, output, output.length);\n globalPos += completeBytes;\n\n callback(null, output);\n },\n flush: function (this: InstanceType<typeof Transform>, callback: (err?: Error | null) => void) {\n if (pending && pending.length > 0) {\n this.push(pending);\n }\n callback(null);\n },\n });\n\n return transform;\n}\n"],"names":["createBcjArmDecoder","decodeBcjArm","armCode","nowPos","isEncoder","buffer","size","i","src","dest","input","_properties","_unpackSize","output","bufferFrom","length","globalPos","pending","transform","Transform","chunk","_encoding","callback","data","Buffer","concat","completeBytes","allocBuffer","slice","flush","push"],"mappings":"AAAA,4EAA4E;AAC5E,8DAA8D;AAC9D,EAAE;AACF,4EAA4E;AAC5E,iFAAiF;AACjF,EAAE;AACF,wFAAwF;AACxF,EAAE;AACF,2EAA2E;;;;;;;;;;;;QAqF3DA;eAAAA;;QAZAC;eAAAA;;;mCAvEmC;AAEnD;;;;;;;;;;;;;;;CAeC,GACD,SAASC,QAAQC,MAAc,EAAEC,SAAkB,EAAEC,MAAc,EAAEC,IAAY;IAC/E,sCAAsC;IACtCA,OAAOA,OAAO,CAAC;IAEf,IAAIC,IAAI;IACR,MAAOA,IAAID,MAAMC,KAAK,EAAG;QACvB,2CAA2C;QAC3C,IAAIF,MAAM,CAACE,IAAI,EAAE,KAAK,MAAM;YAC1B,iDAAiD;YACjD,IAAIC,MAAM,AAACH,MAAM,CAACE,IAAI,EAAE,IAAI,KAAOF,MAAM,CAACE,IAAI,EAAE,IAAI,IAAKF,MAAM,CAACE,IAAI,EAAE;YAEtE,gDAAgD;YAChDC,QAAQ;YAER,oCAAoC;YACpC,IAAIA,MAAM,YAAY;gBACpBA,OAAO;YACT;YACAA,MAAMA,MAAM,GAAG,qBAAqB;YAEpC,IAAIC,OAAAA,KAAAA;YACJ,IAAIL,WAAW;gBACb,iCAAiC;gBACjC,+BAA+B;gBAC/BK,OAAON,SAASI,IAAI,IAAIC;YAC1B,OAAO;gBACL,iCAAiC;gBACjC,iCAAiC;gBACjCC,OAAOD,MAAOL,CAAAA,SAASI,IAAI,CAAA;YAC7B;YAEA,sDAAsD;YACtDE,UAAU;YAEV,2CAA2C;YAC3CJ,MAAM,CAACE,IAAI,EAAE,GAAG,AAACE,SAAS,KAAM;YAChCJ,MAAM,CAACE,IAAI,EAAE,GAAG,AAACE,SAAS,IAAK;YAC/BJ,MAAM,CAACE,IAAI,EAAE,GAAGE,OAAO;QACzB;IACF;IAEA,OAAOF;AACT;AAWO,SAASN,aAAaS,KAAa,EAAEC,WAAoB,EAAEC,WAAoB;IACpF,IAAMC,SAASC,IAAAA,+BAAU,EAACJ,QAAQ,gCAAgC;IAElER,QAAQ,GAAG,OAAOW,QAAQA,OAAOE,MAAM;IAEvC,OAAOF;AACT;AAMO,SAASb,oBAAoBW,WAAoB,EAAEC,WAAoB;IAC5E,IAAII,YAAY,GAAG,4CAA4C;IAC/D,IAAIC,UAAyB,MAAM,0BAA0B;IAE7D,IAAMC,YAAY,IAAIC,8BAAS,CAAC;QAC9BD,WAAW,
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/filters/bcj/BcjArm.ts"],"sourcesContent":["// BCJ (ARM 32-bit) filter codec - converts ARM branch instruction addresses\n// This filter makes ARM executables more compressible by LZMA\n//\n// ARM branch instructions (BL) use relative addressing. The filter converts\n// these to absolute addresses during compression, and back during decompression.\n//\n// Reference: https://github.com/tukaani-project/xz/blob/master/src/liblzma/simple/arm.c\n//\n// This implementation uses true streaming - processes data chunk by chunk.\n\nimport { allocBuffer, bufferFrom, Transform } from 'extract-base-iterator';\n\n/**\n * Core ARM BCJ conversion function (matches reference arm_code)\n * Works for both encoding and decoding based on isEncoder flag\n *\n * ARM BL instruction format:\n * - 4 bytes aligned\n * - Byte pattern: XX XX XX EB (where EB = 0xEB opcode for BL)\n * - Lower 24 bits are signed offset (in words, not bytes)\n * - ARM pipeline adds +8 to the effective address\n *\n * @param nowPos - Current position in the overall stream\n * @param isEncoder - true for encoding, false for decoding\n * @param buffer - Buffer to process (modified in place)\n * @param size - Size of buffer\n * @returns Number of bytes processed\n */\nfunction armCode(nowPos: number, isEncoder: boolean, buffer: Buffer, size: number): number {\n // Only process complete 4-byte groups\n size = size & ~3;\n\n let i = 0;\n for (; i < size; i += 4) {\n // Check for BL instruction: byte 3 is 0xEB\n if (buffer[i + 3] === 0xeb) {\n // Read 24-bit value (little-endian in bytes 0-2)\n let src = (buffer[i + 2] << 16) | (buffer[i + 1] << 8) | buffer[i + 0];\n\n // Left shift by 2 (convert from words to bytes)\n src <<= 2;\n\n // Sign-extend from 26-bit to 32-bit\n if (src & 0x02000000) {\n src |= 0xfc000000;\n }\n src = src | 0; // Make signed 32-bit\n\n let dest: number;\n if (isEncoder) {\n // Encoding: relative to absolute\n // dest = now_pos + i + 8 + src\n dest = nowPos + i + 8 + src;\n } else {\n // Decoding: absolute to relative\n // dest = src - (now_pos + i + 8)\n dest = src - (nowPos + i + 8);\n }\n\n // Right shift by 2 (convert back from bytes to words)\n dest >>>= 2;\n\n // Write back lower 24 bits (little-endian)\n buffer[i + 2] = (dest >>> 16) & 0xff;\n buffer[i + 1] = (dest >>> 8) & 0xff;\n buffer[i + 0] = dest & 0xff;\n }\n }\n\n return i;\n}\n\n/**\n * Decode ARM BCJ filtered data (synchronous, for buffered use)\n * Reverses the BCJ transformation by converting absolute addresses back to relative\n *\n * @param input - ARM BCJ filtered data\n * @param _properties - Unused for ARM BCJ\n * @param _unpackSize - Unused for ARM BCJ\n * @returns Unfiltered data\n */\nexport function decodeBcjArm(input: Buffer, _properties?: Buffer, _unpackSize?: number): Buffer {\n const output = bufferFrom(input); // Copy since we modify in place\n\n armCode(0, false, output, output.length);\n\n return output;\n}\n\n/**\n * Create a streaming ARM BCJ decoder Transform.\n * Processes data in 4-byte aligned chunks.\n */\nexport function createBcjArmDecoder(_properties?: Buffer, _unpackSize?: number): InstanceType<typeof Transform> {\n let globalPos = 0; // Position in the overall stream (in bytes)\n let pending: Buffer | null = null; // Incomplete 4-byte group\n\n const transform = new Transform({\n transform: (chunk: Buffer, _encoding: string, callback: (err?: Error | null, data?: Buffer) => void) => {\n // Combine pending bytes with new chunk\n let data: Buffer;\n if (pending && pending.length > 0) {\n data = Buffer.concat([pending, chunk]);\n } else {\n data = chunk;\n }\n\n // Process only complete 4-byte groups\n const completeBytes = data.length & ~3;\n if (completeBytes === 0) {\n pending = data;\n callback(null, allocBuffer(0));\n return;\n }\n\n const output = bufferFrom(data.slice(0, completeBytes));\n pending = data.length > completeBytes ? data.slice(completeBytes) : null;\n\n armCode(globalPos, false, output, output.length);\n globalPos += completeBytes;\n\n callback(null, output);\n },\n flush: function (this: InstanceType<typeof Transform>, callback: (err?: Error | null) => void) {\n if (pending && pending.length > 0) {\n this.push(pending);\n }\n callback(null);\n },\n });\n\n return transform;\n}\n"],"names":["createBcjArmDecoder","decodeBcjArm","armCode","nowPos","isEncoder","buffer","size","i","src","dest","input","_properties","_unpackSize","output","bufferFrom","length","globalPos","pending","transform","Transform","chunk","_encoding","callback","data","Buffer","concat","completeBytes","allocBuffer","slice","flush","push"],"mappings":"AAAA,4EAA4E;AAC5E,8DAA8D;AAC9D,EAAE;AACF,4EAA4E;AAC5E,iFAAiF;AACjF,EAAE;AACF,wFAAwF;AACxF,EAAE;AACF,2EAA2E;;;;;;;;;;;;QAqF3DA;eAAAA;;QAZAC;eAAAA;;;mCAvEmC;AAEnD;;;;;;;;;;;;;;;CAeC,GACD,SAASC,QAAQC,MAAc,EAAEC,SAAkB,EAAEC,MAAc,EAAEC,IAAY;IAC/E,sCAAsC;IACtCA,OAAOA,OAAO,CAAC;IAEf,IAAIC,IAAI;IACR,MAAOA,IAAID,MAAMC,KAAK,EAAG;QACvB,2CAA2C;QAC3C,IAAIF,MAAM,CAACE,IAAI,EAAE,KAAK,MAAM;YAC1B,iDAAiD;YACjD,IAAIC,MAAM,AAACH,MAAM,CAACE,IAAI,EAAE,IAAI,KAAOF,MAAM,CAACE,IAAI,EAAE,IAAI,IAAKF,MAAM,CAACE,IAAI,EAAE;YAEtE,gDAAgD;YAChDC,QAAQ;YAER,oCAAoC;YACpC,IAAIA,MAAM,YAAY;gBACpBA,OAAO;YACT;YACAA,MAAMA,MAAM,GAAG,qBAAqB;YAEpC,IAAIC,OAAAA,KAAAA;YACJ,IAAIL,WAAW;gBACb,iCAAiC;gBACjC,+BAA+B;gBAC/BK,OAAON,SAASI,IAAI,IAAIC;YAC1B,OAAO;gBACL,iCAAiC;gBACjC,iCAAiC;gBACjCC,OAAOD,MAAOL,CAAAA,SAASI,IAAI,CAAA;YAC7B;YAEA,sDAAsD;YACtDE,UAAU;YAEV,2CAA2C;YAC3CJ,MAAM,CAACE,IAAI,EAAE,GAAG,AAACE,SAAS,KAAM;YAChCJ,MAAM,CAACE,IAAI,EAAE,GAAG,AAACE,SAAS,IAAK;YAC/BJ,MAAM,CAACE,IAAI,EAAE,GAAGE,OAAO;QACzB;IACF;IAEA,OAAOF;AACT;AAWO,SAASN,aAAaS,KAAa,EAAEC,WAAoB,EAAEC,WAAoB;IACpF,IAAMC,SAASC,IAAAA,+BAAU,EAACJ,QAAQ,gCAAgC;IAElER,QAAQ,GAAG,OAAOW,QAAQA,OAAOE,MAAM;IAEvC,OAAOF;AACT;AAMO,SAASb,oBAAoBW,WAAoB,EAAEC,WAAoB;IAC5E,IAAII,YAAY,GAAG,4CAA4C;IAC/D,IAAIC,UAAyB,MAAM,0BAA0B;IAE7D,IAAMC,YAAY,IAAIC,8BAAS,CAAC;QAC9BD,WAAW,SAAXA,UAAYE,OAAeC,WAAmBC;YAC5C,uCAAuC;YACvC,IAAIC;YACJ,IAAIN,WAAWA,QAAQF,MAAM,GAAG,GAAG;gBACjCQ,OAAOC,OAAOC,MAAM,CAAC;oBAACR;oBAASG;iBAAM;YACvC,OAAO;gBACLG,OAAOH;YACT;YAEA,sCAAsC;YACtC,IAAMM,gBAAgBH,KAAKR,MAAM,GAAG,CAAC;YACrC,IAAIW,kBAAkB,GAAG;gBACvBT,UAAUM;gBACVD,SAAS,MAAMK,IAAAA,gCAAW,EAAC;gBAC3B;YACF;YAEA,IAAMd,SAASC,IAAAA,+BAAU,EAACS,KAAKK,KAAK,CAAC,GAAGF;YACxCT,UAAUM,KAAKR,MAAM,GAAGW,gBAAgBH,KAAKK,KAAK,CAACF,iBAAiB;YAEpExB,QAAQc,WAAW,OAAOH,QAAQA,OAAOE,MAAM;YAC/CC,aAAaU;YAEbJ,SAAS,MAAMT;QACjB;QACAgB,OAAO,SAAPA,MAAuDP,QAAsC;YAC3F,IAAIL,WAAWA,QAAQF,MAAM,GAAG,GAAG;gBACjC,IAAI,CAACe,IAAI,CAACb;YACZ;YACAK,SAAS;QACX;IACF;IAEA,OAAOJ;AACT"}
|
|
@@ -59,7 +59,7 @@ function createDeltaDecoder(properties, _unpackSize) {
|
|
|
59
59
|
}
|
|
60
60
|
var byteIndex = 0;
|
|
61
61
|
return new _extractbaseiterator.Transform({
|
|
62
|
-
transform: function(chunk, _encoding, callback) {
|
|
62
|
+
transform: function transform(chunk, _encoding, callback) {
|
|
63
63
|
var output = (0, _extractbaseiterator.allocBuffer)(chunk.length);
|
|
64
64
|
for(var j = 0; j < chunk.length; j++){
|
|
65
65
|
var idx = byteIndex % distance;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/filters/delta/Delta.ts"],"sourcesContent":["// Delta filter codec - stores differences between consecutive bytes\n// Useful for data with gradual changes (images, audio, sensor data)\n//\n// The Delta filter stores the difference between each byte and the byte\n// N positions before it, where N is the \"distance\" parameter (default 1).\n// This makes data with regular patterns more compressible.\n//\n// This implementation uses true streaming - processes data chunk by chunk\n// while maintaining state between chunks.\n\nimport { allocBuffer, bufferFrom, Transform } from 'extract-base-iterator';\n\n/**\n * Decode Delta filtered data (synchronous, for buffered use)\n * Reverses the delta transformation by adding previous values\n *\n * @param input - Delta filtered data\n * @param properties - Optional 1-byte properties (distance - 1)\n * @param _unpackSize - Unused for Delta\n * @returns Unfiltered data\n */\nexport function decodeDelta(input: Buffer, properties?: Buffer, _unpackSize?: number): Buffer {\n // Distance parameter: default is 1\n let distance = 1;\n if (properties && properties.length >= 1) {\n // Properties byte contains (distance - 1)\n distance = properties[0] + 1;\n }\n\n const output = bufferFrom(input); // Copy since we modify in place\n\n // State buffer for multi-byte distance\n const state: number[] = [];\n for (let i = 0; i < distance; i++) {\n state.push(0);\n }\n\n for (let j = 0; j < output.length; j++) {\n const idx = j % distance;\n state[idx] = (state[idx] + output[j]) & 0xff;\n output[j] = state[idx];\n }\n\n return output;\n}\n\n/**\n * Create a streaming Delta decoder Transform.\n * Processes data chunk by chunk, maintaining state between chunks.\n */\nexport function createDeltaDecoder(properties?: Buffer, _unpackSize?: number): InstanceType<typeof Transform> {\n // Distance parameter: default is 1\n let distance = 1;\n if (properties && properties.length >= 1) {\n distance = properties[0] + 1;\n }\n\n // State buffer for multi-byte distance\n const state: number[] = [];\n for (let i = 0; i < distance; i++) {\n state.push(0);\n }\n\n let byteIndex = 0;\n\n return new Transform({\n transform: (chunk: Buffer, _encoding: string, callback: (err?: Error | null, data?: Buffer) => void) => {\n const output = allocBuffer(chunk.length);\n\n for (let j = 0; j < chunk.length; j++) {\n const idx = byteIndex % distance;\n state[idx] = (state[idx] + chunk[j]) & 0xff;\n output[j] = state[idx];\n byteIndex++;\n }\n\n callback(null, output);\n },\n });\n}\n"],"names":["createDeltaDecoder","decodeDelta","input","properties","_unpackSize","distance","length","output","bufferFrom","state","i","push","j","idx","byteIndex","Transform","transform","chunk","_encoding","callback","allocBuffer"],"mappings":"AAAA,oEAAoE;AACpE,oEAAoE;AACpE,EAAE;AACF,wEAAwE;AACxE,0EAA0E;AAC1E,2DAA2D;AAC3D,EAAE;AACF,0EAA0E;AAC1E,0CAA0C;;;;;;;;;;;;QA0C1BA;eAAAA;;QA7BAC;eAAAA;;;mCAXmC;AAW5C,SAASA,YAAYC,KAAa,EAAEC,UAAmB,EAAEC,WAAoB;IAClF,mCAAmC;IACnC,IAAIC,WAAW;IACf,IAAIF,cAAcA,WAAWG,MAAM,IAAI,GAAG;QACxC,0CAA0C;QAC1CD,WAAWF,UAAU,CAAC,EAAE,GAAG;IAC7B;IAEA,IAAMI,SAASC,IAAAA,+BAAU,EAACN,QAAQ,gCAAgC;IAElE,uCAAuC;IACvC,IAAMO,QAAkB,EAAE;IAC1B,IAAK,IAAIC,IAAI,GAAGA,IAAIL,UAAUK,IAAK;QACjCD,MAAME,IAAI,CAAC;IACb;IAEA,IAAK,IAAIC,IAAI,GAAGA,IAAIL,OAAOD,MAAM,EAAEM,IAAK;QACtC,IAAMC,MAAMD,IAAIP;QAChBI,KAAK,CAACI,IAAI,GAAG,AAACJ,KAAK,CAACI,IAAI,GAAGN,MAAM,CAACK,EAAE,GAAI;QACxCL,MAAM,CAACK,EAAE,GAAGH,KAAK,CAACI,IAAI;IACxB;IAEA,OAAON;AACT;AAMO,SAASP,mBAAmBG,UAAmB,EAAEC,WAAoB;IAC1E,mCAAmC;IACnC,IAAIC,WAAW;IACf,IAAIF,cAAcA,WAAWG,MAAM,IAAI,GAAG;QACxCD,WAAWF,UAAU,CAAC,EAAE,GAAG;IAC7B;IAEA,uCAAuC;IACvC,IAAMM,QAAkB,EAAE;IAC1B,IAAK,IAAIC,IAAI,GAAGA,IAAIL,UAAUK,IAAK;QACjCD,MAAME,IAAI,CAAC;IACb;IAEA,IAAIG,YAAY;IAEhB,OAAO,IAAIC,8BAAS,CAAC;QACnBC,WAAW,
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/filters/delta/Delta.ts"],"sourcesContent":["// Delta filter codec - stores differences between consecutive bytes\n// Useful for data with gradual changes (images, audio, sensor data)\n//\n// The Delta filter stores the difference between each byte and the byte\n// N positions before it, where N is the \"distance\" parameter (default 1).\n// This makes data with regular patterns more compressible.\n//\n// This implementation uses true streaming - processes data chunk by chunk\n// while maintaining state between chunks.\n\nimport { allocBuffer, bufferFrom, Transform } from 'extract-base-iterator';\n\n/**\n * Decode Delta filtered data (synchronous, for buffered use)\n * Reverses the delta transformation by adding previous values\n *\n * @param input - Delta filtered data\n * @param properties - Optional 1-byte properties (distance - 1)\n * @param _unpackSize - Unused for Delta\n * @returns Unfiltered data\n */\nexport function decodeDelta(input: Buffer, properties?: Buffer, _unpackSize?: number): Buffer {\n // Distance parameter: default is 1\n let distance = 1;\n if (properties && properties.length >= 1) {\n // Properties byte contains (distance - 1)\n distance = properties[0] + 1;\n }\n\n const output = bufferFrom(input); // Copy since we modify in place\n\n // State buffer for multi-byte distance\n const state: number[] = [];\n for (let i = 0; i < distance; i++) {\n state.push(0);\n }\n\n for (let j = 0; j < output.length; j++) {\n const idx = j % distance;\n state[idx] = (state[idx] + output[j]) & 0xff;\n output[j] = state[idx];\n }\n\n return output;\n}\n\n/**\n * Create a streaming Delta decoder Transform.\n * Processes data chunk by chunk, maintaining state between chunks.\n */\nexport function createDeltaDecoder(properties?: Buffer, _unpackSize?: number): InstanceType<typeof Transform> {\n // Distance parameter: default is 1\n let distance = 1;\n if (properties && properties.length >= 1) {\n distance = properties[0] + 1;\n }\n\n // State buffer for multi-byte distance\n const state: number[] = [];\n for (let i = 0; i < distance; i++) {\n state.push(0);\n }\n\n let byteIndex = 0;\n\n return new Transform({\n transform: (chunk: Buffer, _encoding: string, callback: (err?: Error | null, data?: Buffer) => void) => {\n const output = allocBuffer(chunk.length);\n\n for (let j = 0; j < chunk.length; j++) {\n const idx = byteIndex % distance;\n state[idx] = (state[idx] + chunk[j]) & 0xff;\n output[j] = state[idx];\n byteIndex++;\n }\n\n callback(null, output);\n },\n });\n}\n"],"names":["createDeltaDecoder","decodeDelta","input","properties","_unpackSize","distance","length","output","bufferFrom","state","i","push","j","idx","byteIndex","Transform","transform","chunk","_encoding","callback","allocBuffer"],"mappings":"AAAA,oEAAoE;AACpE,oEAAoE;AACpE,EAAE;AACF,wEAAwE;AACxE,0EAA0E;AAC1E,2DAA2D;AAC3D,EAAE;AACF,0EAA0E;AAC1E,0CAA0C;;;;;;;;;;;;QA0C1BA;eAAAA;;QA7BAC;eAAAA;;;mCAXmC;AAW5C,SAASA,YAAYC,KAAa,EAAEC,UAAmB,EAAEC,WAAoB;IAClF,mCAAmC;IACnC,IAAIC,WAAW;IACf,IAAIF,cAAcA,WAAWG,MAAM,IAAI,GAAG;QACxC,0CAA0C;QAC1CD,WAAWF,UAAU,CAAC,EAAE,GAAG;IAC7B;IAEA,IAAMI,SAASC,IAAAA,+BAAU,EAACN,QAAQ,gCAAgC;IAElE,uCAAuC;IACvC,IAAMO,QAAkB,EAAE;IAC1B,IAAK,IAAIC,IAAI,GAAGA,IAAIL,UAAUK,IAAK;QACjCD,MAAME,IAAI,CAAC;IACb;IAEA,IAAK,IAAIC,IAAI,GAAGA,IAAIL,OAAOD,MAAM,EAAEM,IAAK;QACtC,IAAMC,MAAMD,IAAIP;QAChBI,KAAK,CAACI,IAAI,GAAG,AAACJ,KAAK,CAACI,IAAI,GAAGN,MAAM,CAACK,EAAE,GAAI;QACxCL,MAAM,CAACK,EAAE,GAAGH,KAAK,CAACI,IAAI;IACxB;IAEA,OAAON;AACT;AAMO,SAASP,mBAAmBG,UAAmB,EAAEC,WAAoB;IAC1E,mCAAmC;IACnC,IAAIC,WAAW;IACf,IAAIF,cAAcA,WAAWG,MAAM,IAAI,GAAG;QACxCD,WAAWF,UAAU,CAAC,EAAE,GAAG;IAC7B;IAEA,uCAAuC;IACvC,IAAMM,QAAkB,EAAE;IAC1B,IAAK,IAAIC,IAAI,GAAGA,IAAIL,UAAUK,IAAK;QACjCD,MAAME,IAAI,CAAC;IACb;IAEA,IAAIG,YAAY;IAEhB,OAAO,IAAIC,8BAAS,CAAC;QACnBC,WAAW,SAAXA,UAAYC,OAAeC,WAAmBC;YAC5C,IAAMZ,SAASa,IAAAA,gCAAW,EAACH,MAAMX,MAAM;YAEvC,IAAK,IAAIM,IAAI,GAAGA,IAAIK,MAAMX,MAAM,EAAEM,IAAK;gBACrC,IAAMC,MAAMC,YAAYT;gBACxBI,KAAK,CAACI,IAAI,GAAG,AAACJ,KAAK,CAACI,IAAI,GAAGI,KAAK,CAACL,EAAE,GAAI;gBACvCL,MAAM,CAACK,EAAE,GAAGH,KAAK,CAACI,IAAI;gBACtBC;YACF;YAEAK,SAAS,MAAMZ;QACjB;IACF;AACF"}
|
|
@@ -130,7 +130,7 @@ function createLzma2Decoder(properties) {
|
|
|
130
130
|
// Enhanced: Use OutputSink for direct emission (zero-copy)
|
|
131
131
|
// Create a decoder with direct stream emission
|
|
132
132
|
var streamDecoder = new _LzmaDecoderts.LzmaDecoder({
|
|
133
|
-
write: function(chunk) {
|
|
133
|
+
write: function write(chunk) {
|
|
134
134
|
return _this.push(chunk);
|
|
135
135
|
}
|
|
136
136
|
});
|
|
@@ -187,7 +187,7 @@ function createLzmaDecoder(properties, unpackSize) {
|
|
|
187
187
|
// Enhanced: Use OutputSink for direct emission (zero-copy)
|
|
188
188
|
// Create a decoder with direct stream emission
|
|
189
189
|
var streamDecoder = new _LzmaDecoderts.LzmaDecoder({
|
|
190
|
-
write: function(chunk) {
|
|
190
|
+
write: function write(chunk) {
|
|
191
191
|
return _this.push(chunk);
|
|
192
192
|
}
|
|
193
193
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/lzma/stream/transforms.ts"],"sourcesContent":["/**\n * LZMA Transform Stream Wrappers\n *\n * Provides Transform streams for LZMA1 and LZMA2 decompression.\n *\n * LZMA2 streaming works by buffering until a complete chunk is available,\n * then decoding synchronously. LZMA2 chunks are bounded in size (~2MB max\n * uncompressed), so memory usage is predictable and bounded.\n *\n * Performance Optimization:\n * - Uses OutputSink pattern for zero-copy output during decode\n * - Each decoded byte written directly to stream (not buffered then copied)\n * - ~4x faster than previous buffering approach\n *\n * True byte-by-byte async LZMA streaming would require rewriting the entire\n * decoder with continuation-passing style, which is complex and not worth\n * the effort given LZMA2's chunked format.\n */\n\nimport { allocBufferUnsafe, Transform } from 'extract-base-iterator';\nimport { hasCompleteChunk } from '../lib/Lzma2ChunkParser.ts';\nimport { LzmaDecoder } from '../sync/LzmaDecoder.ts';\nimport { parseLzma2DictionarySize } from '../types.ts';\n\n/**\n * Create an LZMA2 decoder Transform stream\n *\n * This is a streaming decoder that processes LZMA2 chunks incrementally.\n * Memory usage is O(dictionary_size + max_chunk_size) instead of O(folder_size).\n *\n * @param properties - 1-byte LZMA2 properties (dictionary size)\n * @returns Transform stream that decompresses LZMA2 data\n */\nexport function createLzma2Decoder(properties: Buffer | Uint8Array): InstanceType<typeof Transform> {\n if (!properties || properties.length < 1) {\n throw new Error('LZMA2 requires properties byte');\n }\n\n const dictSize = parseLzma2DictionarySize(properties[0]);\n\n // LZMA decoder instance - reused across chunks for solid mode\n const decoder = new LzmaDecoder();\n decoder.setDictionarySize(dictSize);\n\n // Track current LZMA properties\n let propsSet = false;\n\n // Store lc/lp/pb for reuse in stream decoder\n let currentLc: number | undefined;\n let currentLp: number | undefined;\n let currentPb: number | undefined;\n\n // Buffer for incomplete chunk data\n let pending: Buffer | null = null;\n let finished = false;\n\n return new Transform({\n transform: function (this: InstanceType<typeof Transform>, chunk: Buffer, _encoding: string, callback: (err?: Error | null) => void) {\n if (finished) {\n callback(null);\n return;\n }\n\n // Combine with pending data\n let input: Buffer;\n if (pending && pending.length > 0) {\n input = Buffer.concat([pending, chunk]);\n pending = null;\n } else {\n input = chunk;\n }\n\n let offset = 0;\n\n try {\n while (offset < input.length && !finished) {\n const result = hasCompleteChunk(input, offset);\n\n if (!result.success) {\n // Need more data\n pending = input.slice(offset);\n break;\n }\n\n const { chunk: chunkInfo, totalSize } = result;\n\n if (chunkInfo.type === 'end') {\n finished = true;\n break;\n }\n\n // Handle dictionary reset\n if (chunkInfo.dictReset) {\n decoder.resetDictionary();\n }\n\n const dataOffset = offset + chunkInfo.headerSize;\n\n if (chunkInfo.type === 'uncompressed') {\n const uncompData = input.slice(dataOffset, dataOffset + chunkInfo.uncompSize);\n this.push(uncompData);\n\n // Feed uncompressed data to dictionary for subsequent LZMA chunks\n decoder.feedUncompressed(uncompData);\n } else {\n // LZMA compressed chunk\n\n // Variables to store properties (used for both decoders)\n let lc: number;\n let lp: number;\n let pb: number;\n\n // Apply new properties if present\n if (chunkInfo.newProps) {\n ({ lc, lp, pb } = chunkInfo.newProps);\n // Store properties for reuse in stream decoder\n currentLc = lc;\n currentLp = lp;\n currentPb = pb;\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 } else {\n // No new properties, check if we already have them\n if (!propsSet) {\n throw new Error('LZMA chunk without properties');\n }\n }\n\n // Reset probabilities if state reset\n if (chunkInfo.stateReset) {\n decoder.resetProbabilities();\n }\n\n // Determine solid mode - preserve dictionary if not resetting state or if only resetting state (not dict)\n const useSolid = !chunkInfo.stateReset || (chunkInfo.stateReset && !chunkInfo.dictReset);\n\n const compData = input.slice(dataOffset, dataOffset + chunkInfo.compSize);\n\n // Enhanced: Use OutputSink for direct emission (zero-copy)\n // Create a decoder with direct stream emission\n const streamDecoder = new LzmaDecoder({\n write: (chunk: Buffer) => this.push(chunk),\n });\n streamDecoder.setDictionarySize(dictSize);\n // Set properties from current values (from first chunk or newProps)\n if (currentLc !== undefined && currentLp !== undefined && currentPb !== undefined) {\n streamDecoder.setLcLpPb(currentLc, currentLp, currentPb);\n }\n\n // Use solid mode based on chunk properties\n streamDecoder.decodeWithSink(compData, 0, chunkInfo.uncompSize, useSolid);\n\n // Flush any remaining data in the OutWindow\n streamDecoder.flushOutWindow();\n }\n\n offset += totalSize;\n }\n\n callback(null);\n } catch (err) {\n callback(err as Error);\n }\n },\n\n flush: function (this: InstanceType<typeof Transform>, callback: (err?: Error | null) => void) {\n if (pending && pending.length > 0 && !finished) {\n callback(new Error('Truncated LZMA2 stream'));\n } else {\n callback(null);\n }\n },\n });\n}\n\n/**\n * Create an LZMA1 decoder Transform stream\n *\n * Note: LZMA1 has no chunk boundaries, so this requires knowing the\n * uncompressed size upfront. The stream buffers all input, then\n * decompresses when complete.\n *\n * For true streaming, use LZMA2 which has built-in chunking.\n *\n * Optimization: Pre-allocates input buffer and copies chunks once,\n * avoiding the double-buffering of Buffer.concat().\n *\n * @param properties - 5-byte LZMA properties\n * @param unpackSize - Expected uncompressed size\n * @returns Transform stream that decompresses LZMA1 data\n */\nexport function createLzmaDecoder(properties: Buffer | Uint8Array, unpackSize: number): InstanceType<typeof Transform> {\n const decoder = new LzmaDecoder();\n decoder.setDecoderProperties(properties);\n\n const chunks: Buffer[] = [];\n let totalSize = 0;\n\n return new Transform({\n transform: function (this: InstanceType<typeof Transform>, chunk: Buffer, _encoding: string, callback: (err?: Error | null) => void) {\n chunks.push(chunk);\n totalSize += chunk.length;\n callback(null);\n },\n\n flush: function (this: InstanceType<typeof Transform>, callback: (err?: Error | null) => void) {\n try {\n // Optimization: Pre-allocate single buffer instead of Buffer.concat()\n // This reduces peak memory usage by ~50% during concatenation\n const input = allocBufferUnsafe(totalSize);\n let offset = 0;\n\n // Copy each chunk into the pre-allocated buffer\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n chunk.copy(input, offset);\n offset += chunk.length;\n }\n\n // Enhanced: Use OutputSink for direct emission (zero-copy)\n // Create a decoder with direct stream emission\n const streamDecoder = new LzmaDecoder({\n write: (chunk: Buffer) => this.push(chunk),\n });\n streamDecoder.setDecoderProperties(properties);\n streamDecoder.decodeWithSink(input, 0, unpackSize, false);\n\n // Flush any remaining data in the OutWindow\n streamDecoder.flushOutWindow();\n\n callback(null);\n } catch (err) {\n callback(err as Error);\n }\n },\n });\n}\n"],"names":["createLzma2Decoder","createLzmaDecoder","properties","length","Error","dictSize","parseLzma2DictionarySize","decoder","LzmaDecoder","setDictionarySize","propsSet","currentLc","currentLp","currentPb","pending","finished","Transform","transform","chunk","_encoding","callback","input","Buffer","concat","offset","result","hasCompleteChunk","success","slice","chunkInfo","totalSize","type","dictReset","resetDictionary","dataOffset","headerSize","uncompData","uncompSize","push","feedUncompressed","lc","lp","pb","newProps","setLcLpPb","stateReset","resetProbabilities","useSolid","compData","compSize","streamDecoder","write","undefined","decodeWithSink","flushOutWindow","err","flush","unpackSize","setDecoderProperties","chunks","allocBufferUnsafe","i","copy"],"mappings":"AAAA;;;;;;;;;;;;;;;;;CAiBC;;;;;;;;;;;QAgBeA;eAAAA;;QAgKAC;eAAAA;;;mCA9K6B;kCACZ;6BACL;uBACa;AAWlC,SAASD,mBAAmBE,UAA+B;IAChE,IAAI,CAACA,cAAcA,WAAWC,MAAM,GAAG,GAAG;QACxC,MAAM,IAAIC,MAAM;IAClB;IAEA,IAAMC,WAAWC,IAAAA,iCAAwB,EAACJ,UAAU,CAAC,EAAE;IAEvD,8DAA8D;IAC9D,IAAMK,UAAU,IAAIC,0BAAW;IAC/BD,QAAQE,iBAAiB,CAACJ;IAE1B,gCAAgC;IAChC,IAAIK,WAAW;IAEf,6CAA6C;IAC7C,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IAEJ,mCAAmC;IACnC,IAAIC,UAAyB;IAC7B,IAAIC,WAAW;IAEf,OAAO,IAAIC,8BAAS,CAAC;QACnBC,WAAW,SAAXA,UAA2DC,KAAa,EAAEC,SAAiB,EAAEC,QAAsC;;YACjI,IAAIL,UAAU;gBACZK,SAAS;gBACT;YACF;YAEA,4BAA4B;YAC5B,IAAIC;YACJ,IAAIP,WAAWA,QAAQX,MAAM,GAAG,GAAG;gBACjCkB,QAAQC,OAAOC,MAAM,CAAC;oBAACT;oBAASI;iBAAM;gBACtCJ,UAAU;YACZ,OAAO;gBACLO,QAAQH;YACV;YAEA,IAAIM,SAAS;YAEb,IAAI;gBACF,MAAOA,SAASH,MAAMlB,MAAM,IAAI,CAACY,SAAU;oBACzC,IAAMU,SAASC,IAAAA,oCAAgB,EAACL,OAAOG;oBAEvC,IAAI,CAACC,OAAOE,OAAO,EAAE;wBACnB,iBAAiB;wBACjBb,UAAUO,MAAMO,KAAK,CAACJ;wBACtB;oBACF;oBAEA,IAAQN,AAAOW,YAAyBJ,OAAhCP,OAAkBY,YAAcL,OAAdK;oBAE1B,IAAID,UAAUE,IAAI,KAAK,OAAO;wBAC5BhB,WAAW;wBACX;oBACF;oBAEA,0BAA0B;oBAC1B,IAAIc,UAAUG,SAAS,EAAE;wBACvBzB,QAAQ0B,eAAe;oBACzB;oBAEA,IAAMC,aAAaV,SAASK,UAAUM,UAAU;oBAEhD,IAAIN,UAAUE,IAAI,KAAK,gBAAgB;wBACrC,IAAMK,aAAaf,MAAMO,KAAK,CAACM,YAAYA,aAAaL,UAAUQ,UAAU;wBAC5E,IAAI,CAACC,IAAI,CAACF;wBAEV,kEAAkE;wBAClE7B,QAAQgC,gBAAgB,CAACH;oBAC3B,OAAO;wBACL,wBAAwB;wBAExB,yDAAyD;wBACzD,IAAII,KAAAA,KAAAA;wBACJ,IAAIC,KAAAA,KAAAA;wBACJ,IAAIC,KAAAA,KAAAA;wBAEJ,kCAAkC;wBAClC,IAAIb,UAAUc,QAAQ,EAAE;;kCACJd,UAAUc,QAAQ,EAAjCH,SAAAA,IAAIC,SAAAA,IAAIC,SAAAA;4BACX,+CAA+C;4BAC/C/B,YAAY6B;4BACZ5B,YAAY6B;4BACZ5B,YAAY6B;4BACZ,IAAI,CAACnC,QAAQqC,SAAS,CAACJ,IAAIC,IAAIC,KAAK;gCAClC,MAAM,IAAItC,MAAM,AAAC,+BAAuCqC,OAATD,IAAG,QAAeE,OAATD,IAAG,QAAS,OAAHC;4BACnE;4BACAhC,WAAW;wBACb,OAAO;4BACL,mDAAmD;4BACnD,IAAI,CAACA,UAAU;gCACb,MAAM,IAAIN,MAAM;4BAClB;wBACF;wBAEA,qCAAqC;wBACrC,IAAIyB,UAAUgB,UAAU,EAAE;4BACxBtC,QAAQuC,kBAAkB;wBAC5B;wBAEA,0GAA0G;wBAC1G,IAAMC,WAAW,CAAClB,UAAUgB,UAAU,IAAKhB,UAAUgB,UAAU,IAAI,CAAChB,UAAUG,SAAS;wBAEvF,IAAMgB,WAAW3B,MAAMO,KAAK,CAACM,YAAYA,aAAaL,UAAUoB,QAAQ;wBAExE,2DAA2D;wBAC3D,+CAA+C;wBAC/C,IAAMC,gBAAgB,IAAI1C,0BAAW,CAAC;4BACpC2C,OAAO,SAACjC;uCAAkB,MAAKoB,IAAI,CAACpB;;wBACtC;wBACAgC,cAAczC,iBAAiB,CAACJ;wBAChC,oEAAoE;wBACpE,IAAIM,cAAcyC,aAAaxC,cAAcwC,aAAavC,cAAcuC,WAAW;4BACjFF,cAAcN,SAAS,CAACjC,WAAWC,WAAWC;wBAChD;wBAEA,2CAA2C;wBAC3CqC,cAAcG,cAAc,CAACL,UAAU,GAAGnB,UAAUQ,UAAU,EAAEU;wBAEhE,4CAA4C;wBAC5CG,cAAcI,cAAc;oBAC9B;oBAEA9B,UAAUM;gBACZ;gBAEAV,SAAS;YACX,EAAE,OAAOmC,KAAK;gBACZnC,SAASmC;YACX;QACF;QAEAC,OAAO,SAAPA,MAAuDpC,QAAsC;YAC3F,IAAIN,WAAWA,QAAQX,MAAM,GAAG,KAAK,CAACY,UAAU;gBAC9CK,SAAS,IAAIhB,MAAM;YACrB,OAAO;gBACLgB,SAAS;YACX;QACF;IACF;AACF;AAkBO,SAASnB,kBAAkBC,UAA+B,EAAEuD,UAAkB;IACnF,IAAMlD,UAAU,IAAIC,0BAAW;IAC/BD,QAAQmD,oBAAoB,CAACxD;IAE7B,IAAMyD,SAAmB,EAAE;IAC3B,IAAI7B,YAAY;IAEhB,OAAO,IAAId,8BAAS,CAAC;QACnBC,WAAW,SAAXA,UAA2DC,KAAa,EAAEC,SAAiB,EAAEC,QAAsC;YACjIuC,OAAOrB,IAAI,CAACpB;YACZY,aAAaZ,MAAMf,MAAM;YACzBiB,SAAS;QACX;QAEAoC,OAAO,SAAPA,MAAuDpC,QAAsC;;YAC3F,IAAI;gBACF,sEAAsE;gBACtE,8DAA8D;gBAC9D,IAAMC,QAAQuC,IAAAA,sCAAiB,EAAC9B;gBAChC,IAAIN,SAAS;gBAEb,gDAAgD;gBAChD,IAAK,IAAIqC,IAAI,GAAGA,IAAIF,OAAOxD,MAAM,EAAE0D,IAAK;oBACtC,IAAM3C,QAAQyC,MAAM,CAACE,EAAE;oBACvB3C,MAAM4C,IAAI,CAACzC,OAAOG;oBAClBA,UAAUN,MAAMf,MAAM;gBACxB;gBAEA,2DAA2D;gBAC3D,+CAA+C;gBAC/C,IAAM+C,gBAAgB,IAAI1C,0BAAW,CAAC;oBACpC2C,OAAO,SAACjC;+BAAkB,MAAKoB,IAAI,CAACpB;;gBACtC;gBACAgC,cAAcQ,oBAAoB,CAACxD;gBACnCgD,cAAcG,cAAc,CAAChC,OAAO,GAAGoC,YAAY;gBAEnD,4CAA4C;gBAC5CP,cAAcI,cAAc;gBAE5BlC,SAAS;YACX,EAAE,OAAOmC,KAAK;gBACZnC,SAASmC;YACX;QACF;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/lzma/stream/transforms.ts"],"sourcesContent":["/**\n * LZMA Transform Stream Wrappers\n *\n * Provides Transform streams for LZMA1 and LZMA2 decompression.\n *\n * LZMA2 streaming works by buffering until a complete chunk is available,\n * then decoding synchronously. LZMA2 chunks are bounded in size (~2MB max\n * uncompressed), so memory usage is predictable and bounded.\n *\n * Performance Optimization:\n * - Uses OutputSink pattern for zero-copy output during decode\n * - Each decoded byte written directly to stream (not buffered then copied)\n * - ~4x faster than previous buffering approach\n *\n * True byte-by-byte async LZMA streaming would require rewriting the entire\n * decoder with continuation-passing style, which is complex and not worth\n * the effort given LZMA2's chunked format.\n */\n\nimport { allocBufferUnsafe, Transform } from 'extract-base-iterator';\nimport { hasCompleteChunk } from '../lib/Lzma2ChunkParser.ts';\nimport { LzmaDecoder } from '../sync/LzmaDecoder.ts';\nimport { parseLzma2DictionarySize } from '../types.ts';\n\n/**\n * Create an LZMA2 decoder Transform stream\n *\n * This is a streaming decoder that processes LZMA2 chunks incrementally.\n * Memory usage is O(dictionary_size + max_chunk_size) instead of O(folder_size).\n *\n * @param properties - 1-byte LZMA2 properties (dictionary size)\n * @returns Transform stream that decompresses LZMA2 data\n */\nexport function createLzma2Decoder(properties: Buffer | Uint8Array): InstanceType<typeof Transform> {\n if (!properties || properties.length < 1) {\n throw new Error('LZMA2 requires properties byte');\n }\n\n const dictSize = parseLzma2DictionarySize(properties[0]);\n\n // LZMA decoder instance - reused across chunks for solid mode\n const decoder = new LzmaDecoder();\n decoder.setDictionarySize(dictSize);\n\n // Track current LZMA properties\n let propsSet = false;\n\n // Store lc/lp/pb for reuse in stream decoder\n let currentLc: number | undefined;\n let currentLp: number | undefined;\n let currentPb: number | undefined;\n\n // Buffer for incomplete chunk data\n let pending: Buffer | null = null;\n let finished = false;\n\n return new Transform({\n transform: function (this: InstanceType<typeof Transform>, chunk: Buffer, _encoding: string, callback: (err?: Error | null) => void) {\n if (finished) {\n callback(null);\n return;\n }\n\n // Combine with pending data\n let input: Buffer;\n if (pending && pending.length > 0) {\n input = Buffer.concat([pending, chunk]);\n pending = null;\n } else {\n input = chunk;\n }\n\n let offset = 0;\n\n try {\n while (offset < input.length && !finished) {\n const result = hasCompleteChunk(input, offset);\n\n if (!result.success) {\n // Need more data\n pending = input.slice(offset);\n break;\n }\n\n const { chunk: chunkInfo, totalSize } = result;\n\n if (chunkInfo.type === 'end') {\n finished = true;\n break;\n }\n\n // Handle dictionary reset\n if (chunkInfo.dictReset) {\n decoder.resetDictionary();\n }\n\n const dataOffset = offset + chunkInfo.headerSize;\n\n if (chunkInfo.type === 'uncompressed') {\n const uncompData = input.slice(dataOffset, dataOffset + chunkInfo.uncompSize);\n this.push(uncompData);\n\n // Feed uncompressed data to dictionary for subsequent LZMA chunks\n decoder.feedUncompressed(uncompData);\n } else {\n // LZMA compressed chunk\n\n // Variables to store properties (used for both decoders)\n let lc: number;\n let lp: number;\n let pb: number;\n\n // Apply new properties if present\n if (chunkInfo.newProps) {\n ({ lc, lp, pb } = chunkInfo.newProps);\n // Store properties for reuse in stream decoder\n currentLc = lc;\n currentLp = lp;\n currentPb = pb;\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 } else {\n // No new properties, check if we already have them\n if (!propsSet) {\n throw new Error('LZMA chunk without properties');\n }\n }\n\n // Reset probabilities if state reset\n if (chunkInfo.stateReset) {\n decoder.resetProbabilities();\n }\n\n // Determine solid mode - preserve dictionary if not resetting state or if only resetting state (not dict)\n const useSolid = !chunkInfo.stateReset || (chunkInfo.stateReset && !chunkInfo.dictReset);\n\n const compData = input.slice(dataOffset, dataOffset + chunkInfo.compSize);\n\n // Enhanced: Use OutputSink for direct emission (zero-copy)\n // Create a decoder with direct stream emission\n const streamDecoder = new LzmaDecoder({\n write: (chunk: Buffer) => this.push(chunk),\n });\n streamDecoder.setDictionarySize(dictSize);\n // Set properties from current values (from first chunk or newProps)\n if (currentLc !== undefined && currentLp !== undefined && currentPb !== undefined) {\n streamDecoder.setLcLpPb(currentLc, currentLp, currentPb);\n }\n\n // Use solid mode based on chunk properties\n streamDecoder.decodeWithSink(compData, 0, chunkInfo.uncompSize, useSolid);\n\n // Flush any remaining data in the OutWindow\n streamDecoder.flushOutWindow();\n }\n\n offset += totalSize;\n }\n\n callback(null);\n } catch (err) {\n callback(err as Error);\n }\n },\n\n flush: function (this: InstanceType<typeof Transform>, callback: (err?: Error | null) => void) {\n if (pending && pending.length > 0 && !finished) {\n callback(new Error('Truncated LZMA2 stream'));\n } else {\n callback(null);\n }\n },\n });\n}\n\n/**\n * Create an LZMA1 decoder Transform stream\n *\n * Note: LZMA1 has no chunk boundaries, so this requires knowing the\n * uncompressed size upfront. The stream buffers all input, then\n * decompresses when complete.\n *\n * For true streaming, use LZMA2 which has built-in chunking.\n *\n * Optimization: Pre-allocates input buffer and copies chunks once,\n * avoiding the double-buffering of Buffer.concat().\n *\n * @param properties - 5-byte LZMA properties\n * @param unpackSize - Expected uncompressed size\n * @returns Transform stream that decompresses LZMA1 data\n */\nexport function createLzmaDecoder(properties: Buffer | Uint8Array, unpackSize: number): InstanceType<typeof Transform> {\n const decoder = new LzmaDecoder();\n decoder.setDecoderProperties(properties);\n\n const chunks: Buffer[] = [];\n let totalSize = 0;\n\n return new Transform({\n transform: function (this: InstanceType<typeof Transform>, chunk: Buffer, _encoding: string, callback: (err?: Error | null) => void) {\n chunks.push(chunk);\n totalSize += chunk.length;\n callback(null);\n },\n\n flush: function (this: InstanceType<typeof Transform>, callback: (err?: Error | null) => void) {\n try {\n // Optimization: Pre-allocate single buffer instead of Buffer.concat()\n // This reduces peak memory usage by ~50% during concatenation\n const input = allocBufferUnsafe(totalSize);\n let offset = 0;\n\n // Copy each chunk into the pre-allocated buffer\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i];\n chunk.copy(input, offset);\n offset += chunk.length;\n }\n\n // Enhanced: Use OutputSink for direct emission (zero-copy)\n // Create a decoder with direct stream emission\n const streamDecoder = new LzmaDecoder({\n write: (chunk: Buffer) => this.push(chunk),\n });\n streamDecoder.setDecoderProperties(properties);\n streamDecoder.decodeWithSink(input, 0, unpackSize, false);\n\n // Flush any remaining data in the OutWindow\n streamDecoder.flushOutWindow();\n\n callback(null);\n } catch (err) {\n callback(err as Error);\n }\n },\n });\n}\n"],"names":["createLzma2Decoder","createLzmaDecoder","properties","length","Error","dictSize","parseLzma2DictionarySize","decoder","LzmaDecoder","setDictionarySize","propsSet","currentLc","currentLp","currentPb","pending","finished","Transform","transform","chunk","_encoding","callback","input","Buffer","concat","offset","result","hasCompleteChunk","success","slice","chunkInfo","totalSize","type","dictReset","resetDictionary","dataOffset","headerSize","uncompData","uncompSize","push","feedUncompressed","lc","lp","pb","newProps","setLcLpPb","stateReset","resetProbabilities","useSolid","compData","compSize","streamDecoder","write","undefined","decodeWithSink","flushOutWindow","err","flush","unpackSize","setDecoderProperties","chunks","allocBufferUnsafe","i","copy"],"mappings":"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"}
|
package/dist/cjs/native.js
CHANGED
|
@@ -49,7 +49,7 @@ var NATIVE_PREBUILDS = [
|
|
|
49
49
|
// Cache for native module loading result
|
|
50
50
|
var nativeModule = null;
|
|
51
51
|
var installationAttempted = false;
|
|
52
|
-
var sizeMismatchError = function(expected, actual) {
|
|
52
|
+
var sizeMismatchError = function sizeMismatchError(expected, actual) {
|
|
53
53
|
return new Error("Native decode size mismatch (expected ".concat(expected, ", got ").concat(actual, ")"));
|
|
54
54
|
};
|
|
55
55
|
function collectStream(stream, input, expectedSize) {
|
|
@@ -87,7 +87,7 @@ function createRawDecoder(lzma, filterId, buildOptions) {
|
|
|
87
87
|
function createNativeModule(bindings) {
|
|
88
88
|
return {
|
|
89
89
|
xz: {
|
|
90
|
-
decompress: function(input) {
|
|
90
|
+
decompress: function decompress(input) {
|
|
91
91
|
return bindings.decompress(input);
|
|
92
92
|
}
|
|
93
93
|
},
|
|
@@ -115,7 +115,7 @@ function tryLoadNative() {
|
|
|
115
115
|
if (nativeDisabled) return null;
|
|
116
116
|
if (major < 14) return null;
|
|
117
117
|
if (NATIVE_PREBUILDS.indexOf("".concat(process.platform, "-").concat(process.arch)) < 0) return null; // only supported prebuilds (or else tries to build from source on install)
|
|
118
|
-
var load = function() {
|
|
118
|
+
var load = function load() {
|
|
119
119
|
try {
|
|
120
120
|
var bindings = _require('lzma-native');
|
|
121
121
|
nativeModule = createNativeModule(bindings);
|
package/dist/cjs/native.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/native.ts"],"sourcesContent":["/**\n * Native Acceleration Module\n *\n * Provides optional native acceleration via lzma-native on Node.js 10+.\n * Falls back gracefully to pure JS implementation on older Node versions\n * or when the native module is not available.\n */\n\nimport Module from 'module';\nimport path from 'path';\nimport url from 'url';\n\nimport { parseLzma2DictionarySize, parseProperties } from './lzma/types.ts';\n\n// Get __dirname for ES modules\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\nconst __dirname = path.dirname(typeof __filename !== 'undefined' ? __filename : url.fileURLToPath(import.meta.url));\n\n// Get node_modules path (go up from dist/cjs to package root, then to node_modules)\nconst nodeModulesPath = path.join(__dirname, '..', '..', 'node_modules');\nconst major = +process.versions.node.split('.')[0];\n\nconst nativeDisabled = process.env.LZMA_NATIVE_DISABLE === '1';\nconst NATIVE_PREBUILDS = ['darwin-arm64', 'darwin-x64', 'linux-arm64', 'linux-x64', 'win32-ia32', 'win32-x64'];\n\n// Cache for native module loading result\nlet nativeModule: NativeModule | null = null;\nlet installationAttempted = false;\n\ninterface NativeDecoderMethods {\n decompress(input: Buffer): Promise<Buffer>;\n}\n\ntype RawDecoder = (input: Buffer, properties: Buffer, unpackSize?: number) => Promise<Buffer>;\n\nexport interface NativeModule {\n xz?: NativeDecoderMethods;\n lzma?: RawDecoder;\n lzma2?: RawDecoder;\n}\n\ninterface LzmaNativeExports {\n decompress(input: Buffer, options?: unknown): Promise<Buffer>;\n createStream(coder?: string | Record<string, unknown>, options?: Record<string, unknown>): NodeJS.ReadWriteStream;\n FILTER_LZMA1: string;\n FILTER_LZMA2: string;\n}\n\ninterface RawFilterOptions {\n dictSize: number;\n lc?: number;\n lp?: number;\n pb?: number;\n}\n\nconst sizeMismatchError = (expected: number, actual: number): Error => new Error(`Native decode size mismatch (expected ${expected}, got ${actual})`);\n\nfunction collectStream(stream: NodeJS.ReadWriteStream, input: Buffer, expectedSize?: number): Promise<Buffer> {\n return new Promise<Buffer>((resolve, reject) => {\n const chunks: Buffer[] = [];\n\n stream.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n stream.once('error', reject);\n stream.once('end', () => {\n const output = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks);\n if (typeof expectedSize === 'number' && expectedSize >= 0 && output.length !== expectedSize) {\n reject(sizeMismatchError(expectedSize, output.length));\n return;\n }\n resolve(output);\n });\n\n stream.end(input);\n });\n}\n\nfunction createRawDecoder(lzma: LzmaNativeExports, filterId: string, buildOptions: (properties: Buffer) => RawFilterOptions): RawDecoder {\n return (input, properties, unpackSize) => {\n const filters = [\n {\n id: filterId,\n options: buildOptions(properties),\n },\n ];\n const stream = lzma.createStream('rawDecoder', { filters });\n return collectStream(stream, input, unpackSize);\n };\n}\n\nfunction createNativeModule(bindings: LzmaNativeExports): NativeModule {\n return {\n xz: {\n decompress: (input) => bindings.decompress(input),\n },\n lzma: createRawDecoder(bindings, bindings.FILTER_LZMA1, (properties) => {\n if (!properties || properties.length < 5) throw new Error('LZMA requires 5-byte properties');\n const { lc, lp, pb, dictionarySize } = parseProperties(properties);\n return {\n dictSize: dictionarySize,\n lc,\n lp,\n pb,\n };\n }),\n lzma2: createRawDecoder(bindings, bindings.FILTER_LZMA2, (properties) => {\n if (!properties || properties.length < 1) throw new Error('LZMA2 requires properties byte');\n return {\n dictSize: parseLzma2DictionarySize(properties[0]),\n };\n }),\n };\n}\n\n/**\n * Try to load the native lzma-native module\n * Returns null if not available or Node version is too old\n */\nexport function tryLoadNative(): NativeModule | null {\n if (installationAttempted) return nativeModule;\n installationAttempted = true;\n if (nativeDisabled) return null;\n if (major < 14) return null;\n if (NATIVE_PREBUILDS.indexOf(`${process.platform}-${process.arch}`) < 0) return null; // only supported prebuilds (or else tries to build from source on install)\n\n const load = (): NativeModule | null => {\n try {\n const bindings = _require('lzma-native') as LzmaNativeExports;\n nativeModule = createNativeModule(bindings);\n return nativeModule;\n } catch {\n return null;\n }\n };\n\n const loaded = load();\n if (loaded) return loaded;\n\n try {\n console.log('Installing lzma-native for native acceleration...');\n const installModule = _require('install-module-linked').default;\n installModule.sync('lzma-native', nodeModulesPath, {});\n return load();\n } catch {\n return null;\n }\n}\n\nexport function isNativeAvailable(): boolean {\n return tryLoadNative() !== null;\n}\n"],"names":["isNativeAvailable","tryLoadNative","_require","require","Module","createRequire","__dirname","path","dirname","__filename","url","fileURLToPath","nodeModulesPath","join","major","process","versions","node","split","nativeDisabled","env","LZMA_NATIVE_DISABLE","NATIVE_PREBUILDS","nativeModule","installationAttempted","sizeMismatchError","expected","actual","Error","collectStream","stream","input","expectedSize","Promise","resolve","reject","chunks","on","chunk","push","once","output","length","Buffer","concat","end","createRawDecoder","lzma","filterId","buildOptions","properties","unpackSize","filters","id","options","createStream","createNativeModule","bindings","xz","decompress","FILTER_LZMA1","parseProperties","lc","lp","pb","dictionarySize","dictSize","lzma2","FILTER_LZMA2","parseLzma2DictionarySize","indexOf","platform","arch","load","loaded","console","log","installModule","default","sync"],"mappings":"AAAA;;;;;;CAMC;;;;;;;;;;;QA+IeA;eAAAA;;QA9BAC;eAAAA;;;6DA/GG;2DACF;0DACD;uBAE0C;;;;;;AAE1D,+BAA+B;AAC/B,IAAMC,WAAW,OAAOC,YAAY,cAAcC,eAAM,CAACC,aAAa,CAAC,uDAAmBF;AAC1F,IAAMG,YAAYC,aAAI,CAACC,OAAO,CAAC,OAAOC,eAAe,cAAcA,aAAaC,YAAG,CAACC,aAAa,CAAC;AAElG,oFAAoF;AACpF,IAAMC,kBAAkBL,aAAI,CAACM,IAAI,CAACP,WAAW,MAAM,MAAM;AACzD,IAAMQ,QAAQ,CAACC,QAAQC,QAAQ,CAACC,IAAI,CAACC,KAAK,CAAC,IAAI,CAAC,EAAE;AAElD,IAAMC,iBAAiBJ,QAAQK,GAAG,CAACC,mBAAmB,KAAK;AAC3D,IAAMC,mBAAmB;IAAC;IAAgB;IAAc;IAAe;IAAa;IAAc;CAAY;AAE9G,yCAAyC;AACzC,IAAIC,eAAoC;AACxC,IAAIC,wBAAwB;AA4B5B,IAAMC,oBAAoB,
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/native.ts"],"sourcesContent":["/**\n * Native Acceleration Module\n *\n * Provides optional native acceleration via lzma-native on Node.js 10+.\n * Falls back gracefully to pure JS implementation on older Node versions\n * or when the native module is not available.\n */\n\nimport Module from 'module';\nimport path from 'path';\nimport url from 'url';\n\nimport { parseLzma2DictionarySize, parseProperties } from './lzma/types.ts';\n\n// Get __dirname for ES modules\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\nconst __dirname = path.dirname(typeof __filename !== 'undefined' ? __filename : url.fileURLToPath(import.meta.url));\n\n// Get node_modules path (go up from dist/cjs to package root, then to node_modules)\nconst nodeModulesPath = path.join(__dirname, '..', '..', 'node_modules');\nconst major = +process.versions.node.split('.')[0];\n\nconst nativeDisabled = process.env.LZMA_NATIVE_DISABLE === '1';\nconst NATIVE_PREBUILDS = ['darwin-arm64', 'darwin-x64', 'linux-arm64', 'linux-x64', 'win32-ia32', 'win32-x64'];\n\n// Cache for native module loading result\nlet nativeModule: NativeModule | null = null;\nlet installationAttempted = false;\n\ninterface NativeDecoderMethods {\n decompress(input: Buffer): Promise<Buffer>;\n}\n\ntype RawDecoder = (input: Buffer, properties: Buffer, unpackSize?: number) => Promise<Buffer>;\n\nexport interface NativeModule {\n xz?: NativeDecoderMethods;\n lzma?: RawDecoder;\n lzma2?: RawDecoder;\n}\n\ninterface LzmaNativeExports {\n decompress(input: Buffer, options?: unknown): Promise<Buffer>;\n createStream(coder?: string | Record<string, unknown>, options?: Record<string, unknown>): NodeJS.ReadWriteStream;\n FILTER_LZMA1: string;\n FILTER_LZMA2: string;\n}\n\ninterface RawFilterOptions {\n dictSize: number;\n lc?: number;\n lp?: number;\n pb?: number;\n}\n\nconst sizeMismatchError = (expected: number, actual: number): Error => new Error(`Native decode size mismatch (expected ${expected}, got ${actual})`);\n\nfunction collectStream(stream: NodeJS.ReadWriteStream, input: Buffer, expectedSize?: number): Promise<Buffer> {\n return new Promise<Buffer>((resolve, reject) => {\n const chunks: Buffer[] = [];\n\n stream.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n stream.once('error', reject);\n stream.once('end', () => {\n const output = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks);\n if (typeof expectedSize === 'number' && expectedSize >= 0 && output.length !== expectedSize) {\n reject(sizeMismatchError(expectedSize, output.length));\n return;\n }\n resolve(output);\n });\n\n stream.end(input);\n });\n}\n\nfunction createRawDecoder(lzma: LzmaNativeExports, filterId: string, buildOptions: (properties: Buffer) => RawFilterOptions): RawDecoder {\n return (input, properties, unpackSize) => {\n const filters = [\n {\n id: filterId,\n options: buildOptions(properties),\n },\n ];\n const stream = lzma.createStream('rawDecoder', { filters });\n return collectStream(stream, input, unpackSize);\n };\n}\n\nfunction createNativeModule(bindings: LzmaNativeExports): NativeModule {\n return {\n xz: {\n decompress: (input) => bindings.decompress(input),\n },\n lzma: createRawDecoder(bindings, bindings.FILTER_LZMA1, (properties) => {\n if (!properties || properties.length < 5) throw new Error('LZMA requires 5-byte properties');\n const { lc, lp, pb, dictionarySize } = parseProperties(properties);\n return {\n dictSize: dictionarySize,\n lc,\n lp,\n pb,\n };\n }),\n lzma2: createRawDecoder(bindings, bindings.FILTER_LZMA2, (properties) => {\n if (!properties || properties.length < 1) throw new Error('LZMA2 requires properties byte');\n return {\n dictSize: parseLzma2DictionarySize(properties[0]),\n };\n }),\n };\n}\n\n/**\n * Try to load the native lzma-native module\n * Returns null if not available or Node version is too old\n */\nexport function tryLoadNative(): NativeModule | null {\n if (installationAttempted) return nativeModule;\n installationAttempted = true;\n if (nativeDisabled) return null;\n if (major < 14) return null;\n if (NATIVE_PREBUILDS.indexOf(`${process.platform}-${process.arch}`) < 0) return null; // only supported prebuilds (or else tries to build from source on install)\n\n const load = (): NativeModule | null => {\n try {\n const bindings = _require('lzma-native') as LzmaNativeExports;\n nativeModule = createNativeModule(bindings);\n return nativeModule;\n } catch {\n return null;\n }\n };\n\n const loaded = load();\n if (loaded) return loaded;\n\n try {\n console.log('Installing lzma-native for native acceleration...');\n const installModule = _require('install-module-linked').default;\n installModule.sync('lzma-native', nodeModulesPath, {});\n return load();\n } catch {\n return null;\n }\n}\n\nexport function isNativeAvailable(): boolean {\n return tryLoadNative() !== null;\n}\n"],"names":["isNativeAvailable","tryLoadNative","_require","require","Module","createRequire","__dirname","path","dirname","__filename","url","fileURLToPath","nodeModulesPath","join","major","process","versions","node","split","nativeDisabled","env","LZMA_NATIVE_DISABLE","NATIVE_PREBUILDS","nativeModule","installationAttempted","sizeMismatchError","expected","actual","Error","collectStream","stream","input","expectedSize","Promise","resolve","reject","chunks","on","chunk","push","once","output","length","Buffer","concat","end","createRawDecoder","lzma","filterId","buildOptions","properties","unpackSize","filters","id","options","createStream","createNativeModule","bindings","xz","decompress","FILTER_LZMA1","parseProperties","lc","lp","pb","dictionarySize","dictSize","lzma2","FILTER_LZMA2","parseLzma2DictionarySize","indexOf","platform","arch","load","loaded","console","log","installModule","default","sync"],"mappings":"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"}
|
package/dist/cjs/sevenz.js
CHANGED
|
@@ -51,8 +51,8 @@ var schedule = typeof setImmediate === 'function' ? setImmediate : function(fn)
|
|
|
51
51
|
return process.nextTick(fn);
|
|
52
52
|
};
|
|
53
53
|
function decode7zLzma(data, properties, unpackSize, callback) {
|
|
54
|
-
var worker = function(cb) {
|
|
55
|
-
var fallback = function() {
|
|
54
|
+
var worker = function worker(cb) {
|
|
55
|
+
var fallback = function fallback() {
|
|
56
56
|
schedule(function() {
|
|
57
57
|
try {
|
|
58
58
|
cb(null, (0, _LzmaDecoderts.decodeLzma)(data, properties, unpackSize));
|
|
@@ -87,8 +87,8 @@ function decode7zLzma(data, properties, unpackSize, callback) {
|
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
89
|
function decode7zLzma2(data, properties, unpackSize, callback) {
|
|
90
|
-
var worker = function(cb) {
|
|
91
|
-
var fallback = function() {
|
|
90
|
+
var worker = function worker(cb) {
|
|
91
|
+
var fallback = function fallback() {
|
|
92
92
|
schedule(function() {
|
|
93
93
|
try {
|
|
94
94
|
cb(null, (0, _Lzma2Decoderts.decodeLzma2)(data, properties, unpackSize));
|
package/dist/cjs/sevenz.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/sevenz.ts"],"sourcesContent":["/**\n * High-Level 7z-Specific Decoders\n *\n * These functions accept properties separately (matching 7z format structure)\n * and execute either the native lzma-native path or the pure JS fallback.\n *\n * This provides automatic native acceleration for 7z files while maintaining\n * the API that 7z-iterator expects.\n *\n * IMPORTANT: Buffer Management Pattern\n *\n * ❌ SLOW - DO NOT use OutputSink with buffering:\n * const chunks: Buffer[] = [];\n * decodeLzma2(data, props, size, { write: c => chunks.push(c) });\n * return Buffer.concat(chunks); // ← 3 copies: push + concat + return\n *\n * OutWindow → chunks.push(chunk) → Buffer.concat(chunks) → result\n * COPY TO ARRAY COPY ALL FINAL BUFFER\n *\n * ✅ FAST - Direct return (let decoder manage buffer):\n * return decodeLzma2(data, props, size) as Buffer; // ← 1 copy\n *\n * OutWindow → pre-allocated buffer → result\n * DIRECT WRITE\n *\n * The decodeLzma2() function internally pre-allocates the exact output size\n * and writes directly to it. Wrapping with an OutputSink that buffers to an\n * array defeats this optimization by creating unnecessary intermediate copies.\n */\n\nimport type { BufferLike } from 'extract-base-iterator';\nimport { decodeLzma2 } from './lzma/sync/Lzma2Decoder.ts';\nimport { decodeLzma } from './lzma/sync/LzmaDecoder.ts';\nimport { tryLoadNative } from './native.ts';\n\n/** Callback for async decode operations: (error, result) => void */\nexport type DecodeCallback<T = Buffer> = (error: Error | null, result?: T) => void;\n\n/** Callback invoked when an async 7z decode completes */\nexport type SevenZDecodeCallback = DecodeCallback<Buffer>;\n\nconst schedule = typeof setImmediate === 'function' ? setImmediate : (fn: () => void) => process.nextTick(fn);\n\nexport function decode7zLzma(data: BufferLike, properties: Buffer, unpackSize: number, callback: SevenZDecodeCallback): void;\nexport function decode7zLzma(data: BufferLike, properties: Buffer, unpackSize: number): Promise<Buffer>;\n/**\n * Decode LZMA-compressed data from a 7z file\n */\nexport function decode7zLzma(data: BufferLike, properties: Buffer, unpackSize: number, callback?: SevenZDecodeCallback): Promise<Buffer> | void {\n const worker = (cb: SevenZDecodeCallback) => {\n const fallback = () => {\n schedule(() => {\n try {\n cb(null, decodeLzma(data, properties, unpackSize) as Buffer);\n } catch (err) {\n cb(err as Error);\n }\n });\n };\n\n const native = tryLoadNative();\n if (native?.lzma) {\n try {\n // Native lzma-native expects Buffer, convert if needed\n const buf = Buffer.isBuffer(data) ? data : data.toBuffer();\n const promise = native.lzma(buf, properties, unpackSize);\n if (promise && typeof promise.then === 'function') {\n promise.then((value) => cb(null, value), fallback);\n return;\n }\n } catch {\n // fall through to fallback\n }\n }\n fallback();\n };\n\n if (typeof callback === 'function') return worker(callback);\n return new Promise((resolve, reject) => worker((err, value) => (err ? reject(err) : resolve(value as Buffer))));\n}\n\n/**\n * Decode LZMA2-compressed data from a 7z file\n */\nexport function decode7zLzma2(data: BufferLike, properties: Buffer, unpackSize: number | undefined, callback: SevenZDecodeCallback): void;\nexport function decode7zLzma2(data: BufferLike, properties: Buffer, unpackSize?: number): Promise<Buffer>;\nexport function decode7zLzma2(data: BufferLike, properties: Buffer, unpackSize?: number, callback?: SevenZDecodeCallback): Promise<Buffer> | void {\n const worker = (cb: SevenZDecodeCallback) => {\n const fallback = () => {\n schedule(() => {\n try {\n cb(null, decodeLzma2(data, properties, unpackSize) as Buffer);\n } catch (err) {\n cb(err as Error);\n }\n });\n };\n\n const native = tryLoadNative();\n if (native?.lzma2) {\n try {\n // Native lzma-native expects Buffer, convert if needed\n const buf = Buffer.isBuffer(data) ? data : data.toBuffer();\n const promise = native.lzma2(buf, properties, unpackSize);\n if (promise && typeof promise.then === 'function') {\n promise.then((value) => cb(null, value), fallback);\n return;\n }\n } catch {\n // fall through to fallback\n }\n }\n fallback();\n };\n\n if (typeof callback === 'function') return worker(callback);\n return new Promise((resolve, reject) => worker((err, value) => (err ? reject(err) : resolve(value as Buffer))));\n}\n"],"names":["decode7zLzma","decode7zLzma2","schedule","setImmediate","fn","process","nextTick","data","properties","unpackSize","callback","worker","cb","fallback","decodeLzma","err","native","tryLoadNative","lzma","buf","Buffer","isBuffer","toBuffer","promise","then","value","Promise","resolve","reject","decodeLzma2","lzma2"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BC;;;;;;;;;;;QAoBeA;eAAAA;;QAsCAC;eAAAA;;;8BAvDY;6BACD;wBACG;AAQ9B,IAAMC,WAAW,OAAOC,iBAAiB,aAAaA,eAAe,SAACC;WAAmBC,QAAQC,QAAQ,CAACF;;AAOnG,SAASJ,aAAaO,IAAgB,EAAEC,UAAkB,EAAEC,UAAkB,EAAEC,QAA+B;IACpH,IAAMC,SAAS,
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/sevenz.ts"],"sourcesContent":["/**\n * High-Level 7z-Specific Decoders\n *\n * These functions accept properties separately (matching 7z format structure)\n * and execute either the native lzma-native path or the pure JS fallback.\n *\n * This provides automatic native acceleration for 7z files while maintaining\n * the API that 7z-iterator expects.\n *\n * IMPORTANT: Buffer Management Pattern\n *\n * ❌ SLOW - DO NOT use OutputSink with buffering:\n * const chunks: Buffer[] = [];\n * decodeLzma2(data, props, size, { write: c => chunks.push(c) });\n * return Buffer.concat(chunks); // ← 3 copies: push + concat + return\n *\n * OutWindow → chunks.push(chunk) → Buffer.concat(chunks) → result\n * COPY TO ARRAY COPY ALL FINAL BUFFER\n *\n * ✅ FAST - Direct return (let decoder manage buffer):\n * return decodeLzma2(data, props, size) as Buffer; // ← 1 copy\n *\n * OutWindow → pre-allocated buffer → result\n * DIRECT WRITE\n *\n * The decodeLzma2() function internally pre-allocates the exact output size\n * and writes directly to it. Wrapping with an OutputSink that buffers to an\n * array defeats this optimization by creating unnecessary intermediate copies.\n */\n\nimport type { BufferLike } from 'extract-base-iterator';\nimport { decodeLzma2 } from './lzma/sync/Lzma2Decoder.ts';\nimport { decodeLzma } from './lzma/sync/LzmaDecoder.ts';\nimport { tryLoadNative } from './native.ts';\n\n/** Callback for async decode operations: (error, result) => void */\nexport type DecodeCallback<T = Buffer> = (error: Error | null, result?: T) => void;\n\n/** Callback invoked when an async 7z decode completes */\nexport type SevenZDecodeCallback = DecodeCallback<Buffer>;\n\nconst schedule = typeof setImmediate === 'function' ? setImmediate : (fn: () => void) => process.nextTick(fn);\n\nexport function decode7zLzma(data: BufferLike, properties: Buffer, unpackSize: number, callback: SevenZDecodeCallback): void;\nexport function decode7zLzma(data: BufferLike, properties: Buffer, unpackSize: number): Promise<Buffer>;\n/**\n * Decode LZMA-compressed data from a 7z file\n */\nexport function decode7zLzma(data: BufferLike, properties: Buffer, unpackSize: number, callback?: SevenZDecodeCallback): Promise<Buffer> | void {\n const worker = (cb: SevenZDecodeCallback) => {\n const fallback = () => {\n schedule(() => {\n try {\n cb(null, decodeLzma(data, properties, unpackSize) as Buffer);\n } catch (err) {\n cb(err as Error);\n }\n });\n };\n\n const native = tryLoadNative();\n if (native?.lzma) {\n try {\n // Native lzma-native expects Buffer, convert if needed\n const buf = Buffer.isBuffer(data) ? data : data.toBuffer();\n const promise = native.lzma(buf, properties, unpackSize);\n if (promise && typeof promise.then === 'function') {\n promise.then((value) => cb(null, value), fallback);\n return;\n }\n } catch {\n // fall through to fallback\n }\n }\n fallback();\n };\n\n if (typeof callback === 'function') return worker(callback);\n return new Promise((resolve, reject) => worker((err, value) => (err ? reject(err) : resolve(value as Buffer))));\n}\n\n/**\n * Decode LZMA2-compressed data from a 7z file\n */\nexport function decode7zLzma2(data: BufferLike, properties: Buffer, unpackSize: number | undefined, callback: SevenZDecodeCallback): void;\nexport function decode7zLzma2(data: BufferLike, properties: Buffer, unpackSize?: number): Promise<Buffer>;\nexport function decode7zLzma2(data: BufferLike, properties: Buffer, unpackSize?: number, callback?: SevenZDecodeCallback): Promise<Buffer> | void {\n const worker = (cb: SevenZDecodeCallback) => {\n const fallback = () => {\n schedule(() => {\n try {\n cb(null, decodeLzma2(data, properties, unpackSize) as Buffer);\n } catch (err) {\n cb(err as Error);\n }\n });\n };\n\n const native = tryLoadNative();\n if (native?.lzma2) {\n try {\n // Native lzma-native expects Buffer, convert if needed\n const buf = Buffer.isBuffer(data) ? data : data.toBuffer();\n const promise = native.lzma2(buf, properties, unpackSize);\n if (promise && typeof promise.then === 'function') {\n promise.then((value) => cb(null, value), fallback);\n return;\n }\n } catch {\n // fall through to fallback\n }\n }\n fallback();\n };\n\n if (typeof callback === 'function') return worker(callback);\n return new Promise((resolve, reject) => worker((err, value) => (err ? reject(err) : resolve(value as Buffer))));\n}\n"],"names":["decode7zLzma","decode7zLzma2","schedule","setImmediate","fn","process","nextTick","data","properties","unpackSize","callback","worker","cb","fallback","decodeLzma","err","native","tryLoadNative","lzma","buf","Buffer","isBuffer","toBuffer","promise","then","value","Promise","resolve","reject","decodeLzma2","lzma2"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BC;;;;;;;;;;;QAoBeA;eAAAA;;QAsCAC;eAAAA;;;8BAvDY;6BACD;wBACG;AAQ9B,IAAMC,WAAW,OAAOC,iBAAiB,aAAaA,eAAe,SAACC;WAAmBC,QAAQC,QAAQ,CAACF;;AAOnG,SAASJ,aAAaO,IAAgB,EAAEC,UAAkB,EAAEC,UAAkB,EAAEC,QAA+B;IACpH,IAAMC,SAAS,gBAACC;QACd,IAAMC,WAAW;YACfX,SAAS;gBACP,IAAI;oBACFU,GAAG,MAAME,IAAAA,yBAAU,EAACP,MAAMC,YAAYC;gBACxC,EAAE,OAAOM,KAAK;oBACZH,GAAGG;gBACL;YACF;QACF;QAEA,IAAMC,SAASC,IAAAA,uBAAa;QAC5B,IAAID,mBAAAA,6BAAAA,OAAQE,IAAI,EAAE;YAChB,IAAI;gBACF,uDAAuD;gBACvD,IAAMC,MAAMC,OAAOC,QAAQ,CAACd,QAAQA,OAAOA,KAAKe,QAAQ;gBACxD,IAAMC,UAAUP,OAAOE,IAAI,CAACC,KAAKX,YAAYC;gBAC7C,IAAIc,WAAW,OAAOA,QAAQC,IAAI,KAAK,YAAY;oBACjDD,QAAQC,IAAI,CAAC,SAACC;+BAAUb,GAAG,MAAMa;uBAAQZ;oBACzC;gBACF;YACF,EAAE,eAAM;YACN,2BAA2B;YAC7B;QACF;QACAA;IACF;IAEA,IAAI,OAAOH,aAAa,YAAY,OAAOC,OAAOD;IAClD,OAAO,IAAIgB,QAAQ,SAACC,SAASC;eAAWjB,OAAO,SAACI,KAAKU;mBAAWV,MAAMa,OAAOb,OAAOY,QAAQF;;;AAC9F;AAOO,SAASxB,cAAcM,IAAgB,EAAEC,UAAkB,EAAEC,UAAmB,EAAEC,QAA+B;IACtH,IAAMC,SAAS,gBAACC;QACd,IAAMC,WAAW;YACfX,SAAS;gBACP,IAAI;oBACFU,GAAG,MAAMiB,IAAAA,2BAAW,EAACtB,MAAMC,YAAYC;gBACzC,EAAE,OAAOM,KAAK;oBACZH,GAAGG;gBACL;YACF;QACF;QAEA,IAAMC,SAASC,IAAAA,uBAAa;QAC5B,IAAID,mBAAAA,6BAAAA,OAAQc,KAAK,EAAE;YACjB,IAAI;gBACF,uDAAuD;gBACvD,IAAMX,MAAMC,OAAOC,QAAQ,CAACd,QAAQA,OAAOA,KAAKe,QAAQ;gBACxD,IAAMC,UAAUP,OAAOc,KAAK,CAACX,KAAKX,YAAYC;gBAC9C,IAAIc,WAAW,OAAOA,QAAQC,IAAI,KAAK,YAAY;oBACjDD,QAAQC,IAAI,CAAC,SAACC;+BAAUb,GAAG,MAAMa;uBAAQZ;oBACzC;gBACF;YACF,EAAE,eAAM;YACN,2BAA2B;YAC7B;QACF;QACAA;IACF;IAEA,IAAI,OAAOH,aAAa,YAAY,OAAOC,OAAOD;IAClD,OAAO,IAAIgB,QAAQ,SAACC,SAASC;eAAWjB,OAAO,SAACI,KAAKU;mBAAWV,MAAMa,OAAOb,OAAOY,QAAQF;;;AAC9F"}
|
|
@@ -18,7 +18,7 @@ function createBufferingDecoder(decodeFn, properties, unpackSize) {
|
|
|
18
18
|
var chunks = [];
|
|
19
19
|
var _totalSize = 0;
|
|
20
20
|
return new _extractbaseiterator.Transform({
|
|
21
|
-
transform: function(chunk, _encoding, callback) {
|
|
21
|
+
transform: function transform(chunk, _encoding, callback) {
|
|
22
22
|
chunks.push(chunk);
|
|
23
23
|
_totalSize += chunk.length;
|
|
24
24
|
callback();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/utils/createBufferingDecoder.ts"],"sourcesContent":["import { bufferFrom, Transform } from 'extract-base-iterator';\nimport type { Transform as TransformType } from 'stream';\n\ntype DecodeFn = (input: Buffer, properties?: Buffer, unpackSize?: number) => Buffer;\n\n/**\n * Helper to create a Transform stream from a synchronous decoder\n *\n * This buffers all input and applies the decoder when the stream ends.\n * This is suitable for codecs that don't support true streaming.\n */\nexport default function createBufferingDecoder(decodeFn: DecodeFn, properties?: Buffer, unpackSize?: number): InstanceType<typeof TransformType> {\n const chunks: Buffer[] = [];\n let _totalSize = 0;\n\n return new Transform({\n transform: (chunk: Buffer, _encoding: string, callback: (err?: Error | null, data?: Buffer) => void) => {\n chunks.push(chunk);\n _totalSize += chunk.length;\n callback();\n },\n flush: function (this: InstanceType<typeof TransformType>, callback: (err?: Error | null) => void) {\n try {\n // Concatenate all chunks\n const input = bufferFrom(Buffer.concat(chunks));\n // Decode using the synchronous decoder\n const output = decodeFn(input, properties, unpackSize);\n // Push the result\n this.push(output);\n callback();\n } catch (err) {\n callback(err as Error);\n }\n },\n });\n}\n"],"names":["createBufferingDecoder","decodeFn","properties","unpackSize","chunks","_totalSize","Transform","transform","chunk","_encoding","callback","push","length","flush","input","bufferFrom","Buffer","concat","output","err"],"mappings":";;;;+BAKA;;;;;CAKC,GACD;;;eAAwBA;;;mCAXc;AAWvB,SAASA,uBAAuBC,QAAkB,EAAEC,UAAmB,EAAEC,UAAmB;IACzG,IAAMC,SAAmB,EAAE;IAC3B,IAAIC,aAAa;IAEjB,OAAO,IAAIC,8BAAS,CAAC;QACnBC,WAAW,
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/src/utils/createBufferingDecoder.ts"],"sourcesContent":["import { bufferFrom, Transform } from 'extract-base-iterator';\nimport type { Transform as TransformType } from 'stream';\n\ntype DecodeFn = (input: Buffer, properties?: Buffer, unpackSize?: number) => Buffer;\n\n/**\n * Helper to create a Transform stream from a synchronous decoder\n *\n * This buffers all input and applies the decoder when the stream ends.\n * This is suitable for codecs that don't support true streaming.\n */\nexport default function createBufferingDecoder(decodeFn: DecodeFn, properties?: Buffer, unpackSize?: number): InstanceType<typeof TransformType> {\n const chunks: Buffer[] = [];\n let _totalSize = 0;\n\n return new Transform({\n transform: (chunk: Buffer, _encoding: string, callback: (err?: Error | null, data?: Buffer) => void) => {\n chunks.push(chunk);\n _totalSize += chunk.length;\n callback();\n },\n flush: function (this: InstanceType<typeof TransformType>, callback: (err?: Error | null) => void) {\n try {\n // Concatenate all chunks\n const input = bufferFrom(Buffer.concat(chunks));\n // Decode using the synchronous decoder\n const output = decodeFn(input, properties, unpackSize);\n // Push the result\n this.push(output);\n callback();\n } catch (err) {\n callback(err as Error);\n }\n },\n });\n}\n"],"names":["createBufferingDecoder","decodeFn","properties","unpackSize","chunks","_totalSize","Transform","transform","chunk","_encoding","callback","push","length","flush","input","bufferFrom","Buffer","concat","output","err"],"mappings":";;;;+BAKA;;;;;CAKC,GACD;;;eAAwBA;;;mCAXc;AAWvB,SAASA,uBAAuBC,QAAkB,EAAEC,UAAmB,EAAEC,UAAmB;IACzG,IAAMC,SAAmB,EAAE;IAC3B,IAAIC,aAAa;IAEjB,OAAO,IAAIC,8BAAS,CAAC;QACnBC,WAAW,SAAXA,UAAYC,OAAeC,WAAmBC;YAC5CN,OAAOO,IAAI,CAACH;YACZH,cAAcG,MAAMI,MAAM;YAC1BF;QACF;QACAG,OAAO,SAAPA,MAA2DH,QAAsC;YAC/F,IAAI;gBACF,yBAAyB;gBACzB,IAAMI,QAAQC,IAAAA,+BAAU,EAACC,OAAOC,MAAM,CAACb;gBACvC,uCAAuC;gBACvC,IAAMc,SAASjB,SAASa,OAAOZ,YAAYC;gBAC3C,kBAAkB;gBAClB,IAAI,CAACQ,IAAI,CAACO;gBACVR;YACF,EAAE,OAAOS,KAAK;gBACZT,SAASS;YACX;QACF;IACF;AACF"}
|
package/dist/cjs/xz/Decoder.js
CHANGED
|
@@ -218,7 +218,7 @@ var FILTER_LZMA2 = 0x21;
|
|
|
218
218
|
return input.readByte(offset);
|
|
219
219
|
};
|
|
220
220
|
// Local multibyte decoder using bound getByte
|
|
221
|
-
var decodeMultibyteLocal = function(offset) {
|
|
221
|
+
var decodeMultibyteLocal = function decodeMultibyteLocal(offset) {
|
|
222
222
|
var value = 0;
|
|
223
223
|
var i = 0;
|
|
224
224
|
var byte;
|
|
@@ -375,9 +375,9 @@ var FILTER_LZMA2 = 0x21;
|
|
|
375
375
|
return output;
|
|
376
376
|
}
|
|
377
377
|
function decodeXZ(input, callback) {
|
|
378
|
-
var worker = function(cb) {
|
|
378
|
+
var worker = function worker(cb) {
|
|
379
379
|
var _native_xz;
|
|
380
|
-
var fallback = function() {
|
|
380
|
+
var fallback = function fallback() {
|
|
381
381
|
try {
|
|
382
382
|
cb(null, decodeXZPure(input));
|
|
383
383
|
} catch (err) {
|
|
@@ -446,7 +446,7 @@ function createXZDecoder() {
|
|
|
446
446
|
} : function(offset) {
|
|
447
447
|
return input.readUInt32LEAt(offset);
|
|
448
448
|
};
|
|
449
|
-
var equals = function(offset, expected) {
|
|
449
|
+
var equals = function equals(offset, expected) {
|
|
450
450
|
if (offset + expected.length > input.length) return false;
|
|
451
451
|
for(var i = 0; i < expected.length; i++){
|
|
452
452
|
if (getByte(offset + i) !== expected[i]) return false;
|
|
@@ -494,11 +494,8 @@ function createXZDecoder() {
|
|
|
494
494
|
var blockRecords = parseIndex(input, indexStart, checkSize);
|
|
495
495
|
// Decompress blocks sequentially (native is async)
|
|
496
496
|
var blockIndex = 0;
|
|
497
|
-
var pushBlock = function(err) {
|
|
498
|
-
if (err)
|
|
499
|
-
callback(err);
|
|
500
|
-
return;
|
|
501
|
-
}
|
|
497
|
+
var pushBlock = function pushBlock1(err) {
|
|
498
|
+
if (err) return callback(err);
|
|
502
499
|
if (blockIndex >= blockRecords.length) {
|
|
503
500
|
// All blocks processed - purge input BufferList to free memory
|
|
504
501
|
if (!Buffer.isBuffer(input)) input.clear();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/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 * IMPORTANT: Buffer Management Pattern\n *\n * When calling decodeLzma2(), use the direct return pattern:\n *\n * ✅ CORRECT - Fast path:\n * const output = decodeLzma2(data, props, size) as Buffer;\n *\n * ❌ WRONG - Slow path (do NOT buffer):\n * const chunks: Buffer[] = [];\n * decodeLzma2(data, props, size, { write: c => chunks.push(c) });\n * return Buffer.concat(chunks); // ← Unnecessary copies!\n */\n\nimport { allocBuffer, type BufferLike, BufferList, Transform } from 'extract-base-iterator';\nimport type { Transform as TransformType } from 'stream';\nimport { decodeBcj } from '../filters/bcj/Bcj.ts';\nimport { decodeBcjArm } from '../filters/bcj/BcjArm.ts';\nimport { decodeBcjArm64 } from '../filters/bcj/BcjArm64.ts';\nimport { decodeBcjArmt } from '../filters/bcj/BcjArmt.ts';\nimport { decodeBcjIa64 } from '../filters/bcj/BcjIa64.ts';\nimport { decodeBcjPpc } from '../filters/bcj/BcjPpc.ts';\nimport { decodeBcjSparc } from '../filters/bcj/BcjSparc.ts';\nimport { decodeDelta } from '../filters/delta/Delta.ts';\nimport { decodeLzma2 } from '../lzma/index.ts';\nimport { tryLoadNative } from '../native.ts';\nimport type { DecodeCallback } from '../sevenz.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 (from XZ specification)\nconst FILTER_DELTA = 0x03;\nconst FILTER_BCJ_X86 = 0x04;\nconst FILTER_BCJ_PPC = 0x05;\nconst FILTER_BCJ_IA64 = 0x06;\nconst FILTER_BCJ_ARM = 0x07;\nconst FILTER_BCJ_ARMT = 0x08;\nconst FILTER_BCJ_SPARC = 0x09;\nconst FILTER_BCJ_ARM64 = 0x0a;\nconst FILTER_LZMA2 = 0x21;\n\n// Filter info for parsing\ninterface FilterInfo {\n id: number;\n props: Buffer;\n}\n\n// Re-export BufferLike for public API\nexport type { BufferLike } from 'extract-base-iterator';\n\n/**\n * Read a byte from Buffer or BufferList\n */\nfunction readByte(buf: BufferLike, offset: number): number {\n return Buffer.isBuffer(buf) ? buf[offset] : buf.readByte(offset);\n}\n\n/**\n * Read UInt32LE from Buffer or BufferList (returns null if out of bounds)\n */\nfunction readUInt32LE(buf: BufferLike, offset: number): number | null {\n if (Buffer.isBuffer(buf)) {\n if (offset < 0 || offset + 4 > buf.length) return null;\n return buf.readUInt32LE(offset);\n }\n return buf.readUInt32LEAt(offset);\n}\n\n/**\n * Compare buffer contents at offset with expected byte sequence\n * Works with both Buffer and BufferList\n */\nfunction bufferEquals(buf: BufferLike, 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 (readByte(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 * Works with both Buffer and BufferList\n */\nfunction decodeMultibyte(buf: BufferLike, 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 = readByte(buf, offset + i);\n value |= (byte & 0x7f) << (i * 7);\n i++;\n if (i > 4) {\n throw new Error('Multibyte integer too large');\n }\n } while (byte & 0x80);\n return { value, bytesRead: i };\n}\n\n/**\n * Apply a preprocessing filter (BCJ/Delta) to decompressed data\n */\nfunction applyFilter(data: Buffer, filter: FilterInfo): Buffer {\n switch (filter.id) {\n case FILTER_BCJ_X86:\n return decodeBcj(data, filter.props);\n case FILTER_BCJ_ARM:\n return decodeBcjArm(data, filter.props);\n case FILTER_BCJ_ARM64:\n return decodeBcjArm64(data, filter.props);\n case FILTER_BCJ_ARMT:\n return decodeBcjArmt(data, filter.props);\n case FILTER_BCJ_PPC:\n return decodeBcjPpc(data, filter.props);\n case FILTER_BCJ_SPARC:\n return decodeBcjSparc(data, filter.props);\n case FILTER_BCJ_IA64:\n return decodeBcjIa64(data, filter.props);\n case FILTER_DELTA:\n return decodeDelta(data, filter.props);\n default:\n throw new Error(`Unsupported filter: 0x${filter.id.toString(16)}`);\n }\n}\n\n/**\n * Parse XZ Block Header to extract filters and LZMA2 properties\n */\nfunction parseBlockHeader(\n input: Buffer,\n offset: number,\n _checkSize: number\n): {\n filters: FilterInfo[];\n lzma2Props: Buffer;\n headerSize: number;\n dataStart: number;\n dataEnd: number;\n nextOffset: number;\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\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 if (hasUncompressedSize) {\n const result = decodeMultibyte(input, offset);\n offset += result.bytesRead;\n }\n\n // Parse all filters\n const filters: FilterInfo[] = [];\n let lzma2Props: Buffer | null = null;\n\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 // LZMA2 must be the last filter\n lzma2Props = filterProps;\n } else if (filterId === FILTER_DELTA || (filterId >= FILTER_BCJ_X86 && filterId <= FILTER_BCJ_ARM64)) {\n // Preprocessing filter - store for later application\n filters.push({ id: filterId, props: filterProps });\n } else {\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 (must be aligned to 4 bytes)\n const blockDataStart = blockHeaderStart + blockHeaderSize;\n\n return {\n filters,\n lzma2Props,\n headerSize: blockHeaderSize,\n dataStart: blockDataStart,\n dataEnd: input.length,\n nextOffset: blockDataStart,\n };\n}\n\n/**\n * Parse XZ Index to get block positions\n * Works with both Buffer and BufferList\n */\nfunction parseIndex(\n input: BufferLike,\n indexStart: number,\n checkSize: number\n): Array<{\n compressedPos: number;\n compressedDataSize: number;\n uncompressedSize: number;\n}> {\n // One-time binding for buffer access (avoids repeated Buffer.isBuffer checks)\n const getByte = Buffer.isBuffer(input) ? (offset: number) => input[offset] : (offset: number) => input.readByte(offset);\n\n // Local multibyte decoder using bound getByte\n const decodeMultibyteLocal = (offset: number): { value: number; bytesRead: number } => {\n let value = 0;\n let i = 0;\n let byte: number;\n do {\n if (offset + i >= input.length) {\n throw new Error('Truncated multibyte integer');\n }\n byte = getByte(offset + i);\n value |= (byte & 0x7f) << (i * 7);\n i++;\n if (i > 4) {\n throw new Error('Multibyte integer too large');\n }\n } while (byte & 0x80);\n return { value, bytesRead: i };\n };\n\n let offset = indexStart;\n\n // Index indicator (0x00)\n if (getByte(offset) !== 0x00) {\n throw new Error('Invalid index indicator');\n }\n offset++;\n\n // Number of records\n const countResult = decodeMultibyteLocal(offset);\n const recordCount = countResult.value;\n offset += countResult.bytesRead;\n\n const records: Array<{\n compressedPos: number;\n unpaddedSize: number;\n compressedDataSize: number;\n uncompressedSize: number;\n }> = [];\n\n // Parse each record\n for (let i = 0; i < recordCount; i++) {\n // Unpadded Size (header + compressed data + check)\n const unpaddedResult = decodeMultibyteLocal(offset);\n offset += unpaddedResult.bytesRead;\n\n // Uncompressed size\n const uncompressedResult = decodeMultibyteLocal(offset);\n offset += uncompressedResult.bytesRead;\n\n records.push({\n compressedPos: 0, // will be calculated\n unpaddedSize: unpaddedResult.value,\n compressedDataSize: 0, // will be calculated\n uncompressedSize: uncompressedResult.value,\n });\n }\n\n // Calculate actual positions by walking through blocks\n let currentPos = 12; // After stream header\n for (let i = 0; i < records.length; i++) {\n const record = records[i];\n // Record where this block's header starts\n record.compressedPos = currentPos;\n\n // Get block header size from the actual data\n const headerSizeRaw = getByte(currentPos);\n const headerSize = (headerSizeRaw + 1) * 4;\n\n // Calculate compressed data size from unpadded size\n record.compressedDataSize = record.unpaddedSize - headerSize - checkSize;\n\n // Move to next block: unpaddedSize + padding to 4-byte boundary\n const paddedSize = Math.ceil(record.unpaddedSize / 4) * 4;\n currentPos += paddedSize;\n }\n\n return records;\n}\n\n/**\n * Pure JS XZ decompression (handles all XZ spec features)\n * Returns BufferList for memory efficiency with large files.\n */\nfunction decodeXZPure(input: Buffer): Buffer | BufferList {\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 = readByte(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 // Find footer by skipping stream padding (null bytes at end before footer)\n // Stream padding must be multiple of 4 bytes\n let footerEnd = input.length;\n while (footerEnd > 12 && readByte(input, footerEnd - 1) === 0x00) {\n footerEnd--;\n }\n // Align to 4-byte boundary (stream padding rules)\n while (footerEnd % 4 !== 0 && footerEnd > 12) {\n footerEnd++;\n }\n\n // Verify footer magic (at footerEnd - 2)\n if (!bufferEquals(input, footerEnd - 2, XZ_FOOTER_MAGIC)) {\n throw new Error('Invalid XZ footer magic');\n }\n\n // Get backward size (tells us where index starts) - at footerEnd - 8\n const backwardSizeLE = readUInt32LE(input, footerEnd - 8);\n if (backwardSizeLE === null) {\n throw new Error('Invalid backward size');\n }\n const backwardSize = (backwardSizeLE + 1) * 4;\n const indexStart = footerEnd - 12 - backwardSize;\n\n // Parse Index to get block information\n const blockRecords = parseIndex(input, indexStart, checkSize);\n\n // Handle empty files (no blocks) - return empty buffer\n if (blockRecords.length === 0) return allocBuffer(0);\n\n // Calculate total uncompressed size for multi-block decision\n let totalUncompressedSize = 0;\n for (let i = 0; i < blockRecords.length; i++) {\n totalUncompressedSize += blockRecords[i].uncompressedSize;\n }\n\n // Small multi-block files: use Buffer.concat directly (avoids BufferList overhead)\n // Threshold of 64KB: below this, the overhead of linked list nodes isn't worth it\n const BUFFERLIST_THRESHOLD = 64 * 1024; // 64KB\n\n // Single block OR small multi-block: return Buffer directly\n if (blockRecords.length === 1 || totalUncompressedSize < BUFFERLIST_THRESHOLD) {\n const record = blockRecords[0];\n const recordStart = record.compressedPos;\n const blockInfo = parseBlockHeader(input, recordStart, checkSize);\n const dataStart = recordStart + blockInfo.headerSize;\n const dataEnd = dataStart + record.compressedDataSize;\n const compressedData = input.slice(dataStart, dataEnd);\n\n let blockOutput = decodeLzma2(compressedData, blockInfo.lzma2Props, record.uncompressedSize) as Buffer;\n\n for (let j = blockInfo.filters.length - 1; j >= 0; j--) {\n blockOutput = applyFilter(blockOutput, blockInfo.filters[j]) as Buffer;\n }\n\n return blockOutput;\n }\n\n // Multi-block (large): use BufferList to avoid large contiguous allocation\n const output = new BufferList();\n\n for (let i = 0; i < blockRecords.length; i++) {\n const record = blockRecords[i];\n const recordStart = record.compressedPos;\n\n // Parse block header\n const blockInfo = parseBlockHeader(input, recordStart, checkSize);\n\n // Extract compressed data for this block\n const dataStart = recordStart + blockInfo.headerSize;\n const dataEnd = dataStart + record.compressedDataSize;\n\n // Note: XZ blocks have padding AFTER the check field to align to 4 bytes,\n // but the compressedSize from index is exact - no need to strip padding.\n // LZMA2 data includes a 0x00 end marker which must NOT be stripped.\n const compressedData = input.slice(dataStart, dataEnd);\n\n // Decompress this block with LZMA2 (fast path, no buffering)\n let blockOutput = decodeLzma2(compressedData, blockInfo.lzma2Props, record.uncompressedSize) as Buffer;\n\n // Apply preprocessing filters in reverse order (BCJ/Delta applied after LZMA2)\n // Filters are stored in order they were applied during compression,\n // so we need to reverse for decompression\n for (let j = blockInfo.filters.length - 1; j >= 0; j--) {\n blockOutput = applyFilter(blockOutput, blockInfo.filters[j]) as Buffer;\n }\n\n // Append block to BufferList\n output.append(blockOutput);\n }\n\n return output;\n}\n\n/** Callback invoked when an async decode completes */\nexport type XzDecodeCallback = DecodeCallback<BufferLike>;\n\n/**\n * Decompress XZ data. With a callback the result is provided asynchronously;\n * otherwise a Promise resolves with the decoded data.\n *\n * Returns Buffer for single-block files (most small files).\n * Returns BufferList for multi-block files (avoids large contiguous allocation).\n */\nexport function decodeXZ(input: Buffer, callback: XzDecodeCallback): void;\nexport function decodeXZ(input: Buffer): Promise<BufferLike>;\nexport function decodeXZ(input: Buffer, callback?: XzDecodeCallback): Promise<BufferLike> | void {\n const worker = (cb: XzDecodeCallback) => {\n const fallback = () => {\n try {\n cb(null, decodeXZPure(input));\n } catch (err) {\n cb(err as Error);\n }\n };\n\n const native = tryLoadNative();\n if (native?.xz?.decompress) {\n try {\n const promise = native.xz.decompress(input);\n if (promise && typeof promise.then === 'function') {\n promise.then((value) => cb(null, value as BufferLike), fallback);\n return;\n }\n } catch {\n // fall through to fallback\n }\n }\n fallback();\n };\n\n if (typeof callback === 'function') return worker(callback);\n return new Promise((resolve, reject) => worker((err, value) => (err ? reject(err) : resolve(value as BufferLike))));\n}\n\n// Callback-based LZMA2 decoder type (for Node 0.8+ compatibility - no promises)\ntype Lzma2DecodeCallback = (err: Error | null, result?: Buffer) => void;\ntype Lzma2Decoder = (data: Buffer, props: Buffer, size: number, callback: Lzma2DecodeCallback) => void;\n\n/**\n * Create an XZ decompression Transform stream\n * @returns Transform stream that decompresses XZ data\n *\n * Uses native lzma-native bindings when available for better performance.\n * Falls back to pure JS implementation on older Node versions or when native is unavailable.\n */\nexport function createXZDecoder(): TransformType {\n const bufferList = new BufferList();\n // Cache native module lookup (only done once)\n const native = tryLoadNative();\n\n // Choose decoder: native (async via callback) or pure JS (sync wrapped in callback)\n const decodeLzma2Block: Lzma2Decoder = native?.lzma2\n ? (data, props, size, cb) => {\n native.lzma2?.(data, props, size).then(\n (result) => cb(null, result),\n (err) => cb(err)\n );\n }\n : (data, props, size, cb) => {\n try {\n cb(null, decodeLzma2(data, props, size) as Buffer);\n } catch (err) {\n cb(err as Error);\n }\n };\n\n return new Transform({\n transform(chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void) {\n bufferList.append(chunk);\n callback();\n },\n\n flush(callback: (error?: Error | null) => void) {\n const input: BufferLike = bufferList;\n\n // One-time binding for buffer access (avoids repeated Buffer.isBuffer checks)\n const getByte = Buffer.isBuffer(input) ? (offset: number) => input[offset] : (offset: number) => input.readByte(offset);\n\n const getUInt32LE = Buffer.isBuffer(input) ? (offset: number) => (offset < 0 || offset + 4 > input.length ? null : input.readUInt32LE(offset)) : (offset: number) => input.readUInt32LEAt(offset);\n\n const equals = (offset: number, expected: number[]): boolean => {\n if (offset + expected.length > input.length) return false;\n for (let i = 0; i < expected.length; i++) {\n if (getByte(offset + i) !== expected[i]) return false;\n }\n return true;\n };\n\n // Verify XZ magic (need at least 12 bytes)\n if (input.length < 12 || !equals(0, XZ_MAGIC)) {\n callback(new Error('Invalid XZ magic bytes'));\n return;\n }\n\n // Stream flags at offset 6-7\n const checkType = getByte(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 // Find footer by skipping stream padding (null bytes at end before footer)\n let footerEnd = input.length;\n while (footerEnd > 12 && getByte(footerEnd - 1) === 0x00) {\n footerEnd--;\n }\n // Align to 4-byte boundary\n while (footerEnd % 4 !== 0 && footerEnd > 12) {\n footerEnd++;\n }\n\n // Verify footer magic (at footerEnd - 2)\n if (!equals(footerEnd - 2, XZ_FOOTER_MAGIC)) {\n callback(new Error('Invalid XZ footer magic'));\n return;\n }\n\n // Get backward size (at footerEnd - 8)\n const backwardSizeLE = getUInt32LE(footerEnd - 8);\n if (backwardSizeLE === null) {\n callback(new Error('Invalid backward size'));\n return;\n }\n const backwardSize = (backwardSizeLE + 1) * 4;\n const indexStart = footerEnd - 12 - backwardSize;\n\n // Parse Index to get block information\n const blockRecords = parseIndex(input, indexStart, checkSize);\n\n // Decompress blocks sequentially (native is async)\n let blockIndex = 0;\n const pushBlock = (err: Error | null) => {\n if (err) {\n callback(err);\n return;\n }\n\n if (blockIndex >= blockRecords.length) {\n // All blocks processed - purge input BufferList to free memory\n if (!Buffer.isBuffer(input)) input.clear();\n callback(null);\n return;\n }\n\n const record = blockRecords[blockIndex++];\n const recordStart = record.compressedPos;\n\n // Parse block header (need to get the header bytes)\n // Read header size byte first\n const headerSizeRaw = getByte(recordStart);\n const headerSize = (headerSizeRaw + 1) * 4;\n\n // Read the full header to parse filters\n const headerData = input.slice(recordStart, recordStart + headerSize);\n const blockInfo = parseBlockHeader(headerData, 0, checkSize);\n\n // Extract compressed data for this block\n const dataStart = recordStart + headerSize;\n const dataEnd = dataStart + record.compressedDataSize;\n const compressedData = input.slice(dataStart, dataEnd);\n\n // Decompress this block (native or pure JS, callback-based)\n decodeLzma2Block(compressedData, blockInfo.lzma2Props, record.uncompressedSize, (decodeErr, blockOutput) => {\n if (decodeErr || !blockOutput) {\n pushBlock(decodeErr || new Error('Decode returned no data'));\n return;\n }\n\n // Apply preprocessing filters in reverse order\n for (let j = blockInfo.filters.length - 1; j >= 0; j--) {\n blockOutput = applyFilter(blockOutput, blockInfo.filters[j]) as Buffer;\n }\n\n // Push the block output immediately (streaming)\n this.push(blockOutput);\n\n // Continue with next block\n pushBlock(null);\n });\n };\n\n // Start processing blocks\n pushBlock(null);\n },\n });\n}\n"],"names":["createXZDecoder","decodeXZ","XZ_MAGIC","XZ_FOOTER_MAGIC","FILTER_DELTA","FILTER_BCJ_X86","FILTER_BCJ_PPC","FILTER_BCJ_IA64","FILTER_BCJ_ARM","FILTER_BCJ_ARMT","FILTER_BCJ_SPARC","FILTER_BCJ_ARM64","FILTER_LZMA2","readByte","buf","offset","Buffer","isBuffer","readUInt32LE","length","readUInt32LEAt","bufferEquals","expected","i","decodeMultibyte","value","byte","Error","bytesRead","applyFilter","data","filter","id","decodeBcj","props","decodeBcjArm","decodeBcjArm64","decodeBcjArmt","decodeBcjPpc","decodeBcjSparc","decodeBcjIa64","decodeDelta","toString","parseBlockHeader","input","_checkSize","blockHeaderSizeRaw","blockHeaderSize","blockHeaderStart","blockFlags","numFilters","hasCompressedSize","hasUncompressedSize","result","filters","lzma2Props","filterIdResult","filterId","propsSizeResult","filterProps","slice","push","blockDataStart","headerSize","dataStart","dataEnd","nextOffset","parseIndex","indexStart","checkSize","getByte","decodeMultibyteLocal","countResult","recordCount","records","unpaddedResult","uncompressedResult","compressedPos","unpaddedSize","compressedDataSize","uncompressedSize","currentPos","record","headerSizeRaw","paddedSize","Math","ceil","decodeXZPure","checkSizes","checkType","footerEnd","backwardSizeLE","backwardSize","blockRecords","allocBuffer","totalUncompressedSize","BUFFERLIST_THRESHOLD","recordStart","blockInfo","compressedData","blockOutput","decodeLzma2","j","output","BufferList","append","callback","worker","cb","native","fallback","err","tryLoadNative","xz","decompress","promise","then","Promise","resolve","reject","bufferList","decodeLzma2Block","lzma2","size","Transform","transform","chunk","_encoding","flush","getUInt32LE","equals","blockIndex","pushBlock","clear","headerData","decodeErr"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/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 * IMPORTANT: Buffer Management Pattern\n *\n * When calling decodeLzma2(), use the direct return pattern:\n *\n * ✅ CORRECT - Fast path:\n * const output = decodeLzma2(data, props, size) as Buffer;\n *\n * ❌ WRONG - Slow path (do NOT buffer):\n * const chunks: Buffer[] = [];\n * decodeLzma2(data, props, size, { write: c => chunks.push(c) });\n * return Buffer.concat(chunks); // ← Unnecessary copies!\n */\n\nimport { allocBuffer, type BufferLike, BufferList, Transform } from 'extract-base-iterator';\nimport type { Transform as TransformType } from 'stream';\nimport { decodeBcj } from '../filters/bcj/Bcj.ts';\nimport { decodeBcjArm } from '../filters/bcj/BcjArm.ts';\nimport { decodeBcjArm64 } from '../filters/bcj/BcjArm64.ts';\nimport { decodeBcjArmt } from '../filters/bcj/BcjArmt.ts';\nimport { decodeBcjIa64 } from '../filters/bcj/BcjIa64.ts';\nimport { decodeBcjPpc } from '../filters/bcj/BcjPpc.ts';\nimport { decodeBcjSparc } from '../filters/bcj/BcjSparc.ts';\nimport { decodeDelta } from '../filters/delta/Delta.ts';\nimport { decodeLzma2 } from '../lzma/index.ts';\nimport { tryLoadNative } from '../native.ts';\nimport type { DecodeCallback } from '../sevenz.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 (from XZ specification)\nconst FILTER_DELTA = 0x03;\nconst FILTER_BCJ_X86 = 0x04;\nconst FILTER_BCJ_PPC = 0x05;\nconst FILTER_BCJ_IA64 = 0x06;\nconst FILTER_BCJ_ARM = 0x07;\nconst FILTER_BCJ_ARMT = 0x08;\nconst FILTER_BCJ_SPARC = 0x09;\nconst FILTER_BCJ_ARM64 = 0x0a;\nconst FILTER_LZMA2 = 0x21;\n\n// Filter info for parsing\ninterface FilterInfo {\n id: number;\n props: Buffer;\n}\n\n// Re-export BufferLike for public API\nexport type { BufferLike } from 'extract-base-iterator';\n\n/**\n * Read a byte from Buffer or BufferList\n */\nfunction readByte(buf: BufferLike, offset: number): number {\n return Buffer.isBuffer(buf) ? buf[offset] : buf.readByte(offset);\n}\n\n/**\n * Read UInt32LE from Buffer or BufferList (returns null if out of bounds)\n */\nfunction readUInt32LE(buf: BufferLike, offset: number): number | null {\n if (Buffer.isBuffer(buf)) {\n if (offset < 0 || offset + 4 > buf.length) return null;\n return buf.readUInt32LE(offset);\n }\n return buf.readUInt32LEAt(offset);\n}\n\n/**\n * Compare buffer contents at offset with expected byte sequence\n * Works with both Buffer and BufferList\n */\nfunction bufferEquals(buf: BufferLike, 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 (readByte(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 * Works with both Buffer and BufferList\n */\nfunction decodeMultibyte(buf: BufferLike, 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 = readByte(buf, offset + i);\n value |= (byte & 0x7f) << (i * 7);\n i++;\n if (i > 4) {\n throw new Error('Multibyte integer too large');\n }\n } while (byte & 0x80);\n return { value, bytesRead: i };\n}\n\n/**\n * Apply a preprocessing filter (BCJ/Delta) to decompressed data\n */\nfunction applyFilter(data: Buffer, filter: FilterInfo): Buffer {\n switch (filter.id) {\n case FILTER_BCJ_X86:\n return decodeBcj(data, filter.props);\n case FILTER_BCJ_ARM:\n return decodeBcjArm(data, filter.props);\n case FILTER_BCJ_ARM64:\n return decodeBcjArm64(data, filter.props);\n case FILTER_BCJ_ARMT:\n return decodeBcjArmt(data, filter.props);\n case FILTER_BCJ_PPC:\n return decodeBcjPpc(data, filter.props);\n case FILTER_BCJ_SPARC:\n return decodeBcjSparc(data, filter.props);\n case FILTER_BCJ_IA64:\n return decodeBcjIa64(data, filter.props);\n case FILTER_DELTA:\n return decodeDelta(data, filter.props);\n default:\n throw new Error(`Unsupported filter: 0x${filter.id.toString(16)}`);\n }\n}\n\n/**\n * Parse XZ Block Header to extract filters and LZMA2 properties\n */\nfunction parseBlockHeader(\n input: Buffer,\n offset: number,\n _checkSize: number\n): {\n filters: FilterInfo[];\n lzma2Props: Buffer;\n headerSize: number;\n dataStart: number;\n dataEnd: number;\n nextOffset: number;\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\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 if (hasUncompressedSize) {\n const result = decodeMultibyte(input, offset);\n offset += result.bytesRead;\n }\n\n // Parse all filters\n const filters: FilterInfo[] = [];\n let lzma2Props: Buffer | null = null;\n\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 // LZMA2 must be the last filter\n lzma2Props = filterProps;\n } else if (filterId === FILTER_DELTA || (filterId >= FILTER_BCJ_X86 && filterId <= FILTER_BCJ_ARM64)) {\n // Preprocessing filter - store for later application\n filters.push({ id: filterId, props: filterProps });\n } else {\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 (must be aligned to 4 bytes)\n const blockDataStart = blockHeaderStart + blockHeaderSize;\n\n return {\n filters,\n lzma2Props,\n headerSize: blockHeaderSize,\n dataStart: blockDataStart,\n dataEnd: input.length,\n nextOffset: blockDataStart,\n };\n}\n\n/**\n * Parse XZ Index to get block positions\n * Works with both Buffer and BufferList\n */\nfunction parseIndex(\n input: BufferLike,\n indexStart: number,\n checkSize: number\n): Array<{\n compressedPos: number;\n compressedDataSize: number;\n uncompressedSize: number;\n}> {\n // One-time binding for buffer access (avoids repeated Buffer.isBuffer checks)\n const getByte = Buffer.isBuffer(input) ? (offset: number) => input[offset] : (offset: number) => input.readByte(offset);\n\n // Local multibyte decoder using bound getByte\n const decodeMultibyteLocal = (offset: number): { value: number; bytesRead: number } => {\n let value = 0;\n let i = 0;\n let byte: number;\n do {\n if (offset + i >= input.length) {\n throw new Error('Truncated multibyte integer');\n }\n byte = getByte(offset + i);\n value |= (byte & 0x7f) << (i * 7);\n i++;\n if (i > 4) {\n throw new Error('Multibyte integer too large');\n }\n } while (byte & 0x80);\n return { value, bytesRead: i };\n };\n\n let offset = indexStart;\n\n // Index indicator (0x00)\n if (getByte(offset) !== 0x00) {\n throw new Error('Invalid index indicator');\n }\n offset++;\n\n // Number of records\n const countResult = decodeMultibyteLocal(offset);\n const recordCount = countResult.value;\n offset += countResult.bytesRead;\n\n const records: Array<{\n compressedPos: number;\n unpaddedSize: number;\n compressedDataSize: number;\n uncompressedSize: number;\n }> = [];\n\n // Parse each record\n for (let i = 0; i < recordCount; i++) {\n // Unpadded Size (header + compressed data + check)\n const unpaddedResult = decodeMultibyteLocal(offset);\n offset += unpaddedResult.bytesRead;\n\n // Uncompressed size\n const uncompressedResult = decodeMultibyteLocal(offset);\n offset += uncompressedResult.bytesRead;\n\n records.push({\n compressedPos: 0, // will be calculated\n unpaddedSize: unpaddedResult.value,\n compressedDataSize: 0, // will be calculated\n uncompressedSize: uncompressedResult.value,\n });\n }\n\n // Calculate actual positions by walking through blocks\n let currentPos = 12; // After stream header\n for (let i = 0; i < records.length; i++) {\n const record = records[i];\n // Record where this block's header starts\n record.compressedPos = currentPos;\n\n // Get block header size from the actual data\n const headerSizeRaw = getByte(currentPos);\n const headerSize = (headerSizeRaw + 1) * 4;\n\n // Calculate compressed data size from unpadded size\n record.compressedDataSize = record.unpaddedSize - headerSize - checkSize;\n\n // Move to next block: unpaddedSize + padding to 4-byte boundary\n const paddedSize = Math.ceil(record.unpaddedSize / 4) * 4;\n currentPos += paddedSize;\n }\n\n return records;\n}\n\n/**\n * Pure JS XZ decompression (handles all XZ spec features)\n * Returns BufferList for memory efficiency with large files.\n */\nfunction decodeXZPure(input: Buffer): Buffer | BufferList {\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 = readByte(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 // Find footer by skipping stream padding (null bytes at end before footer)\n // Stream padding must be multiple of 4 bytes\n let footerEnd = input.length;\n while (footerEnd > 12 && readByte(input, footerEnd - 1) === 0x00) {\n footerEnd--;\n }\n // Align to 4-byte boundary (stream padding rules)\n while (footerEnd % 4 !== 0 && footerEnd > 12) {\n footerEnd++;\n }\n\n // Verify footer magic (at footerEnd - 2)\n if (!bufferEquals(input, footerEnd - 2, XZ_FOOTER_MAGIC)) {\n throw new Error('Invalid XZ footer magic');\n }\n\n // Get backward size (tells us where index starts) - at footerEnd - 8\n const backwardSizeLE = readUInt32LE(input, footerEnd - 8);\n if (backwardSizeLE === null) {\n throw new Error('Invalid backward size');\n }\n const backwardSize = (backwardSizeLE + 1) * 4;\n const indexStart = footerEnd - 12 - backwardSize;\n\n // Parse Index to get block information\n const blockRecords = parseIndex(input, indexStart, checkSize);\n\n // Handle empty files (no blocks) - return empty buffer\n if (blockRecords.length === 0) return allocBuffer(0);\n\n // Calculate total uncompressed size for multi-block decision\n let totalUncompressedSize = 0;\n for (let i = 0; i < blockRecords.length; i++) {\n totalUncompressedSize += blockRecords[i].uncompressedSize;\n }\n\n // Small multi-block files: use Buffer.concat directly (avoids BufferList overhead)\n // Threshold of 64KB: below this, the overhead of linked list nodes isn't worth it\n const BUFFERLIST_THRESHOLD = 64 * 1024; // 64KB\n\n // Single block OR small multi-block: return Buffer directly\n if (blockRecords.length === 1 || totalUncompressedSize < BUFFERLIST_THRESHOLD) {\n const record = blockRecords[0];\n const recordStart = record.compressedPos;\n const blockInfo = parseBlockHeader(input, recordStart, checkSize);\n const dataStart = recordStart + blockInfo.headerSize;\n const dataEnd = dataStart + record.compressedDataSize;\n const compressedData = input.slice(dataStart, dataEnd);\n\n let blockOutput = decodeLzma2(compressedData, blockInfo.lzma2Props, record.uncompressedSize) as Buffer;\n\n for (let j = blockInfo.filters.length - 1; j >= 0; j--) {\n blockOutput = applyFilter(blockOutput, blockInfo.filters[j]) as Buffer;\n }\n\n return blockOutput;\n }\n\n // Multi-block (large): use BufferList to avoid large contiguous allocation\n const output = new BufferList();\n\n for (let i = 0; i < blockRecords.length; i++) {\n const record = blockRecords[i];\n const recordStart = record.compressedPos;\n\n // Parse block header\n const blockInfo = parseBlockHeader(input, recordStart, checkSize);\n\n // Extract compressed data for this block\n const dataStart = recordStart + blockInfo.headerSize;\n const dataEnd = dataStart + record.compressedDataSize;\n\n // Note: XZ blocks have padding AFTER the check field to align to 4 bytes,\n // but the compressedSize from index is exact - no need to strip padding.\n // LZMA2 data includes a 0x00 end marker which must NOT be stripped.\n const compressedData = input.slice(dataStart, dataEnd);\n\n // Decompress this block with LZMA2 (fast path, no buffering)\n let blockOutput = decodeLzma2(compressedData, blockInfo.lzma2Props, record.uncompressedSize) as Buffer;\n\n // Apply preprocessing filters in reverse order (BCJ/Delta applied after LZMA2)\n // Filters are stored in order they were applied during compression,\n // so we need to reverse for decompression\n for (let j = blockInfo.filters.length - 1; j >= 0; j--) {\n blockOutput = applyFilter(blockOutput, blockInfo.filters[j]) as Buffer;\n }\n\n // Append block to BufferList\n output.append(blockOutput);\n }\n\n return output;\n}\n\n/** Callback invoked when an async decode completes */\nexport type XzDecodeCallback = DecodeCallback<BufferLike>;\n\n/**\n * Decompress XZ data. With a callback the result is provided asynchronously;\n * otherwise a Promise resolves with the decoded data.\n *\n * Returns Buffer for single-block files (most small files).\n * Returns BufferList for multi-block files (avoids large contiguous allocation).\n */\nexport function decodeXZ(input: Buffer, callback: XzDecodeCallback): void;\nexport function decodeXZ(input: Buffer): Promise<BufferLike>;\nexport function decodeXZ(input: Buffer, callback?: XzDecodeCallback): Promise<BufferLike> | void {\n const worker = (cb: XzDecodeCallback) => {\n const fallback = () => {\n try {\n cb(null, decodeXZPure(input));\n } catch (err) {\n cb(err as Error);\n }\n };\n\n const native = tryLoadNative();\n if (native?.xz?.decompress) {\n try {\n const promise = native.xz.decompress(input);\n if (promise && typeof promise.then === 'function') {\n promise.then((value) => cb(null, value as BufferLike), fallback);\n return;\n }\n } catch {\n // fall through to fallback\n }\n }\n fallback();\n };\n\n if (typeof callback === 'function') return worker(callback);\n return new Promise((resolve, reject) => worker((err, value) => (err ? reject(err) : resolve(value as BufferLike))));\n}\n\n// Callback-based LZMA2 decoder type (for Node 0.8+ compatibility - no promises)\ntype Lzma2DecodeCallback = (err: Error | null, result?: Buffer) => void;\ntype Lzma2Decoder = (data: Buffer, props: Buffer, size: number, callback: Lzma2DecodeCallback) => void;\n\n/**\n * Create an XZ decompression Transform stream\n * @returns Transform stream that decompresses XZ data\n *\n * Uses native lzma-native bindings when available for better performance.\n * Falls back to pure JS implementation on older Node versions or when native is unavailable.\n */\nexport function createXZDecoder(): TransformType {\n const bufferList = new BufferList();\n // Cache native module lookup (only done once)\n const native = tryLoadNative();\n\n // Choose decoder: native (async via callback) or pure JS (sync wrapped in callback)\n const decodeLzma2Block: Lzma2Decoder = native?.lzma2\n ? (data, props, size, cb) => {\n native.lzma2?.(data, props, size).then(\n (result) => cb(null, result),\n (err) => cb(err)\n );\n }\n : (data, props, size, cb) => {\n try {\n cb(null, decodeLzma2(data, props, size) as Buffer);\n } catch (err) {\n cb(err as Error);\n }\n };\n\n return new Transform({\n transform(chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void) {\n bufferList.append(chunk);\n callback();\n },\n\n flush(callback: (error?: Error | null) => void) {\n const input: BufferLike = bufferList;\n\n // One-time binding for buffer access (avoids repeated Buffer.isBuffer checks)\n const getByte = Buffer.isBuffer(input) ? (offset: number) => input[offset] : (offset: number) => input.readByte(offset);\n\n const getUInt32LE = Buffer.isBuffer(input) ? (offset: number) => (offset < 0 || offset + 4 > input.length ? null : input.readUInt32LE(offset)) : (offset: number) => input.readUInt32LEAt(offset);\n\n const equals = (offset: number, expected: number[]): boolean => {\n if (offset + expected.length > input.length) return false;\n for (let i = 0; i < expected.length; i++) {\n if (getByte(offset + i) !== expected[i]) return false;\n }\n return true;\n };\n\n // Verify XZ magic (need at least 12 bytes)\n if (input.length < 12 || !equals(0, XZ_MAGIC)) {\n callback(new Error('Invalid XZ magic bytes'));\n return;\n }\n\n // Stream flags at offset 6-7\n const checkType = getByte(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 // Find footer by skipping stream padding (null bytes at end before footer)\n let footerEnd = input.length;\n while (footerEnd > 12 && getByte(footerEnd - 1) === 0x00) {\n footerEnd--;\n }\n // Align to 4-byte boundary\n while (footerEnd % 4 !== 0 && footerEnd > 12) {\n footerEnd++;\n }\n\n // Verify footer magic (at footerEnd - 2)\n if (!equals(footerEnd - 2, XZ_FOOTER_MAGIC)) {\n callback(new Error('Invalid XZ footer magic'));\n return;\n }\n\n // Get backward size (at footerEnd - 8)\n const backwardSizeLE = getUInt32LE(footerEnd - 8);\n if (backwardSizeLE === null) {\n callback(new Error('Invalid backward size'));\n return;\n }\n const backwardSize = (backwardSizeLE + 1) * 4;\n const indexStart = footerEnd - 12 - backwardSize;\n\n // Parse Index to get block information\n const blockRecords = parseIndex(input, indexStart, checkSize);\n\n // Decompress blocks sequentially (native is async)\n let blockIndex = 0;\n const pushBlock = (err: Error | null) => {\n if (err) return callback(err);\n\n if (blockIndex >= blockRecords.length) {\n // All blocks processed - purge input BufferList to free memory\n if (!Buffer.isBuffer(input)) input.clear();\n callback(null);\n return;\n }\n\n const record = blockRecords[blockIndex++];\n const recordStart = record.compressedPos;\n\n // Parse block header (need to get the header bytes)\n // Read header size byte first\n const headerSizeRaw = getByte(recordStart);\n const headerSize = (headerSizeRaw + 1) * 4;\n\n // Read the full header to parse filters\n const headerData = input.slice(recordStart, recordStart + headerSize);\n const blockInfo = parseBlockHeader(headerData, 0, checkSize);\n\n // Extract compressed data for this block\n const dataStart = recordStart + headerSize;\n const dataEnd = dataStart + record.compressedDataSize;\n const compressedData = input.slice(dataStart, dataEnd);\n\n // Decompress this block (native or pure JS, callback-based)\n decodeLzma2Block(compressedData, blockInfo.lzma2Props, record.uncompressedSize, (decodeErr, blockOutput) => {\n if (decodeErr || !blockOutput) {\n pushBlock(decodeErr || new Error('Decode returned no data'));\n return;\n }\n\n // Apply preprocessing filters in reverse order\n for (let j = blockInfo.filters.length - 1; j >= 0; j--) {\n blockOutput = applyFilter(blockOutput, blockInfo.filters[j]) as Buffer;\n }\n\n // Push the block output immediately (streaming)\n this.push(blockOutput);\n\n // Continue with next block\n pushBlock(null);\n });\n };\n\n // Start processing blocks\n pushBlock(null);\n },\n });\n}\n"],"names":["createXZDecoder","decodeXZ","XZ_MAGIC","XZ_FOOTER_MAGIC","FILTER_DELTA","FILTER_BCJ_X86","FILTER_BCJ_PPC","FILTER_BCJ_IA64","FILTER_BCJ_ARM","FILTER_BCJ_ARMT","FILTER_BCJ_SPARC","FILTER_BCJ_ARM64","FILTER_LZMA2","readByte","buf","offset","Buffer","isBuffer","readUInt32LE","length","readUInt32LEAt","bufferEquals","expected","i","decodeMultibyte","value","byte","Error","bytesRead","applyFilter","data","filter","id","decodeBcj","props","decodeBcjArm","decodeBcjArm64","decodeBcjArmt","decodeBcjPpc","decodeBcjSparc","decodeBcjIa64","decodeDelta","toString","parseBlockHeader","input","_checkSize","blockHeaderSizeRaw","blockHeaderSize","blockHeaderStart","blockFlags","numFilters","hasCompressedSize","hasUncompressedSize","result","filters","lzma2Props","filterIdResult","filterId","propsSizeResult","filterProps","slice","push","blockDataStart","headerSize","dataStart","dataEnd","nextOffset","parseIndex","indexStart","checkSize","getByte","decodeMultibyteLocal","countResult","recordCount","records","unpaddedResult","uncompressedResult","compressedPos","unpaddedSize","compressedDataSize","uncompressedSize","currentPos","record","headerSizeRaw","paddedSize","Math","ceil","decodeXZPure","checkSizes","checkType","footerEnd","backwardSizeLE","backwardSize","blockRecords","allocBuffer","totalUncompressedSize","BUFFERLIST_THRESHOLD","recordStart","blockInfo","compressedData","blockOutput","decodeLzma2","j","output","BufferList","append","callback","worker","cb","native","fallback","err","tryLoadNative","xz","decompress","promise","then","Promise","resolve","reject","bufferList","decodeLzma2Block","lzma2","size","Transform","transform","chunk","_encoding","flush","getUInt32LE","equals","blockIndex","pushBlock","clear","headerData","decodeErr"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;CAmBC;;;;;;;;;;;QAsdeA;eAAAA;;QAxCAC;eAAAA;;;mCA5aoD;qBAE1C;wBACG;0BACE;yBACD;yBACA;wBACD;0BACE;uBACH;uBACA;wBACE;AAG9B,iBAAiB;AACjB,IAAMC,WAAW;IAAC;IAAM;IAAM;IAAM;IAAM;IAAM;CAAK;AACrD,IAAMC,kBAAkB;IAAC;IAAM;CAAK,EAAE,OAAO;AAE7C,qCAAqC;AACrC,IAAMC,eAAe;AACrB,IAAMC,iBAAiB;AACvB,IAAMC,iBAAiB;AACvB,IAAMC,kBAAkB;AACxB,IAAMC,iBAAiB;AACvB,IAAMC,kBAAkB;AACxB,IAAMC,mBAAmB;AACzB,IAAMC,mBAAmB;AACzB,IAAMC,eAAe;AAWrB;;CAEC,GACD,SAASC,SAASC,GAAe,EAAEC,MAAc;IAC/C,OAAOC,OAAOC,QAAQ,CAACH,OAAOA,GAAG,CAACC,OAAO,GAAGD,IAAID,QAAQ,CAACE;AAC3D;AAEA;;CAEC,GACD,SAASG,aAAaJ,GAAe,EAAEC,MAAc;IACnD,IAAIC,OAAOC,QAAQ,CAACH,MAAM;QACxB,IAAIC,SAAS,KAAKA,SAAS,IAAID,IAAIK,MAAM,EAAE,OAAO;QAClD,OAAOL,IAAII,YAAY,CAACH;IAC1B;IACA,OAAOD,IAAIM,cAAc,CAACL;AAC5B;AAEA;;;CAGC,GACD,SAASM,aAAaP,GAAe,EAAEC,MAAc,EAAEO,QAAkB;IACvE,IAAIP,SAASO,SAASH,MAAM,GAAGL,IAAIK,MAAM,EAAE;QACzC,OAAO;IACT;IACA,IAAK,IAAII,IAAI,GAAGA,IAAID,SAASH,MAAM,EAAEI,IAAK;QACxC,IAAIV,SAASC,KAAKC,SAASQ,OAAOD,QAAQ,CAACC,EAAE,EAAE;YAC7C,OAAO;QACT;IACF;IACA,OAAO;AACT;AAEA;;;CAGC,GACD,SAASC,gBAAgBV,GAAe,EAAEC,MAAc;IACtD,IAAIU,QAAQ;IACZ,IAAIF,IAAI;IACR,IAAIG;IACJ,GAAG;QACD,IAAIX,SAASQ,KAAKT,IAAIK,MAAM,EAAE;YAC5B,MAAM,IAAIQ,MAAM;QAClB;QACAD,OAAOb,SAASC,KAAKC,SAASQ;QAC9BE,SAAS,AAACC,CAAAA,OAAO,IAAG,KAAOH,IAAI;QAC/BA;QACA,IAAIA,IAAI,GAAG;YACT,MAAM,IAAII,MAAM;QAClB;IACF,QAASD,OAAO,MAAM;IACtB,OAAO;QAAED,OAAAA;QAAOG,WAAWL;IAAE;AAC/B;AAEA;;CAEC,GACD,SAASM,YAAYC,IAAY,EAAEC,MAAkB;IACnD,OAAQA,OAAOC,EAAE;QACf,KAAK3B;YACH,OAAO4B,IAAAA,gBAAS,EAACH,MAAMC,OAAOG,KAAK;QACrC,KAAK1B;YACH,OAAO2B,IAAAA,sBAAY,EAACL,MAAMC,OAAOG,KAAK;QACxC,KAAKvB;YACH,OAAOyB,IAAAA,0BAAc,EAACN,MAAMC,OAAOG,KAAK;QAC1C,KAAKzB;YACH,OAAO4B,IAAAA,wBAAa,EAACP,MAAMC,OAAOG,KAAK;QACzC,KAAK5B;YACH,OAAOgC,IAAAA,sBAAY,EAACR,MAAMC,OAAOG,KAAK;QACxC,KAAKxB;YACH,OAAO6B,IAAAA,0BAAc,EAACT,MAAMC,OAAOG,KAAK;QAC1C,KAAK3B;YACH,OAAOiC,IAAAA,wBAAa,EAACV,MAAMC,OAAOG,KAAK;QACzC,KAAK9B;YACH,OAAOqC,IAAAA,oBAAW,EAACX,MAAMC,OAAOG,KAAK;QACvC;YACE,MAAM,IAAIP,MAAM,AAAC,yBAA+C,OAAvBI,OAAOC,EAAE,CAACU,QAAQ,CAAC;IAChE;AACF;AAEA;;CAEC,GACD,SAASC,iBACPC,KAAa,EACb7B,MAAc,EACd8B,UAAkB;IASlB,oBAAoB;IACpB,IAAMC,qBAAqBF,KAAK,CAAC7B,OAAO;IACxC,IAAI+B,uBAAuB,GAAG;QAC5B,MAAM,IAAInB,MAAM;IAClB;IACA,IAAMoB,kBAAkB,AAACD,CAAAA,qBAAqB,CAAA,IAAK;IAEnD,qBAAqB;IACrB,IAAME,mBAAmBjC;IACzBA,UAAU,iBAAiB;IAE3B,IAAMkC,aAAaL,KAAK,CAAC7B,SAAS;IAClC,IAAMmC,aAAa,AAACD,CAAAA,aAAa,IAAG,IAAK;IACzC,IAAME,oBAAoB,AAACF,CAAAA,aAAa,IAAG,MAAO;IAClD,IAAMG,sBAAsB,AAACH,CAAAA,aAAa,IAAG,MAAO;IAEpD,sBAAsB;IACtB,IAAIE,mBAAmB;QACrB,IAAME,SAAS7B,gBAAgBoB,OAAO7B;QACtCA,UAAUsC,OAAOzB,SAAS;IAC5B;IAEA,IAAIwB,qBAAqB;QACvB,IAAMC,UAAS7B,gBAAgBoB,OAAO7B;QACtCA,UAAUsC,QAAOzB,SAAS;IAC5B;IAEA,oBAAoB;IACpB,IAAM0B,UAAwB,EAAE;IAChC,IAAIC,aAA4B;IAEhC,IAAK,IAAIhC,IAAI,GAAGA,IAAI2B,YAAY3B,IAAK;QACnC,IAAMiC,iBAAiBhC,gBAAgBoB,OAAO7B;QAC9C,IAAM0C,WAAWD,eAAe/B,KAAK;QACrCV,UAAUyC,eAAe5B,SAAS;QAElC,IAAM8B,kBAAkBlC,gBAAgBoB,OAAO7B;QAC/CA,UAAU2C,gBAAgB9B,SAAS;QAEnC,IAAM+B,cAAcf,MAAMgB,KAAK,CAAC7C,QAAQA,SAAS2C,gBAAgBjC,KAAK;QACtEV,UAAU2C,gBAAgBjC,KAAK;QAE/B,IAAIgC,aAAa7C,cAAc;YAC7B,gCAAgC;YAChC2C,aAAaI;QACf,OAAO,IAAIF,aAAarD,gBAAiBqD,YAAYpD,kBAAkBoD,YAAY9C,kBAAmB;YACpG,qDAAqD;YACrD2C,QAAQO,IAAI,CAAC;gBAAE7B,IAAIyB;gBAAUvB,OAAOyB;YAAY;QAClD,OAAO;YACL,MAAM,IAAIhC,MAAM,AAAC,yBAA8C,OAAtB8B,SAASf,QAAQ,CAAC;QAC7D;IACF;IAEA,IAAI,CAACa,YAAY;QACf,MAAM,IAAI5B,MAAM;IAClB;IAEA,2DAA2D;IAC3D,IAAMmC,iBAAiBd,mBAAmBD;IAE1C,OAAO;QACLO,SAAAA;QACAC,YAAAA;QACAQ,YAAYhB;QACZiB,WAAWF;QACXG,SAASrB,MAAMzB,MAAM;QACrB+C,YAAYJ;IACd;AACF;AAEA;;;CAGC,GACD,SAASK,WACPvB,KAAiB,EACjBwB,UAAkB,EAClBC,SAAiB;IAMjB,8EAA8E;IAC9E,IAAMC,UAAUtD,OAAOC,QAAQ,CAAC2B,SAAS,SAAC7B;eAAmB6B,KAAK,CAAC7B,OAAO;QAAG,SAACA;eAAmB6B,MAAM/B,QAAQ,CAACE;;IAEhH,8CAA8C;IAC9C,IAAMwD,uBAAuB,8BAACxD;QAC5B,IAAIU,QAAQ;QACZ,IAAIF,IAAI;QACR,IAAIG;QACJ,GAAG;YACD,IAAIX,SAASQ,KAAKqB,MAAMzB,MAAM,EAAE;gBAC9B,MAAM,IAAIQ,MAAM;YAClB;YACAD,OAAO4C,QAAQvD,SAASQ;YACxBE,SAAS,AAACC,CAAAA,OAAO,IAAG,KAAOH,IAAI;YAC/BA;YACA,IAAIA,IAAI,GAAG;gBACT,MAAM,IAAII,MAAM;YAClB;QACF,QAASD,OAAO,MAAM;QACtB,OAAO;YAAED,OAAAA;YAAOG,WAAWL;QAAE;IAC/B;IAEA,IAAIR,SAASqD;IAEb,yBAAyB;IACzB,IAAIE,QAAQvD,YAAY,MAAM;QAC5B,MAAM,IAAIY,MAAM;IAClB;IACAZ;IAEA,oBAAoB;IACpB,IAAMyD,cAAcD,qBAAqBxD;IACzC,IAAM0D,cAAcD,YAAY/C,KAAK;IACrCV,UAAUyD,YAAY5C,SAAS;IAE/B,IAAM8C,UAKD,EAAE;IAEP,oBAAoB;IACpB,IAAK,IAAInD,IAAI,GAAGA,IAAIkD,aAAalD,IAAK;QACpC,mDAAmD;QACnD,IAAMoD,iBAAiBJ,qBAAqBxD;QAC5CA,UAAU4D,eAAe/C,SAAS;QAElC,oBAAoB;QACpB,IAAMgD,qBAAqBL,qBAAqBxD;QAChDA,UAAU6D,mBAAmBhD,SAAS;QAEtC8C,QAAQb,IAAI,CAAC;YACXgB,eAAe;YACfC,cAAcH,eAAelD,KAAK;YAClCsD,oBAAoB;YACpBC,kBAAkBJ,mBAAmBnD,KAAK;QAC5C;IACF;IAEA,uDAAuD;IACvD,IAAIwD,aAAa,IAAI,sBAAsB;IAC3C,IAAK,IAAI1D,KAAI,GAAGA,KAAImD,QAAQvD,MAAM,EAAEI,KAAK;QACvC,IAAM2D,SAASR,OAAO,CAACnD,GAAE;QACzB,0CAA0C;QAC1C2D,OAAOL,aAAa,GAAGI;QAEvB,6CAA6C;QAC7C,IAAME,gBAAgBb,QAAQW;QAC9B,IAAMlB,aAAa,AAACoB,CAAAA,gBAAgB,CAAA,IAAK;QAEzC,oDAAoD;QACpDD,OAAOH,kBAAkB,GAAGG,OAAOJ,YAAY,GAAGf,aAAaM;QAE/D,gEAAgE;QAChE,IAAMe,aAAaC,KAAKC,IAAI,CAACJ,OAAOJ,YAAY,GAAG,KAAK;QACxDG,cAAcG;IAChB;IAEA,OAAOV;AACT;AAEA;;;CAGC,GACD,SAASa,aAAa3C,KAAa;QAgBf4C;IAflB,kBAAkB;IAClB,IAAI5C,MAAMzB,MAAM,GAAG,MAAM,CAACE,aAAauB,OAAO,GAAG1C,WAAW;QAC1D,MAAM,IAAIyB,MAAM;IAClB;IAEA,6BAA6B;IAC7B,IAAM8D,YAAY5E,SAAS+B,OAAO,KAAK;IAEvC,kCAAkC;IAClC,IAAM4C,aAAwC;QAC5C,GAAG;QACH,GAAG;QACH,GAAG;QACH,IAAI;IACN;IACA,IAAMnB,aAAYmB,wBAAAA,UAAU,CAACC,UAAU,cAArBD,mCAAAA,wBAAyB;IAE3C,2EAA2E;IAC3E,6CAA6C;IAC7C,IAAIE,YAAY9C,MAAMzB,MAAM;IAC5B,MAAOuE,YAAY,MAAM7E,SAAS+B,OAAO8C,YAAY,OAAO,KAAM;QAChEA;IACF;IACA,kDAAkD;IAClD,MAAOA,YAAY,MAAM,KAAKA,YAAY,GAAI;QAC5CA;IACF;IAEA,yCAAyC;IACzC,IAAI,CAACrE,aAAauB,OAAO8C,YAAY,GAAGvF,kBAAkB;QACxD,MAAM,IAAIwB,MAAM;IAClB;IAEA,qEAAqE;IACrE,IAAMgE,iBAAiBzE,aAAa0B,OAAO8C,YAAY;IACvD,IAAIC,mBAAmB,MAAM;QAC3B,MAAM,IAAIhE,MAAM;IAClB;IACA,IAAMiE,eAAe,AAACD,CAAAA,iBAAiB,CAAA,IAAK;IAC5C,IAAMvB,aAAasB,YAAY,KAAKE;IAEpC,uCAAuC;IACvC,IAAMC,eAAe1B,WAAWvB,OAAOwB,YAAYC;IAEnD,uDAAuD;IACvD,IAAIwB,aAAa1E,MAAM,KAAK,GAAG,OAAO2E,IAAAA,gCAAW,EAAC;IAElD,6DAA6D;IAC7D,IAAIC,wBAAwB;IAC5B,IAAK,IAAIxE,IAAI,GAAGA,IAAIsE,aAAa1E,MAAM,EAAEI,IAAK;QAC5CwE,yBAAyBF,YAAY,CAACtE,EAAE,CAACyD,gBAAgB;IAC3D;IAEA,mFAAmF;IACnF,kFAAkF;IAClF,IAAMgB,uBAAuB,KAAK,MAAM,OAAO;IAE/C,4DAA4D;IAC5D,IAAIH,aAAa1E,MAAM,KAAK,KAAK4E,wBAAwBC,sBAAsB;QAC7E,IAAMd,SAASW,YAAY,CAAC,EAAE;QAC9B,IAAMI,cAAcf,OAAOL,aAAa;QACxC,IAAMqB,YAAYvD,iBAAiBC,OAAOqD,aAAa5B;QACvD,IAAML,YAAYiC,cAAcC,UAAUnC,UAAU;QACpD,IAAME,UAAUD,YAAYkB,OAAOH,kBAAkB;QACrD,IAAMoB,iBAAiBvD,MAAMgB,KAAK,CAACI,WAAWC;QAE9C,IAAImC,cAAcC,IAAAA,oBAAW,EAACF,gBAAgBD,UAAU3C,UAAU,EAAE2B,OAAOF,gBAAgB;QAE3F,IAAK,IAAIsB,IAAIJ,UAAU5C,OAAO,CAACnC,MAAM,GAAG,GAAGmF,KAAK,GAAGA,IAAK;YACtDF,cAAcvE,YAAYuE,aAAaF,UAAU5C,OAAO,CAACgD,EAAE;QAC7D;QAEA,OAAOF;IACT;IAEA,2EAA2E;IAC3E,IAAMG,SAAS,IAAIC,+BAAU;IAE7B,IAAK,IAAIjF,KAAI,GAAGA,KAAIsE,aAAa1E,MAAM,EAAEI,KAAK;QAC5C,IAAM2D,UAASW,YAAY,CAACtE,GAAE;QAC9B,IAAM0E,eAAcf,QAAOL,aAAa;QAExC,qBAAqB;QACrB,IAAMqB,aAAYvD,iBAAiBC,OAAOqD,cAAa5B;QAEvD,yCAAyC;QACzC,IAAML,aAAYiC,eAAcC,WAAUnC,UAAU;QACpD,IAAME,WAAUD,aAAYkB,QAAOH,kBAAkB;QAErD,0EAA0E;QAC1E,yEAAyE;QACzE,oEAAoE;QACpE,IAAMoB,kBAAiBvD,MAAMgB,KAAK,CAACI,YAAWC;QAE9C,6DAA6D;QAC7D,IAAImC,eAAcC,IAAAA,oBAAW,EAACF,iBAAgBD,WAAU3C,UAAU,EAAE2B,QAAOF,gBAAgB;QAE3F,+EAA+E;QAC/E,oEAAoE;QACpE,0CAA0C;QAC1C,IAAK,IAAIsB,KAAIJ,WAAU5C,OAAO,CAACnC,MAAM,GAAG,GAAGmF,MAAK,GAAGA,KAAK;YACtDF,eAAcvE,YAAYuE,cAAaF,WAAU5C,OAAO,CAACgD,GAAE;QAC7D;QAEA,6BAA6B;QAC7BC,OAAOE,MAAM,CAACL;IAChB;IAEA,OAAOG;AACT;AAcO,SAAStG,SAAS2C,KAAa,EAAE8D,QAA2B;IACjE,IAAMC,SAAS,gBAACC;YAUVC;QATJ,IAAMC,WAAW;YACf,IAAI;gBACFF,GAAG,MAAMrB,aAAa3C;YACxB,EAAE,OAAOmE,KAAK;gBACZH,GAAGG;YACL;QACF;QAEA,IAAMF,SAASG,IAAAA,uBAAa;QAC5B,IAAIH,mBAAAA,8BAAAA,aAAAA,OAAQI,EAAE,cAAVJ,iCAAAA,WAAYK,UAAU,EAAE;YAC1B,IAAI;gBACF,IAAMC,UAAUN,OAAOI,EAAE,CAACC,UAAU,CAACtE;gBACrC,IAAIuE,WAAW,OAAOA,QAAQC,IAAI,KAAK,YAAY;oBACjDD,QAAQC,IAAI,CAAC,SAAC3F;+BAAUmF,GAAG,MAAMnF;uBAAsBqF;oBACvD;gBACF;YACF,EAAE,eAAM;YACN,2BAA2B;YAC7B;QACF;QACAA;IACF;IAEA,IAAI,OAAOJ,aAAa,YAAY,OAAOC,OAAOD;IAClD,OAAO,IAAIW,QAAQ,SAACC,SAASC;eAAWZ,OAAO,SAACI,KAAKtF;mBAAWsF,MAAMQ,OAAOR,OAAOO,QAAQ7F;;;AAC9F;AAaO,SAASzB;IACd,IAAMwH,aAAa,IAAIhB,+BAAU;IACjC,8CAA8C;IAC9C,IAAMK,SAASG,IAAAA,uBAAa;IAE5B,oFAAoF;IACpF,IAAMS,mBAAiCZ,CAAAA,mBAAAA,6BAAAA,OAAQa,KAAK,IAChD,SAAC5F,MAAMI,OAAOyF,MAAMf;YAClBC;SAAAA,gBAAAA,OAAOa,KAAK,cAAZb,oCAAAA,mBAAAA,QAAe/E,MAAMI,OAAOyF,MAAMP,IAAI,CACpC,SAAC/D;mBAAWuD,GAAG,MAAMvD;WACrB,SAAC0D;mBAAQH,GAAGG;;IAEhB,IACA,SAACjF,MAAMI,OAAOyF,MAAMf;QAClB,IAAI;YACFA,GAAG,MAAMP,IAAAA,oBAAW,EAACvE,MAAMI,OAAOyF;QACpC,EAAE,OAAOZ,KAAK;YACZH,GAAGG;QACL;IACF;IAEJ,OAAO,IAAIa,8BAAS,CAAC;QACnBC,WAAAA,SAAAA,UAAUC,KAAa,EAAEC,SAAiB,EAAErB,QAAwC;YAClFc,WAAWf,MAAM,CAACqB;YAClBpB;QACF;QAEAsB,OAAAA,SAAAA,MAAMtB,QAAwC;;gBAgC1BlB;YA/BlB,IAAM5C,QAAoB4E;YAE1B,8EAA8E;YAC9E,IAAMlD,UAAUtD,OAAOC,QAAQ,CAAC2B,SAAS,SAAC7B;uBAAmB6B,KAAK,CAAC7B,OAAO;gBAAG,SAACA;uBAAmB6B,MAAM/B,QAAQ,CAACE;;YAEhH,IAAMkH,cAAcjH,OAAOC,QAAQ,CAAC2B,SAAS,SAAC7B;uBAAoBA,SAAS,KAAKA,SAAS,IAAI6B,MAAMzB,MAAM,GAAG,OAAOyB,MAAM1B,YAAY,CAACH;gBAAW,SAACA;uBAAmB6B,MAAMxB,cAAc,CAACL;;YAE1L,IAAMmH,SAAS,gBAACnH,QAAgBO;gBAC9B,IAAIP,SAASO,SAASH,MAAM,GAAGyB,MAAMzB,MAAM,EAAE,OAAO;gBACpD,IAAK,IAAII,IAAI,GAAGA,IAAID,SAASH,MAAM,EAAEI,IAAK;oBACxC,IAAI+C,QAAQvD,SAASQ,OAAOD,QAAQ,CAACC,EAAE,EAAE,OAAO;gBAClD;gBACA,OAAO;YACT;YAEA,2CAA2C;YAC3C,IAAIqB,MAAMzB,MAAM,GAAG,MAAM,CAAC+G,OAAO,GAAGhI,WAAW;gBAC7CwG,SAAS,IAAI/E,MAAM;gBACnB;YACF;YAEA,6BAA6B;YAC7B,IAAM8D,YAAYnB,QAAQ,KAAK;YAE/B,kCAAkC;YAClC,IAAMkB,aAAwC;gBAC5C,GAAG;gBACH,GAAG;gBACH,GAAG;gBACH,IAAI;YACN;YACA,IAAMnB,aAAYmB,wBAAAA,UAAU,CAACC,UAAU,cAArBD,mCAAAA,wBAAyB;YAE3C,2EAA2E;YAC3E,IAAIE,YAAY9C,MAAMzB,MAAM;YAC5B,MAAOuE,YAAY,MAAMpB,QAAQoB,YAAY,OAAO,KAAM;gBACxDA;YACF;YACA,2BAA2B;YAC3B,MAAOA,YAAY,MAAM,KAAKA,YAAY,GAAI;gBAC5CA;YACF;YAEA,yCAAyC;YACzC,IAAI,CAACwC,OAAOxC,YAAY,GAAGvF,kBAAkB;gBAC3CuG,SAAS,IAAI/E,MAAM;gBACnB;YACF;YAEA,uCAAuC;YACvC,IAAMgE,iBAAiBsC,YAAYvC,YAAY;YAC/C,IAAIC,mBAAmB,MAAM;gBAC3Be,SAAS,IAAI/E,MAAM;gBACnB;YACF;YACA,IAAMiE,eAAe,AAACD,CAAAA,iBAAiB,CAAA,IAAK;YAC5C,IAAMvB,aAAasB,YAAY,KAAKE;YAEpC,uCAAuC;YACvC,IAAMC,eAAe1B,WAAWvB,OAAOwB,YAAYC;YAEnD,mDAAmD;YACnD,IAAI8D,aAAa;YACjB,IAAMC,YAAY,oBAACrB;gBACjB,IAAIA,KAAK,OAAOL,SAASK;gBAEzB,IAAIoB,cAActC,aAAa1E,MAAM,EAAE;oBACrC,+DAA+D;oBAC/D,IAAI,CAACH,OAAOC,QAAQ,CAAC2B,QAAQA,MAAMyF,KAAK;oBACxC3B,SAAS;oBACT;gBACF;gBAEA,IAAMxB,SAASW,YAAY,CAACsC,aAAa;gBACzC,IAAMlC,cAAcf,OAAOL,aAAa;gBAExC,oDAAoD;gBACpD,8BAA8B;gBAC9B,IAAMM,gBAAgBb,QAAQ2B;gBAC9B,IAAMlC,aAAa,AAACoB,CAAAA,gBAAgB,CAAA,IAAK;gBAEzC,wCAAwC;gBACxC,IAAMmD,aAAa1F,MAAMgB,KAAK,CAACqC,aAAaA,cAAclC;gBAC1D,IAAMmC,YAAYvD,iBAAiB2F,YAAY,GAAGjE;gBAElD,yCAAyC;gBACzC,IAAML,YAAYiC,cAAclC;gBAChC,IAAME,UAAUD,YAAYkB,OAAOH,kBAAkB;gBACrD,IAAMoB,iBAAiBvD,MAAMgB,KAAK,CAACI,WAAWC;gBAE9C,4DAA4D;gBAC5DwD,iBAAiBtB,gBAAgBD,UAAU3C,UAAU,EAAE2B,OAAOF,gBAAgB,EAAE,SAACuD,WAAWnC;oBAC1F,IAAImC,aAAa,CAACnC,aAAa;wBAC7BgC,UAAUG,aAAa,IAAI5G,MAAM;wBACjC;oBACF;oBAEA,+CAA+C;oBAC/C,IAAK,IAAI2E,IAAIJ,UAAU5C,OAAO,CAACnC,MAAM,GAAG,GAAGmF,KAAK,GAAGA,IAAK;wBACtDF,cAAcvE,YAAYuE,aAAaF,UAAU5C,OAAO,CAACgD,EAAE;oBAC7D;oBAEA,gDAAgD;oBAChD,MAAKzC,IAAI,CAACuC;oBAEV,2BAA2B;oBAC3BgC,UAAU;gBACZ;YACF;YAEA,0BAA0B;YAC1BA,UAAU;QACZ;IACF;AACF"}
|
package/dist/esm/xz/Decoder.js
CHANGED
|
@@ -460,10 +460,7 @@ export function decodeXZ(input, callback) {
|
|
|
460
460
|
// Decompress blocks sequentially (native is async)
|
|
461
461
|
let blockIndex = 0;
|
|
462
462
|
const pushBlock = (err)=>{
|
|
463
|
-
if (err)
|
|
464
|
-
callback(err);
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
463
|
+
if (err) return callback(err);
|
|
467
464
|
if (blockIndex >= blockRecords.length) {
|
|
468
465
|
// All blocks processed - purge input BufferList to free memory
|
|
469
466
|
if (!Buffer.isBuffer(input)) input.clear();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/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 * IMPORTANT: Buffer Management Pattern\n *\n * When calling decodeLzma2(), use the direct return pattern:\n *\n * ✅ CORRECT - Fast path:\n * const output = decodeLzma2(data, props, size) as Buffer;\n *\n * ❌ WRONG - Slow path (do NOT buffer):\n * const chunks: Buffer[] = [];\n * decodeLzma2(data, props, size, { write: c => chunks.push(c) });\n * return Buffer.concat(chunks); // ← Unnecessary copies!\n */\n\nimport { allocBuffer, type BufferLike, BufferList, Transform } from 'extract-base-iterator';\nimport type { Transform as TransformType } from 'stream';\nimport { decodeBcj } from '../filters/bcj/Bcj.ts';\nimport { decodeBcjArm } from '../filters/bcj/BcjArm.ts';\nimport { decodeBcjArm64 } from '../filters/bcj/BcjArm64.ts';\nimport { decodeBcjArmt } from '../filters/bcj/BcjArmt.ts';\nimport { decodeBcjIa64 } from '../filters/bcj/BcjIa64.ts';\nimport { decodeBcjPpc } from '../filters/bcj/BcjPpc.ts';\nimport { decodeBcjSparc } from '../filters/bcj/BcjSparc.ts';\nimport { decodeDelta } from '../filters/delta/Delta.ts';\nimport { decodeLzma2 } from '../lzma/index.ts';\nimport { tryLoadNative } from '../native.ts';\nimport type { DecodeCallback } from '../sevenz.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 (from XZ specification)\nconst FILTER_DELTA = 0x03;\nconst FILTER_BCJ_X86 = 0x04;\nconst FILTER_BCJ_PPC = 0x05;\nconst FILTER_BCJ_IA64 = 0x06;\nconst FILTER_BCJ_ARM = 0x07;\nconst FILTER_BCJ_ARMT = 0x08;\nconst FILTER_BCJ_SPARC = 0x09;\nconst FILTER_BCJ_ARM64 = 0x0a;\nconst FILTER_LZMA2 = 0x21;\n\n// Filter info for parsing\ninterface FilterInfo {\n id: number;\n props: Buffer;\n}\n\n// Re-export BufferLike for public API\nexport type { BufferLike } from 'extract-base-iterator';\n\n/**\n * Read a byte from Buffer or BufferList\n */\nfunction readByte(buf: BufferLike, offset: number): number {\n return Buffer.isBuffer(buf) ? buf[offset] : buf.readByte(offset);\n}\n\n/**\n * Read UInt32LE from Buffer or BufferList (returns null if out of bounds)\n */\nfunction readUInt32LE(buf: BufferLike, offset: number): number | null {\n if (Buffer.isBuffer(buf)) {\n if (offset < 0 || offset + 4 > buf.length) return null;\n return buf.readUInt32LE(offset);\n }\n return buf.readUInt32LEAt(offset);\n}\n\n/**\n * Compare buffer contents at offset with expected byte sequence\n * Works with both Buffer and BufferList\n */\nfunction bufferEquals(buf: BufferLike, 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 (readByte(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 * Works with both Buffer and BufferList\n */\nfunction decodeMultibyte(buf: BufferLike, 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 = readByte(buf, offset + i);\n value |= (byte & 0x7f) << (i * 7);\n i++;\n if (i > 4) {\n throw new Error('Multibyte integer too large');\n }\n } while (byte & 0x80);\n return { value, bytesRead: i };\n}\n\n/**\n * Apply a preprocessing filter (BCJ/Delta) to decompressed data\n */\nfunction applyFilter(data: Buffer, filter: FilterInfo): Buffer {\n switch (filter.id) {\n case FILTER_BCJ_X86:\n return decodeBcj(data, filter.props);\n case FILTER_BCJ_ARM:\n return decodeBcjArm(data, filter.props);\n case FILTER_BCJ_ARM64:\n return decodeBcjArm64(data, filter.props);\n case FILTER_BCJ_ARMT:\n return decodeBcjArmt(data, filter.props);\n case FILTER_BCJ_PPC:\n return decodeBcjPpc(data, filter.props);\n case FILTER_BCJ_SPARC:\n return decodeBcjSparc(data, filter.props);\n case FILTER_BCJ_IA64:\n return decodeBcjIa64(data, filter.props);\n case FILTER_DELTA:\n return decodeDelta(data, filter.props);\n default:\n throw new Error(`Unsupported filter: 0x${filter.id.toString(16)}`);\n }\n}\n\n/**\n * Parse XZ Block Header to extract filters and LZMA2 properties\n */\nfunction parseBlockHeader(\n input: Buffer,\n offset: number,\n _checkSize: number\n): {\n filters: FilterInfo[];\n lzma2Props: Buffer;\n headerSize: number;\n dataStart: number;\n dataEnd: number;\n nextOffset: number;\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\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 if (hasUncompressedSize) {\n const result = decodeMultibyte(input, offset);\n offset += result.bytesRead;\n }\n\n // Parse all filters\n const filters: FilterInfo[] = [];\n let lzma2Props: Buffer | null = null;\n\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 // LZMA2 must be the last filter\n lzma2Props = filterProps;\n } else if (filterId === FILTER_DELTA || (filterId >= FILTER_BCJ_X86 && filterId <= FILTER_BCJ_ARM64)) {\n // Preprocessing filter - store for later application\n filters.push({ id: filterId, props: filterProps });\n } else {\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 (must be aligned to 4 bytes)\n const blockDataStart = blockHeaderStart + blockHeaderSize;\n\n return {\n filters,\n lzma2Props,\n headerSize: blockHeaderSize,\n dataStart: blockDataStart,\n dataEnd: input.length,\n nextOffset: blockDataStart,\n };\n}\n\n/**\n * Parse XZ Index to get block positions\n * Works with both Buffer and BufferList\n */\nfunction parseIndex(\n input: BufferLike,\n indexStart: number,\n checkSize: number\n): Array<{\n compressedPos: number;\n compressedDataSize: number;\n uncompressedSize: number;\n}> {\n // One-time binding for buffer access (avoids repeated Buffer.isBuffer checks)\n const getByte = Buffer.isBuffer(input) ? (offset: number) => input[offset] : (offset: number) => input.readByte(offset);\n\n // Local multibyte decoder using bound getByte\n const decodeMultibyteLocal = (offset: number): { value: number; bytesRead: number } => {\n let value = 0;\n let i = 0;\n let byte: number;\n do {\n if (offset + i >= input.length) {\n throw new Error('Truncated multibyte integer');\n }\n byte = getByte(offset + i);\n value |= (byte & 0x7f) << (i * 7);\n i++;\n if (i > 4) {\n throw new Error('Multibyte integer too large');\n }\n } while (byte & 0x80);\n return { value, bytesRead: i };\n };\n\n let offset = indexStart;\n\n // Index indicator (0x00)\n if (getByte(offset) !== 0x00) {\n throw new Error('Invalid index indicator');\n }\n offset++;\n\n // Number of records\n const countResult = decodeMultibyteLocal(offset);\n const recordCount = countResult.value;\n offset += countResult.bytesRead;\n\n const records: Array<{\n compressedPos: number;\n unpaddedSize: number;\n compressedDataSize: number;\n uncompressedSize: number;\n }> = [];\n\n // Parse each record\n for (let i = 0; i < recordCount; i++) {\n // Unpadded Size (header + compressed data + check)\n const unpaddedResult = decodeMultibyteLocal(offset);\n offset += unpaddedResult.bytesRead;\n\n // Uncompressed size\n const uncompressedResult = decodeMultibyteLocal(offset);\n offset += uncompressedResult.bytesRead;\n\n records.push({\n compressedPos: 0, // will be calculated\n unpaddedSize: unpaddedResult.value,\n compressedDataSize: 0, // will be calculated\n uncompressedSize: uncompressedResult.value,\n });\n }\n\n // Calculate actual positions by walking through blocks\n let currentPos = 12; // After stream header\n for (let i = 0; i < records.length; i++) {\n const record = records[i];\n // Record where this block's header starts\n record.compressedPos = currentPos;\n\n // Get block header size from the actual data\n const headerSizeRaw = getByte(currentPos);\n const headerSize = (headerSizeRaw + 1) * 4;\n\n // Calculate compressed data size from unpadded size\n record.compressedDataSize = record.unpaddedSize - headerSize - checkSize;\n\n // Move to next block: unpaddedSize + padding to 4-byte boundary\n const paddedSize = Math.ceil(record.unpaddedSize / 4) * 4;\n currentPos += paddedSize;\n }\n\n return records;\n}\n\n/**\n * Pure JS XZ decompression (handles all XZ spec features)\n * Returns BufferList for memory efficiency with large files.\n */\nfunction decodeXZPure(input: Buffer): Buffer | BufferList {\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 = readByte(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 // Find footer by skipping stream padding (null bytes at end before footer)\n // Stream padding must be multiple of 4 bytes\n let footerEnd = input.length;\n while (footerEnd > 12 && readByte(input, footerEnd - 1) === 0x00) {\n footerEnd--;\n }\n // Align to 4-byte boundary (stream padding rules)\n while (footerEnd % 4 !== 0 && footerEnd > 12) {\n footerEnd++;\n }\n\n // Verify footer magic (at footerEnd - 2)\n if (!bufferEquals(input, footerEnd - 2, XZ_FOOTER_MAGIC)) {\n throw new Error('Invalid XZ footer magic');\n }\n\n // Get backward size (tells us where index starts) - at footerEnd - 8\n const backwardSizeLE = readUInt32LE(input, footerEnd - 8);\n if (backwardSizeLE === null) {\n throw new Error('Invalid backward size');\n }\n const backwardSize = (backwardSizeLE + 1) * 4;\n const indexStart = footerEnd - 12 - backwardSize;\n\n // Parse Index to get block information\n const blockRecords = parseIndex(input, indexStart, checkSize);\n\n // Handle empty files (no blocks) - return empty buffer\n if (blockRecords.length === 0) return allocBuffer(0);\n\n // Calculate total uncompressed size for multi-block decision\n let totalUncompressedSize = 0;\n for (let i = 0; i < blockRecords.length; i++) {\n totalUncompressedSize += blockRecords[i].uncompressedSize;\n }\n\n // Small multi-block files: use Buffer.concat directly (avoids BufferList overhead)\n // Threshold of 64KB: below this, the overhead of linked list nodes isn't worth it\n const BUFFERLIST_THRESHOLD = 64 * 1024; // 64KB\n\n // Single block OR small multi-block: return Buffer directly\n if (blockRecords.length === 1 || totalUncompressedSize < BUFFERLIST_THRESHOLD) {\n const record = blockRecords[0];\n const recordStart = record.compressedPos;\n const blockInfo = parseBlockHeader(input, recordStart, checkSize);\n const dataStart = recordStart + blockInfo.headerSize;\n const dataEnd = dataStart + record.compressedDataSize;\n const compressedData = input.slice(dataStart, dataEnd);\n\n let blockOutput = decodeLzma2(compressedData, blockInfo.lzma2Props, record.uncompressedSize) as Buffer;\n\n for (let j = blockInfo.filters.length - 1; j >= 0; j--) {\n blockOutput = applyFilter(blockOutput, blockInfo.filters[j]) as Buffer;\n }\n\n return blockOutput;\n }\n\n // Multi-block (large): use BufferList to avoid large contiguous allocation\n const output = new BufferList();\n\n for (let i = 0; i < blockRecords.length; i++) {\n const record = blockRecords[i];\n const recordStart = record.compressedPos;\n\n // Parse block header\n const blockInfo = parseBlockHeader(input, recordStart, checkSize);\n\n // Extract compressed data for this block\n const dataStart = recordStart + blockInfo.headerSize;\n const dataEnd = dataStart + record.compressedDataSize;\n\n // Note: XZ blocks have padding AFTER the check field to align to 4 bytes,\n // but the compressedSize from index is exact - no need to strip padding.\n // LZMA2 data includes a 0x00 end marker which must NOT be stripped.\n const compressedData = input.slice(dataStart, dataEnd);\n\n // Decompress this block with LZMA2 (fast path, no buffering)\n let blockOutput = decodeLzma2(compressedData, blockInfo.lzma2Props, record.uncompressedSize) as Buffer;\n\n // Apply preprocessing filters in reverse order (BCJ/Delta applied after LZMA2)\n // Filters are stored in order they were applied during compression,\n // so we need to reverse for decompression\n for (let j = blockInfo.filters.length - 1; j >= 0; j--) {\n blockOutput = applyFilter(blockOutput, blockInfo.filters[j]) as Buffer;\n }\n\n // Append block to BufferList\n output.append(blockOutput);\n }\n\n return output;\n}\n\n/** Callback invoked when an async decode completes */\nexport type XzDecodeCallback = DecodeCallback<BufferLike>;\n\n/**\n * Decompress XZ data. With a callback the result is provided asynchronously;\n * otherwise a Promise resolves with the decoded data.\n *\n * Returns Buffer for single-block files (most small files).\n * Returns BufferList for multi-block files (avoids large contiguous allocation).\n */\nexport function decodeXZ(input: Buffer, callback: XzDecodeCallback): void;\nexport function decodeXZ(input: Buffer): Promise<BufferLike>;\nexport function decodeXZ(input: Buffer, callback?: XzDecodeCallback): Promise<BufferLike> | void {\n const worker = (cb: XzDecodeCallback) => {\n const fallback = () => {\n try {\n cb(null, decodeXZPure(input));\n } catch (err) {\n cb(err as Error);\n }\n };\n\n const native = tryLoadNative();\n if (native?.xz?.decompress) {\n try {\n const promise = native.xz.decompress(input);\n if (promise && typeof promise.then === 'function') {\n promise.then((value) => cb(null, value as BufferLike), fallback);\n return;\n }\n } catch {\n // fall through to fallback\n }\n }\n fallback();\n };\n\n if (typeof callback === 'function') return worker(callback);\n return new Promise((resolve, reject) => worker((err, value) => (err ? reject(err) : resolve(value as BufferLike))));\n}\n\n// Callback-based LZMA2 decoder type (for Node 0.8+ compatibility - no promises)\ntype Lzma2DecodeCallback = (err: Error | null, result?: Buffer) => void;\ntype Lzma2Decoder = (data: Buffer, props: Buffer, size: number, callback: Lzma2DecodeCallback) => void;\n\n/**\n * Create an XZ decompression Transform stream\n * @returns Transform stream that decompresses XZ data\n *\n * Uses native lzma-native bindings when available for better performance.\n * Falls back to pure JS implementation on older Node versions or when native is unavailable.\n */\nexport function createXZDecoder(): TransformType {\n const bufferList = new BufferList();\n // Cache native module lookup (only done once)\n const native = tryLoadNative();\n\n // Choose decoder: native (async via callback) or pure JS (sync wrapped in callback)\n const decodeLzma2Block: Lzma2Decoder = native?.lzma2\n ? (data, props, size, cb) => {\n native.lzma2?.(data, props, size).then(\n (result) => cb(null, result),\n (err) => cb(err)\n );\n }\n : (data, props, size, cb) => {\n try {\n cb(null, decodeLzma2(data, props, size) as Buffer);\n } catch (err) {\n cb(err as Error);\n }\n };\n\n return new Transform({\n transform(chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void) {\n bufferList.append(chunk);\n callback();\n },\n\n flush(callback: (error?: Error | null) => void) {\n const input: BufferLike = bufferList;\n\n // One-time binding for buffer access (avoids repeated Buffer.isBuffer checks)\n const getByte = Buffer.isBuffer(input) ? (offset: number) => input[offset] : (offset: number) => input.readByte(offset);\n\n const getUInt32LE = Buffer.isBuffer(input) ? (offset: number) => (offset < 0 || offset + 4 > input.length ? null : input.readUInt32LE(offset)) : (offset: number) => input.readUInt32LEAt(offset);\n\n const equals = (offset: number, expected: number[]): boolean => {\n if (offset + expected.length > input.length) return false;\n for (let i = 0; i < expected.length; i++) {\n if (getByte(offset + i) !== expected[i]) return false;\n }\n return true;\n };\n\n // Verify XZ magic (need at least 12 bytes)\n if (input.length < 12 || !equals(0, XZ_MAGIC)) {\n callback(new Error('Invalid XZ magic bytes'));\n return;\n }\n\n // Stream flags at offset 6-7\n const checkType = getByte(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 // Find footer by skipping stream padding (null bytes at end before footer)\n let footerEnd = input.length;\n while (footerEnd > 12 && getByte(footerEnd - 1) === 0x00) {\n footerEnd--;\n }\n // Align to 4-byte boundary\n while (footerEnd % 4 !== 0 && footerEnd > 12) {\n footerEnd++;\n }\n\n // Verify footer magic (at footerEnd - 2)\n if (!equals(footerEnd - 2, XZ_FOOTER_MAGIC)) {\n callback(new Error('Invalid XZ footer magic'));\n return;\n }\n\n // Get backward size (at footerEnd - 8)\n const backwardSizeLE = getUInt32LE(footerEnd - 8);\n if (backwardSizeLE === null) {\n callback(new Error('Invalid backward size'));\n return;\n }\n const backwardSize = (backwardSizeLE + 1) * 4;\n const indexStart = footerEnd - 12 - backwardSize;\n\n // Parse Index to get block information\n const blockRecords = parseIndex(input, indexStart, checkSize);\n\n // Decompress blocks sequentially (native is async)\n let blockIndex = 0;\n const pushBlock = (err: Error | null) => {\n if (err) {\n callback(err);\n return;\n }\n\n if (blockIndex >= blockRecords.length) {\n // All blocks processed - purge input BufferList to free memory\n if (!Buffer.isBuffer(input)) input.clear();\n callback(null);\n return;\n }\n\n const record = blockRecords[blockIndex++];\n const recordStart = record.compressedPos;\n\n // Parse block header (need to get the header bytes)\n // Read header size byte first\n const headerSizeRaw = getByte(recordStart);\n const headerSize = (headerSizeRaw + 1) * 4;\n\n // Read the full header to parse filters\n const headerData = input.slice(recordStart, recordStart + headerSize);\n const blockInfo = parseBlockHeader(headerData, 0, checkSize);\n\n // Extract compressed data for this block\n const dataStart = recordStart + headerSize;\n const dataEnd = dataStart + record.compressedDataSize;\n const compressedData = input.slice(dataStart, dataEnd);\n\n // Decompress this block (native or pure JS, callback-based)\n decodeLzma2Block(compressedData, blockInfo.lzma2Props, record.uncompressedSize, (decodeErr, blockOutput) => {\n if (decodeErr || !blockOutput) {\n pushBlock(decodeErr || new Error('Decode returned no data'));\n return;\n }\n\n // Apply preprocessing filters in reverse order\n for (let j = blockInfo.filters.length - 1; j >= 0; j--) {\n blockOutput = applyFilter(blockOutput, blockInfo.filters[j]) as Buffer;\n }\n\n // Push the block output immediately (streaming)\n this.push(blockOutput);\n\n // Continue with next block\n pushBlock(null);\n });\n };\n\n // Start processing blocks\n pushBlock(null);\n },\n });\n}\n"],"names":["allocBuffer","BufferList","Transform","decodeBcj","decodeBcjArm","decodeBcjArm64","decodeBcjArmt","decodeBcjIa64","decodeBcjPpc","decodeBcjSparc","decodeDelta","decodeLzma2","tryLoadNative","XZ_MAGIC","XZ_FOOTER_MAGIC","FILTER_DELTA","FILTER_BCJ_X86","FILTER_BCJ_PPC","FILTER_BCJ_IA64","FILTER_BCJ_ARM","FILTER_BCJ_ARMT","FILTER_BCJ_SPARC","FILTER_BCJ_ARM64","FILTER_LZMA2","readByte","buf","offset","Buffer","isBuffer","readUInt32LE","length","readUInt32LEAt","bufferEquals","expected","i","decodeMultibyte","value","byte","Error","bytesRead","applyFilter","data","filter","id","props","toString","parseBlockHeader","input","_checkSize","blockHeaderSizeRaw","blockHeaderSize","blockHeaderStart","blockFlags","numFilters","hasCompressedSize","hasUncompressedSize","result","filters","lzma2Props","filterIdResult","filterId","propsSizeResult","filterProps","slice","push","blockDataStart","headerSize","dataStart","dataEnd","nextOffset","parseIndex","indexStart","checkSize","getByte","decodeMultibyteLocal","countResult","recordCount","records","unpaddedResult","uncompressedResult","compressedPos","unpaddedSize","compressedDataSize","uncompressedSize","currentPos","record","headerSizeRaw","paddedSize","Math","ceil","decodeXZPure","checkSizes","checkType","footerEnd","backwardSizeLE","backwardSize","blockRecords","totalUncompressedSize","BUFFERLIST_THRESHOLD","recordStart","blockInfo","compressedData","blockOutput","j","output","append","decodeXZ","callback","worker","cb","native","fallback","err","xz","decompress","promise","then","Promise","resolve","reject","createXZDecoder","bufferList","decodeLzma2Block","lzma2","size","transform","chunk","_encoding","flush","getUInt32LE","equals","blockIndex","pushBlock","clear","headerData","decodeErr"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/iterators/xz-compat/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 * IMPORTANT: Buffer Management Pattern\n *\n * When calling decodeLzma2(), use the direct return pattern:\n *\n * ✅ CORRECT - Fast path:\n * const output = decodeLzma2(data, props, size) as Buffer;\n *\n * ❌ WRONG - Slow path (do NOT buffer):\n * const chunks: Buffer[] = [];\n * decodeLzma2(data, props, size, { write: c => chunks.push(c) });\n * return Buffer.concat(chunks); // ← Unnecessary copies!\n */\n\nimport { allocBuffer, type BufferLike, BufferList, Transform } from 'extract-base-iterator';\nimport type { Transform as TransformType } from 'stream';\nimport { decodeBcj } from '../filters/bcj/Bcj.ts';\nimport { decodeBcjArm } from '../filters/bcj/BcjArm.ts';\nimport { decodeBcjArm64 } from '../filters/bcj/BcjArm64.ts';\nimport { decodeBcjArmt } from '../filters/bcj/BcjArmt.ts';\nimport { decodeBcjIa64 } from '../filters/bcj/BcjIa64.ts';\nimport { decodeBcjPpc } from '../filters/bcj/BcjPpc.ts';\nimport { decodeBcjSparc } from '../filters/bcj/BcjSparc.ts';\nimport { decodeDelta } from '../filters/delta/Delta.ts';\nimport { decodeLzma2 } from '../lzma/index.ts';\nimport { tryLoadNative } from '../native.ts';\nimport type { DecodeCallback } from '../sevenz.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 (from XZ specification)\nconst FILTER_DELTA = 0x03;\nconst FILTER_BCJ_X86 = 0x04;\nconst FILTER_BCJ_PPC = 0x05;\nconst FILTER_BCJ_IA64 = 0x06;\nconst FILTER_BCJ_ARM = 0x07;\nconst FILTER_BCJ_ARMT = 0x08;\nconst FILTER_BCJ_SPARC = 0x09;\nconst FILTER_BCJ_ARM64 = 0x0a;\nconst FILTER_LZMA2 = 0x21;\n\n// Filter info for parsing\ninterface FilterInfo {\n id: number;\n props: Buffer;\n}\n\n// Re-export BufferLike for public API\nexport type { BufferLike } from 'extract-base-iterator';\n\n/**\n * Read a byte from Buffer or BufferList\n */\nfunction readByte(buf: BufferLike, offset: number): number {\n return Buffer.isBuffer(buf) ? buf[offset] : buf.readByte(offset);\n}\n\n/**\n * Read UInt32LE from Buffer or BufferList (returns null if out of bounds)\n */\nfunction readUInt32LE(buf: BufferLike, offset: number): number | null {\n if (Buffer.isBuffer(buf)) {\n if (offset < 0 || offset + 4 > buf.length) return null;\n return buf.readUInt32LE(offset);\n }\n return buf.readUInt32LEAt(offset);\n}\n\n/**\n * Compare buffer contents at offset with expected byte sequence\n * Works with both Buffer and BufferList\n */\nfunction bufferEquals(buf: BufferLike, 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 (readByte(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 * Works with both Buffer and BufferList\n */\nfunction decodeMultibyte(buf: BufferLike, 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 = readByte(buf, offset + i);\n value |= (byte & 0x7f) << (i * 7);\n i++;\n if (i > 4) {\n throw new Error('Multibyte integer too large');\n }\n } while (byte & 0x80);\n return { value, bytesRead: i };\n}\n\n/**\n * Apply a preprocessing filter (BCJ/Delta) to decompressed data\n */\nfunction applyFilter(data: Buffer, filter: FilterInfo): Buffer {\n switch (filter.id) {\n case FILTER_BCJ_X86:\n return decodeBcj(data, filter.props);\n case FILTER_BCJ_ARM:\n return decodeBcjArm(data, filter.props);\n case FILTER_BCJ_ARM64:\n return decodeBcjArm64(data, filter.props);\n case FILTER_BCJ_ARMT:\n return decodeBcjArmt(data, filter.props);\n case FILTER_BCJ_PPC:\n return decodeBcjPpc(data, filter.props);\n case FILTER_BCJ_SPARC:\n return decodeBcjSparc(data, filter.props);\n case FILTER_BCJ_IA64:\n return decodeBcjIa64(data, filter.props);\n case FILTER_DELTA:\n return decodeDelta(data, filter.props);\n default:\n throw new Error(`Unsupported filter: 0x${filter.id.toString(16)}`);\n }\n}\n\n/**\n * Parse XZ Block Header to extract filters and LZMA2 properties\n */\nfunction parseBlockHeader(\n input: Buffer,\n offset: number,\n _checkSize: number\n): {\n filters: FilterInfo[];\n lzma2Props: Buffer;\n headerSize: number;\n dataStart: number;\n dataEnd: number;\n nextOffset: number;\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\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 if (hasUncompressedSize) {\n const result = decodeMultibyte(input, offset);\n offset += result.bytesRead;\n }\n\n // Parse all filters\n const filters: FilterInfo[] = [];\n let lzma2Props: Buffer | null = null;\n\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 // LZMA2 must be the last filter\n lzma2Props = filterProps;\n } else if (filterId === FILTER_DELTA || (filterId >= FILTER_BCJ_X86 && filterId <= FILTER_BCJ_ARM64)) {\n // Preprocessing filter - store for later application\n filters.push({ id: filterId, props: filterProps });\n } else {\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 (must be aligned to 4 bytes)\n const blockDataStart = blockHeaderStart + blockHeaderSize;\n\n return {\n filters,\n lzma2Props,\n headerSize: blockHeaderSize,\n dataStart: blockDataStart,\n dataEnd: input.length,\n nextOffset: blockDataStart,\n };\n}\n\n/**\n * Parse XZ Index to get block positions\n * Works with both Buffer and BufferList\n */\nfunction parseIndex(\n input: BufferLike,\n indexStart: number,\n checkSize: number\n): Array<{\n compressedPos: number;\n compressedDataSize: number;\n uncompressedSize: number;\n}> {\n // One-time binding for buffer access (avoids repeated Buffer.isBuffer checks)\n const getByte = Buffer.isBuffer(input) ? (offset: number) => input[offset] : (offset: number) => input.readByte(offset);\n\n // Local multibyte decoder using bound getByte\n const decodeMultibyteLocal = (offset: number): { value: number; bytesRead: number } => {\n let value = 0;\n let i = 0;\n let byte: number;\n do {\n if (offset + i >= input.length) {\n throw new Error('Truncated multibyte integer');\n }\n byte = getByte(offset + i);\n value |= (byte & 0x7f) << (i * 7);\n i++;\n if (i > 4) {\n throw new Error('Multibyte integer too large');\n }\n } while (byte & 0x80);\n return { value, bytesRead: i };\n };\n\n let offset = indexStart;\n\n // Index indicator (0x00)\n if (getByte(offset) !== 0x00) {\n throw new Error('Invalid index indicator');\n }\n offset++;\n\n // Number of records\n const countResult = decodeMultibyteLocal(offset);\n const recordCount = countResult.value;\n offset += countResult.bytesRead;\n\n const records: Array<{\n compressedPos: number;\n unpaddedSize: number;\n compressedDataSize: number;\n uncompressedSize: number;\n }> = [];\n\n // Parse each record\n for (let i = 0; i < recordCount; i++) {\n // Unpadded Size (header + compressed data + check)\n const unpaddedResult = decodeMultibyteLocal(offset);\n offset += unpaddedResult.bytesRead;\n\n // Uncompressed size\n const uncompressedResult = decodeMultibyteLocal(offset);\n offset += uncompressedResult.bytesRead;\n\n records.push({\n compressedPos: 0, // will be calculated\n unpaddedSize: unpaddedResult.value,\n compressedDataSize: 0, // will be calculated\n uncompressedSize: uncompressedResult.value,\n });\n }\n\n // Calculate actual positions by walking through blocks\n let currentPos = 12; // After stream header\n for (let i = 0; i < records.length; i++) {\n const record = records[i];\n // Record where this block's header starts\n record.compressedPos = currentPos;\n\n // Get block header size from the actual data\n const headerSizeRaw = getByte(currentPos);\n const headerSize = (headerSizeRaw + 1) * 4;\n\n // Calculate compressed data size from unpadded size\n record.compressedDataSize = record.unpaddedSize - headerSize - checkSize;\n\n // Move to next block: unpaddedSize + padding to 4-byte boundary\n const paddedSize = Math.ceil(record.unpaddedSize / 4) * 4;\n currentPos += paddedSize;\n }\n\n return records;\n}\n\n/**\n * Pure JS XZ decompression (handles all XZ spec features)\n * Returns BufferList for memory efficiency with large files.\n */\nfunction decodeXZPure(input: Buffer): Buffer | BufferList {\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 = readByte(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 // Find footer by skipping stream padding (null bytes at end before footer)\n // Stream padding must be multiple of 4 bytes\n let footerEnd = input.length;\n while (footerEnd > 12 && readByte(input, footerEnd - 1) === 0x00) {\n footerEnd--;\n }\n // Align to 4-byte boundary (stream padding rules)\n while (footerEnd % 4 !== 0 && footerEnd > 12) {\n footerEnd++;\n }\n\n // Verify footer magic (at footerEnd - 2)\n if (!bufferEquals(input, footerEnd - 2, XZ_FOOTER_MAGIC)) {\n throw new Error('Invalid XZ footer magic');\n }\n\n // Get backward size (tells us where index starts) - at footerEnd - 8\n const backwardSizeLE = readUInt32LE(input, footerEnd - 8);\n if (backwardSizeLE === null) {\n throw new Error('Invalid backward size');\n }\n const backwardSize = (backwardSizeLE + 1) * 4;\n const indexStart = footerEnd - 12 - backwardSize;\n\n // Parse Index to get block information\n const blockRecords = parseIndex(input, indexStart, checkSize);\n\n // Handle empty files (no blocks) - return empty buffer\n if (blockRecords.length === 0) return allocBuffer(0);\n\n // Calculate total uncompressed size for multi-block decision\n let totalUncompressedSize = 0;\n for (let i = 0; i < blockRecords.length; i++) {\n totalUncompressedSize += blockRecords[i].uncompressedSize;\n }\n\n // Small multi-block files: use Buffer.concat directly (avoids BufferList overhead)\n // Threshold of 64KB: below this, the overhead of linked list nodes isn't worth it\n const BUFFERLIST_THRESHOLD = 64 * 1024; // 64KB\n\n // Single block OR small multi-block: return Buffer directly\n if (blockRecords.length === 1 || totalUncompressedSize < BUFFERLIST_THRESHOLD) {\n const record = blockRecords[0];\n const recordStart = record.compressedPos;\n const blockInfo = parseBlockHeader(input, recordStart, checkSize);\n const dataStart = recordStart + blockInfo.headerSize;\n const dataEnd = dataStart + record.compressedDataSize;\n const compressedData = input.slice(dataStart, dataEnd);\n\n let blockOutput = decodeLzma2(compressedData, blockInfo.lzma2Props, record.uncompressedSize) as Buffer;\n\n for (let j = blockInfo.filters.length - 1; j >= 0; j--) {\n blockOutput = applyFilter(blockOutput, blockInfo.filters[j]) as Buffer;\n }\n\n return blockOutput;\n }\n\n // Multi-block (large): use BufferList to avoid large contiguous allocation\n const output = new BufferList();\n\n for (let i = 0; i < blockRecords.length; i++) {\n const record = blockRecords[i];\n const recordStart = record.compressedPos;\n\n // Parse block header\n const blockInfo = parseBlockHeader(input, recordStart, checkSize);\n\n // Extract compressed data for this block\n const dataStart = recordStart + blockInfo.headerSize;\n const dataEnd = dataStart + record.compressedDataSize;\n\n // Note: XZ blocks have padding AFTER the check field to align to 4 bytes,\n // but the compressedSize from index is exact - no need to strip padding.\n // LZMA2 data includes a 0x00 end marker which must NOT be stripped.\n const compressedData = input.slice(dataStart, dataEnd);\n\n // Decompress this block with LZMA2 (fast path, no buffering)\n let blockOutput = decodeLzma2(compressedData, blockInfo.lzma2Props, record.uncompressedSize) as Buffer;\n\n // Apply preprocessing filters in reverse order (BCJ/Delta applied after LZMA2)\n // Filters are stored in order they were applied during compression,\n // so we need to reverse for decompression\n for (let j = blockInfo.filters.length - 1; j >= 0; j--) {\n blockOutput = applyFilter(blockOutput, blockInfo.filters[j]) as Buffer;\n }\n\n // Append block to BufferList\n output.append(blockOutput);\n }\n\n return output;\n}\n\n/** Callback invoked when an async decode completes */\nexport type XzDecodeCallback = DecodeCallback<BufferLike>;\n\n/**\n * Decompress XZ data. With a callback the result is provided asynchronously;\n * otherwise a Promise resolves with the decoded data.\n *\n * Returns Buffer for single-block files (most small files).\n * Returns BufferList for multi-block files (avoids large contiguous allocation).\n */\nexport function decodeXZ(input: Buffer, callback: XzDecodeCallback): void;\nexport function decodeXZ(input: Buffer): Promise<BufferLike>;\nexport function decodeXZ(input: Buffer, callback?: XzDecodeCallback): Promise<BufferLike> | void {\n const worker = (cb: XzDecodeCallback) => {\n const fallback = () => {\n try {\n cb(null, decodeXZPure(input));\n } catch (err) {\n cb(err as Error);\n }\n };\n\n const native = tryLoadNative();\n if (native?.xz?.decompress) {\n try {\n const promise = native.xz.decompress(input);\n if (promise && typeof promise.then === 'function') {\n promise.then((value) => cb(null, value as BufferLike), fallback);\n return;\n }\n } catch {\n // fall through to fallback\n }\n }\n fallback();\n };\n\n if (typeof callback === 'function') return worker(callback);\n return new Promise((resolve, reject) => worker((err, value) => (err ? reject(err) : resolve(value as BufferLike))));\n}\n\n// Callback-based LZMA2 decoder type (for Node 0.8+ compatibility - no promises)\ntype Lzma2DecodeCallback = (err: Error | null, result?: Buffer) => void;\ntype Lzma2Decoder = (data: Buffer, props: Buffer, size: number, callback: Lzma2DecodeCallback) => void;\n\n/**\n * Create an XZ decompression Transform stream\n * @returns Transform stream that decompresses XZ data\n *\n * Uses native lzma-native bindings when available for better performance.\n * Falls back to pure JS implementation on older Node versions or when native is unavailable.\n */\nexport function createXZDecoder(): TransformType {\n const bufferList = new BufferList();\n // Cache native module lookup (only done once)\n const native = tryLoadNative();\n\n // Choose decoder: native (async via callback) or pure JS (sync wrapped in callback)\n const decodeLzma2Block: Lzma2Decoder = native?.lzma2\n ? (data, props, size, cb) => {\n native.lzma2?.(data, props, size).then(\n (result) => cb(null, result),\n (err) => cb(err)\n );\n }\n : (data, props, size, cb) => {\n try {\n cb(null, decodeLzma2(data, props, size) as Buffer);\n } catch (err) {\n cb(err as Error);\n }\n };\n\n return new Transform({\n transform(chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void) {\n bufferList.append(chunk);\n callback();\n },\n\n flush(callback: (error?: Error | null) => void) {\n const input: BufferLike = bufferList;\n\n // One-time binding for buffer access (avoids repeated Buffer.isBuffer checks)\n const getByte = Buffer.isBuffer(input) ? (offset: number) => input[offset] : (offset: number) => input.readByte(offset);\n\n const getUInt32LE = Buffer.isBuffer(input) ? (offset: number) => (offset < 0 || offset + 4 > input.length ? null : input.readUInt32LE(offset)) : (offset: number) => input.readUInt32LEAt(offset);\n\n const equals = (offset: number, expected: number[]): boolean => {\n if (offset + expected.length > input.length) return false;\n for (let i = 0; i < expected.length; i++) {\n if (getByte(offset + i) !== expected[i]) return false;\n }\n return true;\n };\n\n // Verify XZ magic (need at least 12 bytes)\n if (input.length < 12 || !equals(0, XZ_MAGIC)) {\n callback(new Error('Invalid XZ magic bytes'));\n return;\n }\n\n // Stream flags at offset 6-7\n const checkType = getByte(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 // Find footer by skipping stream padding (null bytes at end before footer)\n let footerEnd = input.length;\n while (footerEnd > 12 && getByte(footerEnd - 1) === 0x00) {\n footerEnd--;\n }\n // Align to 4-byte boundary\n while (footerEnd % 4 !== 0 && footerEnd > 12) {\n footerEnd++;\n }\n\n // Verify footer magic (at footerEnd - 2)\n if (!equals(footerEnd - 2, XZ_FOOTER_MAGIC)) {\n callback(new Error('Invalid XZ footer magic'));\n return;\n }\n\n // Get backward size (at footerEnd - 8)\n const backwardSizeLE = getUInt32LE(footerEnd - 8);\n if (backwardSizeLE === null) {\n callback(new Error('Invalid backward size'));\n return;\n }\n const backwardSize = (backwardSizeLE + 1) * 4;\n const indexStart = footerEnd - 12 - backwardSize;\n\n // Parse Index to get block information\n const blockRecords = parseIndex(input, indexStart, checkSize);\n\n // Decompress blocks sequentially (native is async)\n let blockIndex = 0;\n const pushBlock = (err: Error | null) => {\n if (err) return callback(err);\n\n if (blockIndex >= blockRecords.length) {\n // All blocks processed - purge input BufferList to free memory\n if (!Buffer.isBuffer(input)) input.clear();\n callback(null);\n return;\n }\n\n const record = blockRecords[blockIndex++];\n const recordStart = record.compressedPos;\n\n // Parse block header (need to get the header bytes)\n // Read header size byte first\n const headerSizeRaw = getByte(recordStart);\n const headerSize = (headerSizeRaw + 1) * 4;\n\n // Read the full header to parse filters\n const headerData = input.slice(recordStart, recordStart + headerSize);\n const blockInfo = parseBlockHeader(headerData, 0, checkSize);\n\n // Extract compressed data for this block\n const dataStart = recordStart + headerSize;\n const dataEnd = dataStart + record.compressedDataSize;\n const compressedData = input.slice(dataStart, dataEnd);\n\n // Decompress this block (native or pure JS, callback-based)\n decodeLzma2Block(compressedData, blockInfo.lzma2Props, record.uncompressedSize, (decodeErr, blockOutput) => {\n if (decodeErr || !blockOutput) {\n pushBlock(decodeErr || new Error('Decode returned no data'));\n return;\n }\n\n // Apply preprocessing filters in reverse order\n for (let j = blockInfo.filters.length - 1; j >= 0; j--) {\n blockOutput = applyFilter(blockOutput, blockInfo.filters[j]) as Buffer;\n }\n\n // Push the block output immediately (streaming)\n this.push(blockOutput);\n\n // Continue with next block\n pushBlock(null);\n });\n };\n\n // Start processing blocks\n pushBlock(null);\n },\n });\n}\n"],"names":["allocBuffer","BufferList","Transform","decodeBcj","decodeBcjArm","decodeBcjArm64","decodeBcjArmt","decodeBcjIa64","decodeBcjPpc","decodeBcjSparc","decodeDelta","decodeLzma2","tryLoadNative","XZ_MAGIC","XZ_FOOTER_MAGIC","FILTER_DELTA","FILTER_BCJ_X86","FILTER_BCJ_PPC","FILTER_BCJ_IA64","FILTER_BCJ_ARM","FILTER_BCJ_ARMT","FILTER_BCJ_SPARC","FILTER_BCJ_ARM64","FILTER_LZMA2","readByte","buf","offset","Buffer","isBuffer","readUInt32LE","length","readUInt32LEAt","bufferEquals","expected","i","decodeMultibyte","value","byte","Error","bytesRead","applyFilter","data","filter","id","props","toString","parseBlockHeader","input","_checkSize","blockHeaderSizeRaw","blockHeaderSize","blockHeaderStart","blockFlags","numFilters","hasCompressedSize","hasUncompressedSize","result","filters","lzma2Props","filterIdResult","filterId","propsSizeResult","filterProps","slice","push","blockDataStart","headerSize","dataStart","dataEnd","nextOffset","parseIndex","indexStart","checkSize","getByte","decodeMultibyteLocal","countResult","recordCount","records","unpaddedResult","uncompressedResult","compressedPos","unpaddedSize","compressedDataSize","uncompressedSize","currentPos","record","headerSizeRaw","paddedSize","Math","ceil","decodeXZPure","checkSizes","checkType","footerEnd","backwardSizeLE","backwardSize","blockRecords","totalUncompressedSize","BUFFERLIST_THRESHOLD","recordStart","blockInfo","compressedData","blockOutput","j","output","append","decodeXZ","callback","worker","cb","native","fallback","err","xz","decompress","promise","then","Promise","resolve","reject","createXZDecoder","bufferList","decodeLzma2Block","lzma2","size","transform","chunk","_encoding","flush","getUInt32LE","equals","blockIndex","pushBlock","clear","headerData","decodeErr"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xz-compat",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.7",
|
|
4
4
|
"description": "XZ Decompression Library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"extract",
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@types/mocha": "*",
|
|
62
62
|
"@types/node": "*",
|
|
63
|
+
"cross-spawn-cb": "^3.2.1",
|
|
63
64
|
"fs-iterator": "^7.0.0",
|
|
64
65
|
"fs-remove-compat": "^1.0.1",
|
|
65
66
|
"fs-stats-spys": "^1.0.0",
|