-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Z_SYNC_FLUSH
support
#222
Comments
You can just call const stream = new fflate.Deflate((chunk, final) => {
/* handle stream chunks here */
});
stream.push(data);
stream.flush(); |
Thank you! I tried your suggestion but I didn't manage to get something working. Here is my test case, replicating the Stack Overflow answer but with "raw" deflate to avoid dealing with headers and adler32 trailers: import * as fflate from "fflate";
import * as pako from "pako";
import * as zlib from "zlib";
async function test(name, compress) {
// Compress data with the provided implementation.
const compressedBuffer = await compress(
new TextEncoder().encode("Hello, World!"),
);
// Concatenate the compressed data twice, and add an empty block at the end.
const full = concatBuffers([
compressedBuffer,
compressedBuffer,
new Uint8Array([0x03, 0x00]),
]);
try {
console.log(name.padEnd(6, " "), zlib.inflateRawSync(full).toString());
} catch (e) {
console.log(name.padEnd(6, " "), "error:", e.message);
}
}
test("fflate", (inputBuffer) => {
let chunks = [];
const deflate = new fflate.Deflate((data) => {
chunks.push(data);
});
deflate.push(inputBuffer);
deflate.flush();
return concatBuffers(chunks);
});
test("pako", (inputBuffer) => {
const deflate = new pako.Deflate({ raw: true });
deflate.push(inputBuffer, pako.constants.Z_SYNC_FLUSH);
return concatBuffers(deflate.chunks);
});
test("zlib", (inputBuffer) => {
return new Promise((resolve) => {
let chunks = [];
const deflate = zlib.createDeflateRaw();
deflate.on("data", (chunk) => {
chunks.push(chunk);
});
deflate.write(inputBuffer);
deflate.flush(zlib.constants.Z_SYNC_FLUSH, () => {
resolve(concatBuffers(chunks));
});
});
});
function concatBuffers(buffers) {
const totalLength = buffers.reduce((acc, bytes) => acc + bytes.length, 0);
const result = new Uint8Array(totalLength);
let offset = 0;
for (const bytes of buffers) {
result.set(bytes, offset);
offset += bytes.length;
}
return result;
}
When run in Node.js, it prints:
I'm probably missing something... do you think this is achievable with fflate now? |
You are correct, this is not currently possible with |
I know this is a niche use-case, thank you very much for considering this! |
What can't you do right now?
I have this use case. I'd like to concatenate deflate streams, so I need to use
Z_SYNC_FLUSH
before finishing the stream to have deterministic trailing bytes. Without this, I would have to inflate the stream to know where it finishes.An optimal solution
When invoking
.push(...)
, add a parameter to ask for a sync flush, ex:How is this done by other libraries?
Pako allows to pass an arbitrary flush mode to
push
: https://github.com/nodeca/pako/blob/62cb729e7813176ce2d2694b89c8724680fca383/lib/deflate.js#L178-L200The text was updated successfully, but these errors were encountered: