Skip to content
File

Blob: src/workerd/api/node/zlib-util.h

cpp879 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4// Copyright Joyent and Node contributors. All rights reserved. MIT license.
5#pragma once
6 
7#include <workerd/api/streams/compression.h>
8#include <workerd/jsg/jsg.h>
9 
10#include <brotli/decode.h>
11#include <brotli/encode.h>
12#include <zlib.h>
13#include <zstd.h>
14#include <zstd_errors.h>
15 
16#include <kj/array.h>
17#include <kj/one-of.h>
18#include <kj/vector.h>
19 
20// The following implementation is adapted from Node.js
21// and therefore follows Node.js style as opposed to kj style.
22// Latest implementation of Node.js zlib can be found at:
23// https://github.com/nodejs/node/blob/main/src/node_zlib.cc
24namespace workerd::api::node {
25 
26#ifndef ZLIB_ERROR_CODES
27#define ZLIB_ERROR_CODES(V) \
28 V(Z_OK) \
29 V(Z_STREAM_END) \
30 V(Z_NEED_DICT) \
31 V(Z_ERRNO) \
32 V(Z_STREAM_ERROR) \
33 V(Z_DATA_ERROR) \
34 V(Z_MEM_ERROR) \
35 V(Z_BUF_ERROR) \
36 V(Z_VERSION_ERROR)
37 
38inline const char* ZlibStrerror(int err) {
39#define V(code) \
40 if (err == code) return #code;
41 ZLIB_ERROR_CODES(V)
42#undef V
43 return "Z_UNKNOWN_ERROR";
44}
45#endif // ZLIB_ERROR_CODES
46 
47// Certain zlib constants are defined by Node.js itself
48static constexpr auto Z_MIN_CHUNK = 64;
49static constexpr auto Z_MAX_CHUNK = 128 * 1024 * 1024;
50static constexpr auto Z_DEFAULT_CHUNK = 16 * 1024;
51static constexpr auto Z_MIN_MEMLEVEL = 1;
52 
53static constexpr auto Z_MAX_MEMLEVEL = 9;
54static constexpr auto Z_DEFAULT_MEMLEVEL = 8;
55static constexpr auto Z_MIN_LEVEL = -1;
56static constexpr auto Z_MAX_LEVEL = 9;
57static constexpr auto Z_DEFAULT_LEVEL = Z_DEFAULT_COMPRESSION;
58static constexpr auto Z_MIN_WINDOWBITS = 8;
59static constexpr auto Z_MAX_WINDOWBITS = 15;
60static constexpr auto Z_DEFAULT_WINDOWBITS = 15;
61 
62static constexpr uint8_t GZIP_HEADER_ID1 = 0x1f;
63static constexpr uint8_t GZIP_HEADER_ID2 = 0x8b;
64 
65using ZlibModeValue = uint8_t;
66enum class ZlibMode : ZlibModeValue {
67 NONE,
68 DEFLATE,
69 INFLATE,
70 GZIP,
71 GUNZIP,
72 DEFLATERAW,
73 INFLATERAW,
74 UNZIP,
75 BROTLI_DECODE,
76 BROTLI_ENCODE,
77 ZSTD_ENCODE,
78 ZSTD_DECODE
79};
80 
81// When possible, we intentionally override chunkSize to a value that is likely to perform better
82static constexpr auto ZLIB_PERFORMANT_CHUNK_SIZE = 40 * 1024;
83 
84struct CompressionError {
85 CompressionError(kj::StringPtr _message, kj::StringPtr _code, int _err)
86 : message(kj::str(_message)),
87 code(kj::str(_code)),
88 err(_err) {
89 JSG_REQUIRE(message.size() != 0, Error, "Compression error message should not be null");
90 }
91 
92 kj::String message;
93 kj::String code;
94 int err;
95};
96 
97class ZlibContext final {
98 public:
99 explicit ZlibContext(ZlibMode _mode): mode(_mode) {}
100 ZlibContext() = default;
101 ~ZlibContext() noexcept(false);
102 
103 KJ_DISALLOW_COPY_AND_MOVE(ZlibContext);
104 
105 void setBuffers(kj::ArrayPtr<kj::byte> input, kj::ArrayPtr<kj::byte> output);
106 
107 void setInputBuffer(kj::ArrayPtr<const kj::byte> input);
108 void setOutputBuffer(kj::ArrayPtr<kj::byte> output);
109 
110 // Clear all buffer pointers from z_stream to prevent stale pointer access.
111 // Must be called after each write operation completes and results have been
112 // captured, so that subsequent operations (e.g. deflateParams) cannot use
113 // dangling pointers into freed backing stores.
114 //
115 // Note: zlib's deflate() rejects next_out == NULL with Z_STREAM_ERROR even
116 // when avail_out == 0, so we point next_out at a valid dummy byte instead.
117 // With avail_out == 0, no data will actually be written to it.
118 void clearBuffers() {
119 stream.next_in = nullptr;
120 stream.avail_in = 0;
121 stream.next_out = &dummyByte;
122 stream.avail_out = 0;
123 }
124 
125 int getFlush() const {
126 return flush;
127 };
128 void setFlush(int value) {
129 flush = value;
130 };
131 // Function signature is same as Node.js implementation.
132 // Ref: https://github.com/nodejs/node/blob/9edf4a0856681a7665bd9dcf2ca7cac252784b98/src/node_zlib.cc#L880
133 void getAfterWriteResult(uint32_t* availIn, uint32_t* availOut) const {
134 *availIn = stream.avail_in;
135 *availOut = stream.avail_out;
136 }
137 void setMode(ZlibMode value) {
138 mode = value;
139 };
140 kj::Maybe<CompressionError> resetStream();
141 kj::Maybe<CompressionError> getError() const;
142 void setAllocationFunctions(alloc_func alloc, free_func free, void* opaque) {
143 stream.zalloc = alloc;
144 stream.zfree = free;
145 stream.opaque = opaque;
146 }
147 
148 // Equivalent to Node.js' `DoThreadPoolWork` function.
149 // Ref: https://github.com/nodejs/node/blob/9edf4a0856681a7665bd9dcf2ca7cac252784b98/src/node_zlib.cc#L760
150 void work();
151 
152 // Returns true when the zlib stream has reached Z_STREAM_END, indicating
153 // that all compressed data has been fully processed.
154 bool isStreamEnd() const {
155 return err == Z_STREAM_END;
156 }
157 
158 uint getAvailIn() const {
159 return stream.avail_in;
160 };
161 void setAvailIn(uint value) {
162 stream.avail_in = value;
163 };
164 uint getAvailOut() const {
165 return stream.avail_out;
166 }
167 void setAvailOut(uint value) {
168 stream.avail_out = value;
169 };
170 
171 z_stream* getStream() {
172 return &stream;
173 }
174 
175 // Zlib
176 void initialize(int _level,
177 int _windowBits,
178 int _memLevel,
179 int _strategy,
180 jsg::Optional<kj::Array<kj::byte>> _dictionary);
181 kj::Maybe<CompressionError> setParams(int level, int strategy);
182 struct Options {
183 jsg::Optional<int> flush;
184 jsg::Optional<int> finishFlush;
185 jsg::Optional<uint> chunkSize;
186 jsg::Optional<kj::uint> windowBits;
187 jsg::Optional<int> level;
188 jsg::Optional<kj::uint> memLevel;
189 jsg::Optional<kj::uint> strategy;
190 jsg::Optional<kj::Array<kj::byte>> dictionary;
191 jsg::Optional<kj::uint> maxOutputLength;
192 
193 JSG_STRUCT(flush,
194 finishFlush,
195 chunkSize,
196 windowBits,
197 level,
198 memLevel,
199 strategy,
200 dictionary,
201 maxOutputLength);
202 };
203 
204 private:
205 bool initializeZlib();
206 kj::Maybe<CompressionError> setDictionary();
207 
208 CompressionError constructError(kj::StringPtr message) const {
209 if (stream.msg != nullptr) message = kj::StringPtr(stream.msg);
210 
211 return {kj::str(message), kj::str(ZlibStrerror(err)), err};
212 };
213 
214 bool initialized = false;
215 ZlibMode mode = ZlibMode::NONE;
216 int flush = Z_NO_FLUSH;
217 int windowBits = 0;
218 int level = 0;
219 int memLevel = 0;
220 int strategy = 0;
221 kj::Vector<kj::byte> dictionary;
222 
223 int err = Z_OK;
224 unsigned int gzip_id_bytes_read = 0;
225 z_stream stream{};
226 // Dummy byte target for clearBuffers(). zlib's deflate() rejects
227 // next_out == NULL even when avail_out == 0, so we need a valid address.
228 Bytef dummyByte = 0;
229};
230 
231using CompressionStreamErrorHandler = jsg::Function<void(int, kj::StringPtr, kj::StringPtr)>;
232 
233class BrotliContext {
234 public:
235 explicit BrotliContext(ZlibMode _mode): mode(_mode) {}
236 KJ_DISALLOW_COPY(BrotliContext);
237 void setBuffers(kj::ArrayPtr<kj::byte> input, kj::ArrayPtr<kj::byte> output);
238 void setInputBuffer(kj::ArrayPtr<const kj::byte> input);
239 void setOutputBuffer(kj::ArrayPtr<kj::byte> output);
240 void setFlush(int flush);
241 kj::uint getAvailOut() const;
242 void getAfterWriteResult(uint32_t* availIn, uint32_t* availOut) const;
243 void setMode(ZlibMode _mode) {
244 mode = _mode;
245 }
246 
247 void clearBuffers() {
248 nextIn = nullptr;
249 nextOut = nullptr;
250 availIn = 0;
251 availOut = 0;
252 }
253 
254 struct Options {
255 jsg::Optional<int> flush;
256 jsg::Optional<int> finishFlush;
257 jsg::Optional<kj::uint> chunkSize;
258 jsg::Optional<jsg::Dict<int>> params;
259 jsg::Optional<kj::uint> maxOutputLength;
260 JSG_STRUCT(flush, finishFlush, chunkSize, params, maxOutputLength);
261 };
262 
263 protected:
264 ZlibMode mode;
265 const uint8_t* nextIn = nullptr;
266 uint8_t* nextOut = nullptr;
267 size_t availIn = 0;
268 size_t availOut = 0;
269 BrotliEncoderOperation flush = BROTLI_OPERATION_PROCESS;
270 
271 // TODO(addaleax): These should not need to be stored here.
272 // This is currently only done this way to make implementing ResetStream()
273 // easier.
274 brotli_alloc_func alloc_brotli = nullptr;
275 brotli_free_func free_brotli = nullptr;
276 void* alloc_opaque_brotli = nullptr;
277};
278 
279class BrotliEncoderContext final: public BrotliContext {
280 public:
281 static const ZlibMode Mode = ZlibMode::BROTLI_ENCODE;
282 explicit BrotliEncoderContext(ZlibMode _mode);
283 
284 KJ_DISALLOW_COPY_AND_MOVE(BrotliEncoderContext);
285 
286 // Equivalent to Node.js' `DoThreadPoolWork` implementation.
287 void work();
288 kj::Maybe<CompressionError> initialize(
289 brotli_alloc_func init_alloc_func, brotli_free_func init_free_func, void* init_opaque_func);
290 kj::Maybe<CompressionError> resetStream();
291 kj::Maybe<CompressionError> setParams(int key, uint32_t value);
292 kj::Maybe<CompressionError> getError() const;
293 bool isStreamEnd() const;
294 
295 private:
296 bool lastResult = false;
297 bool streamEnd = false;
298 kj::Own<BrotliEncoderStateStruct> state;
299};
300 
301class BrotliDecoderContext final: public BrotliContext {
302 public:
303 static const ZlibMode Mode = ZlibMode::BROTLI_DECODE;
304 explicit BrotliDecoderContext(ZlibMode _mode);
305 
306 KJ_DISALLOW_COPY_AND_MOVE(BrotliDecoderContext);
307 
308 // Equivalent to Node.js' `DoThreadPoolWork` implementation.
309 void work();
310 kj::Maybe<CompressionError> initialize(
311 brotli_alloc_func init_alloc_func, brotli_free_func init_free_func, void* init_opaque_func);
312 kj::Maybe<CompressionError> resetStream();
313 kj::Maybe<CompressionError> setParams(int key, uint32_t value);
314 kj::Maybe<CompressionError> getError() const;
315 bool isStreamEnd() const;
316 
317 private:
318 BrotliDecoderResult lastResult = BROTLI_DECODER_RESULT_SUCCESS;
319 BrotliDecoderErrorCode error = BROTLI_DECODER_NO_ERROR;
320 kj::String errorString;
321 kj::Own<BrotliDecoderStateStruct> state;
322};
323 
324class ZstdContext {
325 public:
326 explicit ZstdContext(ZlibMode _mode): mode(_mode) {}
327 KJ_DISALLOW_COPY(ZstdContext);
328 
329 void setBuffers(kj::ArrayPtr<kj::byte> input, kj::ArrayPtr<kj::byte> output);
330 void setInputBuffer(kj::ArrayPtr<const kj::byte> input);
331 void setOutputBuffer(kj::ArrayPtr<kj::byte> output);
332 void setFlush(int flush);
333 kj::uint getAvailOut() const;
334 void getAfterWriteResult(uint32_t* availIn, uint32_t* availOut) const;
335 void setMode(ZlibMode _mode) {
336 mode = _mode;
337 }
338 
339 void clearBuffers() {
340 input_ = {nullptr, 0, 0};
341 output_ = {nullptr, 0, 0};
342 }
343 
344 struct Options {
345 jsg::Optional<int> flush;
346 jsg::Optional<int> finishFlush;
347 jsg::Optional<kj::uint> chunkSize;
348 jsg::Optional<jsg::Dict<int>> params;
349 jsg::Optional<kj::uint> maxOutputLength;
350 jsg::Optional<uint64_t> pledgedSrcSize;
351 JSG_STRUCT(flush, finishFlush, chunkSize, params, maxOutputLength, pledgedSrcSize);
352 };
353 
354 protected:
355 ZlibMode mode;
356 ZSTD_inBuffer input_{nullptr, 0, 0};
357 ZSTD_outBuffer output_{nullptr, 0, 0};
358 ZSTD_EndDirective flush_ = ZSTD_e_continue;
359};
360 
361class ZstdEncoderContext final: public ZstdContext {
362 public:
363 static const ZlibMode Mode = ZlibMode::ZSTD_ENCODE;
364 explicit ZstdEncoderContext(ZlibMode _mode);
365 KJ_DISALLOW_COPY_AND_MOVE(ZstdEncoderContext);
366 
367 void work();
368 kj::Maybe<CompressionError> initialize(uint64_t pledgedSrcSize);
369 kj::Maybe<CompressionError> resetStream();
370 kj::Maybe<CompressionError> setParams(int key, int value);
371 kj::Maybe<CompressionError> getError() const;
372 bool isStreamEnd() const;
373 
374 private:
375 size_t lastResult = 0;
376 kj::Own<ZSTD_CCtx> cctx_;
377 ZSTD_ErrorCode error_ = ZSTD_error_no_error;
378};
379 
380class ZstdDecoderContext final: public ZstdContext {
381 public:
382 static const ZlibMode Mode = ZlibMode::ZSTD_DECODE;
383 explicit ZstdDecoderContext(ZlibMode _mode);
384 KJ_DISALLOW_COPY_AND_MOVE(ZstdDecoderContext);
385 
386 void work();
387 kj::Maybe<CompressionError> initialize();
388 kj::Maybe<CompressionError> resetStream();
389 kj::Maybe<CompressionError> setParams(int key, int value);
390 kj::Maybe<CompressionError> getError() const;
391 bool isStreamEnd() const;
392 
393 private:
394 size_t lastResult = 0;
395 kj::Own<ZSTD_DCtx> dctx_;
396 ZSTD_ErrorCode error_ = ZSTD_error_no_error;
397 bool frameInProgress_ = false;
398};
399 
400// Implements utilities in support of the Node.js Zlib
401class ZlibUtil final: public jsg::Object {
402 public:
403 ZlibUtil() = default;
404 ZlibUtil(jsg::Lock&, const jsg::Url&) {}
405 
406 template <class CompressionContext>
407 class CompressionStream: public jsg::Object {
408 public:
409 explicit CompressionStream(
410 ZlibMode _mode, kj::Arc<const jsg::ExternalMemoryTarget>&& externalMemoryTarget)
411 : allocator(kj::mv(externalMemoryTarget)),
412 context_(_mode) {}
413 // TODO(soon): Find a way to add noexcept(false) to this destructor.
414 ~CompressionStream();
415 KJ_DISALLOW_COPY_AND_MOVE(CompressionStream);
416 
417 static jsg::Ref<CompressionStream> constructor(jsg::Lock& js, ZlibModeValue mode);
418 
419 void close();
420 bool checkError(jsg::Lock& js);
421 void emitError(jsg::Lock& js, const CompressionError& error);
422 template <bool async>
423 void writeStream(
424 jsg::Lock& js, int flush, kj::ArrayPtr<kj::byte> input, kj::ArrayPtr<kj::byte> output);
425 void setErrorHandler(CompressionStreamErrorHandler handler) {
426 errorHandler = kj::mv(handler);
427 }
428 
429 void updateWriteResult(jsg::Lock& js);
430 
431 template <bool async>
432 void write(jsg::Lock& js,
433 int flush,
434 jsg::Optional<kj::Array<kj::byte>> input,
435 uint32_t inputOffset,
436 uint32_t inputLength,
437 kj::Array<kj::byte> output,
438 uint32_t outputOffset,
439 uint32_t outputLength);
440 void reset(jsg::Lock& js);
441 
442 JSG_RESOURCE_TYPE(CompressionStream) {
443 JSG_METHOD(close);
444 JSG_METHOD_NAMED(write, template write<true>);
445 JSG_METHOD_NAMED(writeSync, template write<false>);
446 JSG_METHOD(reset);
447 JSG_METHOD(setErrorHandler);
448 }
449 
450 protected:
451 CompressionContext* context() {
452 return &context_;
453 }
454 
455 void initializeStream(
456 jsg::Lock& js, jsg::JsArrayBufferView& _write_result, jsg::Function<void()> writeCallback);
457 
458 // Used to store allocations in Brotli* operations.
459 // This declaration should be physically positioned before
460 // context to avoid `heap-use-after-free` ASan error.
461 CompressionAllocator allocator;
462 
463 private:
464 CompressionContext context_;
465 bool initialized = false;
466 bool writing = false;
467 bool pending_close = false;
468 bool closed = false;
469 
470 // Equivalent to `write_js_callback` in Node.js
471 jsg::Optional<jsg::Function<void()>> writeCallback;
472 jsg::Optional<jsg::JsRef<jsg::JsArrayBufferView>> writeResult;
473 jsg::Optional<CompressionStreamErrorHandler> errorHandler;
474 };
475 
476 class ZlibStream final: public CompressionStream<ZlibContext> {
477 public:
478 explicit ZlibStream(
479 ZlibMode mode, kj::Arc<const jsg::ExternalMemoryTarget>&& externalMemoryTarget)
480 : CompressionStream(mode, kj::mv(externalMemoryTarget)) {}
481 KJ_DISALLOW_COPY_AND_MOVE(ZlibStream);
482 static jsg::Ref<ZlibStream> constructor(jsg::Lock& js, ZlibModeValue mode);
483 
484 // Instance methods
485 void initialize(jsg::Lock& js,
486 int windowBits,
487 int level,
488 int memLevel,
489 int strategy,
490 jsg::JsArrayBufferView writeState,
491 jsg::Function<void()> writeCallback,
492 jsg::Optional<kj::Array<kj::byte>> dictionary);
493 void params(jsg::Lock& js, int level, int strategy);
494 
495 JSG_RESOURCE_TYPE(ZlibStream) {
496 JSG_INHERIT(CompressionStream<ZlibContext>);
497 
498 JSG_METHOD(initialize);
499 JSG_METHOD(params);
500 }
501 };
502 
503 template <typename CompressionContext>
504 class BrotliCompressionStream: public CompressionStream<CompressionContext> {
505 public:
506 explicit BrotliCompressionStream(
507 ZlibMode _mode, kj::Arc<const jsg::ExternalMemoryTarget>&& externalMemoryTarget)
508 : CompressionStream<CompressionContext>(_mode, kj::mv(externalMemoryTarget)) {}
509 KJ_DISALLOW_COPY_AND_MOVE(BrotliCompressionStream);
510 static jsg::Ref<BrotliCompressionStream> constructor(jsg::Lock& js, ZlibModeValue mode);
511 
512 bool initialize(jsg::Lock& js,
513 jsg::JsArrayBufferView params,
514 jsg::JsArrayBufferView writeResult,
515 jsg::Function<void()> writeCallback);
516 
517 void params() {
518 // Currently a no-op, and not accessed from JS land.
519 // At some point Brotli may support changing parameters on the fly,
520 // in which case we can implement this and a JS equivalent similar to
521 // the zlib Params() function.
522 }
523 
524 JSG_RESOURCE_TYPE(BrotliCompressionStream) {
525 JSG_INHERIT(CompressionStream<CompressionContext>);
526 
527 JSG_METHOD(initialize);
528 JSG_METHOD(params);
529 }
530 
531 CompressionContext* context() {
532 return this->CompressionStream<CompressionContext>::context();
533 }
534 };
535 
536 template <typename CompressionContext>
537 class ZstdCompressionStream: public CompressionStream<CompressionContext> {
538 public:
539 explicit ZstdCompressionStream(
540 ZlibMode _mode, kj::Arc<const jsg::ExternalMemoryTarget>&& externalMemoryTarget)
541 : CompressionStream<CompressionContext>(_mode, kj::mv(externalMemoryTarget)) {}
542 KJ_DISALLOW_COPY_AND_MOVE(ZstdCompressionStream);
543 static jsg::Ref<ZstdCompressionStream> constructor(jsg::Lock& js, ZlibModeValue mode);
544 
545 bool initialize(jsg::Lock& js,
546 jsg::JsArrayBufferView params,
547 jsg::JsArrayBufferView writeResult,
548 jsg::Function<void()> writeCallback,
549 jsg::Optional<uint64_t> pledgedSrcSize);
550 
551 void params() {
552 // Currently a no-op, and not accessed from JS land.
553 }
554 
555 JSG_RESOURCE_TYPE(ZstdCompressionStream) {
556 JSG_INHERIT(CompressionStream<CompressionContext>);
557 
558 JSG_METHOD(initialize);
559 JSG_METHOD(params);
560 }
561 
562 CompressionContext* context() {
563 return this->CompressionStream<CompressionContext>::context();
564 }
565 };
566 
567 using InputSource = kj::OneOf<jsg::NonCoercible<kj::String>, kj::Array<kj::byte>>;
568 using CompressCallbackArg = kj::OneOf<jsg::JsValue, kj::Array<kj::byte>>;
569 using CompressCallback = jsg::Function<void(CompressCallbackArg)>;
570 
571 uint32_t crc32Sync(InputSource data, uint32_t value);
572 void zlibWithCallback(jsg::Lock& js,
573 InputSource data,
574 ZlibContext::Options options,
575 ZlibModeValue mode,
576 CompressCallback cb);
577 kj::Array<kj::byte> zlibSync(
578 jsg::Lock& js, InputSource data, ZlibContext::Options options, ZlibModeValue mode);
579 
580 template <typename Context>
581 kj::Array<kj::byte> brotliSync(jsg::Lock& js, InputSource data, BrotliContext::Options options);
582 template <typename Context>
583 void brotliWithCallback(
584 jsg::Lock& js, InputSource data, BrotliContext::Options options, CompressCallback cb);
585 
586 template <typename Context>
587 kj::Array<kj::byte> zstdSync(jsg::Lock& js, InputSource data, ZstdContext::Options options);
588 template <typename Context>
589 void zstdWithCallback(
590 jsg::Lock& js, InputSource data, ZstdContext::Options options, CompressCallback cb);
591 
592 JSG_RESOURCE_TYPE(ZlibUtil) {
593 JSG_METHOD_NAMED(crc32, crc32Sync);
594 JSG_METHOD(zlibSync);
595 JSG_METHOD_NAMED(zlib, zlibWithCallback);
596 
597 JSG_METHOD_NAMED(brotliDecompressSync, template brotliSync<BrotliDecoderContext>);
598 JSG_METHOD_NAMED(brotliCompressSync, template brotliSync<BrotliEncoderContext>);
599 JSG_METHOD_NAMED(brotliDecompress, template brotliWithCallback<BrotliDecoderContext>);
600 JSG_METHOD_NAMED(brotliCompress, template brotliWithCallback<BrotliEncoderContext>);
601 
602 JSG_METHOD_NAMED(zstdDecompressSync, template zstdSync<ZstdDecoderContext>);
603 JSG_METHOD_NAMED(zstdCompressSync, template zstdSync<ZstdEncoderContext>);
604 JSG_METHOD_NAMED(zstdDecompress, template zstdWithCallback<ZstdDecoderContext>);
605 JSG_METHOD_NAMED(zstdCompress, template zstdWithCallback<ZstdEncoderContext>);
606 
607 JSG_NESTED_TYPE(ZlibStream);
608 JSG_NESTED_TYPE_NAMED(BrotliCompressionStream<BrotliEncoderContext>, BrotliEncoder);
609 JSG_NESTED_TYPE_NAMED(BrotliCompressionStream<BrotliDecoderContext>, BrotliDecoder);
610 JSG_NESTED_TYPE_NAMED(ZstdCompressionStream<ZstdEncoderContext>, ZstdEncoder);
611 JSG_NESTED_TYPE_NAMED(ZstdCompressionStream<ZstdDecoderContext>, ZstdDecoder);
612 
613 // zlib.constants (part of the API contract for node:zlib)
614 JSG_STATIC_CONSTANT_NAMED(CONST_Z_NO_FLUSH, Z_NO_FLUSH);
615 JSG_STATIC_CONSTANT_NAMED(CONST_Z_PARTIAL_FLUSH, Z_PARTIAL_FLUSH);
616 JSG_STATIC_CONSTANT_NAMED(CONST_Z_SYNC_FLUSH, Z_SYNC_FLUSH);
617 JSG_STATIC_CONSTANT_NAMED(CONST_Z_FULL_FLUSH, Z_FULL_FLUSH);
618 JSG_STATIC_CONSTANT_NAMED(CONST_Z_FINISH, Z_FINISH);
619 JSG_STATIC_CONSTANT_NAMED(CONST_Z_BLOCK, Z_BLOCK);
620 
621 JSG_STATIC_CONSTANT_NAMED(CONST_Z_OK, Z_OK);
622 JSG_STATIC_CONSTANT_NAMED(CONST_Z_STREAM_END, Z_STREAM_END);
623 JSG_STATIC_CONSTANT_NAMED(CONST_Z_NEED_DICT, Z_NEED_DICT);
624 JSG_STATIC_CONSTANT_NAMED(CONST_Z_ERRNO, Z_ERRNO);
625 JSG_STATIC_CONSTANT_NAMED(CONST_Z_STREAM_ERROR, Z_STREAM_ERROR);
626 JSG_STATIC_CONSTANT_NAMED(CONST_Z_DATA_ERROR, Z_DATA_ERROR);
627 JSG_STATIC_CONSTANT_NAMED(CONST_Z_MEM_ERROR, Z_MEM_ERROR);
628 JSG_STATIC_CONSTANT_NAMED(CONST_Z_BUF_ERROR, Z_BUF_ERROR);
629 JSG_STATIC_CONSTANT_NAMED(CONST_Z_VERSION_ERROR, Z_VERSION_ERROR);
630 
631 JSG_STATIC_CONSTANT_NAMED(CONST_Z_NO_COMPRESSION, Z_NO_COMPRESSION);
632 JSG_STATIC_CONSTANT_NAMED(CONST_Z_BEST_SPEED, Z_BEST_SPEED);
633 JSG_STATIC_CONSTANT_NAMED(CONST_Z_BEST_COMPRESSION, Z_BEST_COMPRESSION);
634 JSG_STATIC_CONSTANT_NAMED(CONST_Z_DEFAULT_COMPRESSION, Z_DEFAULT_COMPRESSION);
635 JSG_STATIC_CONSTANT_NAMED(CONST_Z_FILTERED, Z_FILTERED);
636 JSG_STATIC_CONSTANT_NAMED(CONST_Z_HUFFMAN_ONLY, Z_HUFFMAN_ONLY);
637 JSG_STATIC_CONSTANT_NAMED(CONST_Z_RLE, Z_RLE);
638 JSG_STATIC_CONSTANT_NAMED(CONST_Z_FIXED, Z_FIXED);
639 JSG_STATIC_CONSTANT_NAMED(CONST_Z_DEFAULT_STRATEGY, Z_DEFAULT_STRATEGY);
640 JSG_STATIC_CONSTANT_NAMED(CONST_ZLIB_VERNUM, ZLIB_VERNUM);
641 
642 JSG_STATIC_CONSTANT_NAMED(CONST_DEFLATE, static_cast<ZlibModeValue>(ZlibMode::DEFLATE));
643 JSG_STATIC_CONSTANT_NAMED(CONST_INFLATE, static_cast<ZlibModeValue>(ZlibMode::INFLATE));
644 JSG_STATIC_CONSTANT_NAMED(CONST_GZIP, static_cast<ZlibModeValue>(ZlibMode::GZIP));
645 JSG_STATIC_CONSTANT_NAMED(CONST_GUNZIP, static_cast<ZlibModeValue>(ZlibMode::GUNZIP));
646 JSG_STATIC_CONSTANT_NAMED(CONST_DEFLATERAW, static_cast<ZlibModeValue>(ZlibMode::DEFLATERAW));
647 JSG_STATIC_CONSTANT_NAMED(CONST_INFLATERAW, static_cast<ZlibModeValue>(ZlibMode::INFLATERAW));
648 JSG_STATIC_CONSTANT_NAMED(CONST_UNZIP, static_cast<ZlibModeValue>(ZlibMode::UNZIP));
649 JSG_STATIC_CONSTANT_NAMED(
650 CONST_BROTLI_DECODE, static_cast<ZlibModeValue>(ZlibMode::BROTLI_DECODE));
651 JSG_STATIC_CONSTANT_NAMED(
652 CONST_BROTLI_ENCODE, static_cast<ZlibModeValue>(ZlibMode::BROTLI_ENCODE));
653 
654 JSG_STATIC_CONSTANT_NAMED(CONST_Z_MIN_WINDOWBITS, Z_MIN_WINDOWBITS);
655 JSG_STATIC_CONSTANT_NAMED(CONST_Z_MAX_WINDOWBITS, Z_MAX_WINDOWBITS);
656 JSG_STATIC_CONSTANT_NAMED(CONST_Z_DEFAULT_WINDOWBITS, Z_DEFAULT_WINDOWBITS);
657 JSG_STATIC_CONSTANT_NAMED(CONST_Z_MIN_CHUNK, Z_MIN_CHUNK);
658 JSG_STATIC_CONSTANT_NAMED(CONST_Z_MAX_CHUNK, Z_MAX_CHUNK);
659 JSG_STATIC_CONSTANT_NAMED(CONST_Z_DEFAULT_CHUNK, Z_DEFAULT_CHUNK);
660 JSG_STATIC_CONSTANT_NAMED(CONST_Z_MIN_MEMLEVEL, Z_MIN_MEMLEVEL);
661 JSG_STATIC_CONSTANT_NAMED(CONST_Z_MAX_MEMLEVEL, Z_MAX_MEMLEVEL);
662 JSG_STATIC_CONSTANT_NAMED(CONST_Z_DEFAULT_MEMLEVEL, Z_DEFAULT_MEMLEVEL);
663 JSG_STATIC_CONSTANT_NAMED(CONST_Z_MIN_LEVEL, Z_MIN_LEVEL);
664 JSG_STATIC_CONSTANT_NAMED(CONST_Z_MAX_LEVEL, Z_MAX_LEVEL);
665 JSG_STATIC_CONSTANT_NAMED(CONST_Z_DEFAULT_LEVEL, Z_DEFAULT_LEVEL);
666 
667 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_OPERATION_PROCESS, BROTLI_OPERATION_PROCESS);
668 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_OPERATION_FLUSH, BROTLI_OPERATION_FLUSH);
669 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_OPERATION_FINISH, BROTLI_OPERATION_FINISH);
670 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_OPERATION_EMIT_METADATA, BROTLI_OPERATION_EMIT_METADATA);
671 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_PARAM_MODE, BROTLI_PARAM_MODE);
672 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_MODE_GENERIC, BROTLI_MODE_GENERIC);
673 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_MODE_TEXT, BROTLI_MODE_TEXT);
674 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_MODE_FONT, BROTLI_MODE_FONT);
675 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DEFAULT_MODE, BROTLI_DEFAULT_MODE);
676 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_PARAM_QUALITY, BROTLI_PARAM_QUALITY);
677 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_MIN_QUALITY, BROTLI_MIN_QUALITY);
678 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_MAX_QUALITY, BROTLI_MAX_QUALITY);
679 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DEFAULT_QUALITY, BROTLI_DEFAULT_QUALITY);
680 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_PARAM_LGWIN, BROTLI_PARAM_LGWIN);
681 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_MIN_WINDOW_BITS, BROTLI_MIN_WINDOW_BITS);
682 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_MAX_WINDOW_BITS, BROTLI_MAX_WINDOW_BITS);
683 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_LARGE_MAX_WINDOW_BITS, BROTLI_LARGE_MAX_WINDOW_BITS);
684 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DEFAULT_WINDOW, BROTLI_DEFAULT_WINDOW);
685 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_PARAM_LGBLOCK, BROTLI_PARAM_LGBLOCK);
686 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_MIN_INPUT_BLOCK_BITS, BROTLI_MIN_INPUT_BLOCK_BITS);
687 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_MAX_INPUT_BLOCK_BITS, BROTLI_MAX_INPUT_BLOCK_BITS);
688 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING,
689 BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING);
690 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_PARAM_SIZE_HINT, BROTLI_PARAM_SIZE_HINT);
691 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_PARAM_LARGE_WINDOW, BROTLI_PARAM_LARGE_WINDOW);
692 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_PARAM_NPOSTFIX, BROTLI_PARAM_NPOSTFIX);
693 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_PARAM_NDIRECT, BROTLI_PARAM_NDIRECT);
694 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_RESULT_ERROR, BROTLI_DECODER_RESULT_ERROR);
695 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_RESULT_SUCCESS, BROTLI_DECODER_RESULT_SUCCESS);
696 JSG_STATIC_CONSTANT_NAMED(
697 CONST_BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT, BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT);
698 JSG_STATIC_CONSTANT_NAMED(
699 CONST_BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT, BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT);
700 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION,
701 BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION);
702 JSG_STATIC_CONSTANT_NAMED(
703 CONST_BROTLI_DECODER_PARAM_LARGE_WINDOW, BROTLI_DECODER_PARAM_LARGE_WINDOW);
704 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_NO_ERROR, BROTLI_DECODER_NO_ERROR);
705 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_SUCCESS, BROTLI_DECODER_SUCCESS);
706 JSG_STATIC_CONSTANT_NAMED(
707 CONST_BROTLI_DECODER_NEEDS_MORE_INPUT, BROTLI_DECODER_NEEDS_MORE_INPUT);
708 JSG_STATIC_CONSTANT_NAMED(
709 CONST_BROTLI_DECODER_NEEDS_MORE_OUTPUT, BROTLI_DECODER_NEEDS_MORE_OUTPUT);
710 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE,
711 BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE);
712 JSG_STATIC_CONSTANT_NAMED(
713 CONST_BROTLI_DECODER_ERROR_FORMAT_RESERVED, BROTLI_DECODER_ERROR_FORMAT_RESERVED);
714 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE,
715 BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE);
716 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET,
717 BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET);
718 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME,
719 BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME);
720 JSG_STATIC_CONSTANT_NAMED(
721 CONST_BROTLI_DECODER_ERROR_FORMAT_CL_SPACE, BROTLI_DECODER_ERROR_FORMAT_CL_SPACE);
722 JSG_STATIC_CONSTANT_NAMED(
723 CONST_BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE, BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE);
724 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT,
725 BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT);
726 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1,
727 BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1);
728 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2,
729 BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2);
730 JSG_STATIC_CONSTANT_NAMED(
731 CONST_BROTLI_DECODER_ERROR_FORMAT_TRANSFORM, BROTLI_DECODER_ERROR_FORMAT_TRANSFORM);
732 JSG_STATIC_CONSTANT_NAMED(
733 CONST_BROTLI_DECODER_ERROR_FORMAT_DICTIONARY, BROTLI_DECODER_ERROR_FORMAT_DICTIONARY);
734 JSG_STATIC_CONSTANT_NAMED(
735 CONST_BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS, BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS);
736 JSG_STATIC_CONSTANT_NAMED(
737 CONST_BROTLI_DECODER_ERROR_FORMAT_PADDING_1, BROTLI_DECODER_ERROR_FORMAT_PADDING_1);
738 JSG_STATIC_CONSTANT_NAMED(
739 CONST_BROTLI_DECODER_ERROR_FORMAT_PADDING_2, BROTLI_DECODER_ERROR_FORMAT_PADDING_2);
740 JSG_STATIC_CONSTANT_NAMED(
741 CONST_BROTLI_DECODER_ERROR_FORMAT_DISTANCE, BROTLI_DECODER_ERROR_FORMAT_DISTANCE);
742 JSG_STATIC_CONSTANT_NAMED(
743 CONST_BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET, BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET);
744 JSG_STATIC_CONSTANT_NAMED(
745 CONST_BROTLI_DECODER_ERROR_INVALID_ARGUMENTS, BROTLI_DECODER_ERROR_INVALID_ARGUMENTS);
746 JSG_STATIC_CONSTANT_NAMED(
747 CONST_BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES, BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES);
748 JSG_STATIC_CONSTANT_NAMED(
749 CONST_BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS, BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS);
750 JSG_STATIC_CONSTANT_NAMED(
751 CONST_BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP, BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP);
752 JSG_STATIC_CONSTANT_NAMED(
753 CONST_BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1, BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1);
754 JSG_STATIC_CONSTANT_NAMED(
755 CONST_BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2, BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2);
756 JSG_STATIC_CONSTANT_NAMED(CONST_BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES,
757 BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES);
758 JSG_STATIC_CONSTANT_NAMED(
759 CONST_BROTLI_DECODER_ERROR_UNREACHABLE, BROTLI_DECODER_ERROR_UNREACHABLE);
760 
761 // Zstd mode constants
762 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_ENCODE, static_cast<ZlibModeValue>(ZlibMode::ZSTD_ENCODE));
763 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_DECODE, static_cast<ZlibModeValue>(ZlibMode::ZSTD_DECODE));
764 // Node.js aliases for mode constants (ZSTD_COMPRESS/ZSTD_DECOMPRESS)
765 JSG_STATIC_CONSTANT_NAMED(
766 CONST_ZSTD_COMPRESS, static_cast<ZlibModeValue>(ZlibMode::ZSTD_ENCODE));
767 JSG_STATIC_CONSTANT_NAMED(
768 CONST_ZSTD_DECOMPRESS, static_cast<ZlibModeValue>(ZlibMode::ZSTD_DECODE));
769 
770 // Zstd flush directives
771 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_e_continue, ZSTD_e_continue);
772 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_e_flush, ZSTD_e_flush);
773 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_e_end, ZSTD_e_end);
774 
775 // Zstd compression parameters
776 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_compressionLevel, ZSTD_c_compressionLevel);
777 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_windowLog, ZSTD_c_windowLog);
778 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_hashLog, ZSTD_c_hashLog);
779 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_chainLog, ZSTD_c_chainLog);
780 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_searchLog, ZSTD_c_searchLog);
781 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_minMatch, ZSTD_c_minMatch);
782 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_targetLength, ZSTD_c_targetLength);
783 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_strategy, ZSTD_c_strategy);
784 JSG_STATIC_CONSTANT_NAMED(
785 CONST_ZSTD_c_enableLongDistanceMatching, ZSTD_c_enableLongDistanceMatching);
786 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_ldmHashLog, ZSTD_c_ldmHashLog);
787 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_ldmMinMatch, ZSTD_c_ldmMinMatch);
788 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_ldmBucketSizeLog, ZSTD_c_ldmBucketSizeLog);
789 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_ldmHashRateLog, ZSTD_c_ldmHashRateLog);
790 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_contentSizeFlag, ZSTD_c_contentSizeFlag);
791 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_checksumFlag, ZSTD_c_checksumFlag);
792 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_dictIDFlag, ZSTD_c_dictIDFlag);
793 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_nbWorkers, ZSTD_c_nbWorkers);
794 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_jobSize, ZSTD_c_jobSize);
795 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_c_overlapLog, ZSTD_c_overlapLog);
796 
797 // Zstd decompression parameters
798 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_d_windowLogMax, ZSTD_d_windowLogMax);
799 
800 // Zstd strategy constants
801 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_fast, ZSTD_fast);
802 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_dfast, ZSTD_dfast);
803 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_greedy, ZSTD_greedy);
804 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_lazy, ZSTD_lazy);
805 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_lazy2, ZSTD_lazy2);
806 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_btlazy2, ZSTD_btlazy2);
807 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_btopt, ZSTD_btopt);
808 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_btultra, ZSTD_btultra);
809 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_btultra2, ZSTD_btultra2);
810 
811 // Zstd default compression level
812 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_CLEVEL_DEFAULT, ZSTD_CLEVEL_DEFAULT);
813 
814 // Zstd error codes
815 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_no_error, ZSTD_error_no_error);
816 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_GENERIC, ZSTD_error_GENERIC);
817 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_prefix_unknown, ZSTD_error_prefix_unknown);
818 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_version_unsupported, ZSTD_error_version_unsupported);
819 JSG_STATIC_CONSTANT_NAMED(
820 CONST_ZSTD_error_frameParameter_unsupported, ZSTD_error_frameParameter_unsupported);
821 JSG_STATIC_CONSTANT_NAMED(
822 CONST_ZSTD_error_frameParameter_windowTooLarge, ZSTD_error_frameParameter_windowTooLarge);
823 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_corruption_detected, ZSTD_error_corruption_detected);
824 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_checksum_wrong, ZSTD_error_checksum_wrong);
825 JSG_STATIC_CONSTANT_NAMED(
826 CONST_ZSTD_error_literals_headerWrong, ZSTD_error_literals_headerWrong);
827 JSG_STATIC_CONSTANT_NAMED(
828 CONST_ZSTD_error_dictionary_corrupted, ZSTD_error_dictionary_corrupted);
829 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_dictionary_wrong, ZSTD_error_dictionary_wrong);
830 JSG_STATIC_CONSTANT_NAMED(
831 CONST_ZSTD_error_dictionaryCreation_failed, ZSTD_error_dictionaryCreation_failed);
832 JSG_STATIC_CONSTANT_NAMED(
833 CONST_ZSTD_error_parameter_unsupported, ZSTD_error_parameter_unsupported);
834 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_parameter_combination_unsupported,
835 ZSTD_error_parameter_combination_unsupported);
836 JSG_STATIC_CONSTANT_NAMED(
837 CONST_ZSTD_error_parameter_outOfBound, ZSTD_error_parameter_outOfBound);
838 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_tableLog_tooLarge, ZSTD_error_tableLog_tooLarge);
839 JSG_STATIC_CONSTANT_NAMED(
840 CONST_ZSTD_error_maxSymbolValue_tooLarge, ZSTD_error_maxSymbolValue_tooLarge);
841 JSG_STATIC_CONSTANT_NAMED(
842 CONST_ZSTD_error_maxSymbolValue_tooSmall, ZSTD_error_maxSymbolValue_tooSmall);
843 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_stabilityCondition_notRespected,
844 ZSTD_error_stabilityCondition_notRespected);
845 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_stage_wrong, ZSTD_error_stage_wrong);
846 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_init_missing, ZSTD_error_init_missing);
847 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_memory_allocation, ZSTD_error_memory_allocation);
848 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_workSpace_tooSmall, ZSTD_error_workSpace_tooSmall);
849 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_dstSize_tooSmall, ZSTD_error_dstSize_tooSmall);
850 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_srcSize_wrong, ZSTD_error_srcSize_wrong);
851 JSG_STATIC_CONSTANT_NAMED(CONST_ZSTD_error_dstBuffer_null, ZSTD_error_dstBuffer_null);
852 JSG_STATIC_CONSTANT_NAMED(
853 CONST_ZSTD_error_noForwardProgress_destFull, ZSTD_error_noForwardProgress_destFull);
854 JSG_STATIC_CONSTANT_NAMED(
855 CONST_ZSTD_error_noForwardProgress_inputEmpty, ZSTD_error_noForwardProgress_inputEmpty);
856 }
857};
858 
859#define EW_NODE_ZLIB_ISOLATE_TYPES \
860 api::node::ZlibUtil, api::node::ZlibUtil::ZlibStream, \
861 api::node::ZlibUtil::BrotliCompressionStream<api::node::BrotliEncoderContext>, \
862 api::node::ZlibUtil::BrotliCompressionStream<api::node::BrotliDecoderContext>, \
863 api::node::ZlibUtil::ZstdCompressionStream<api::node::ZstdEncoderContext>, \
864 api::node::ZlibUtil::ZstdCompressionStream<api::node::ZstdDecoderContext>, \
865 api::node::ZlibUtil::CompressionStream<api::node::ZlibContext>, \
866 api::node::ZlibUtil::CompressionStream<api::node::BrotliEncoderContext>, \
867 api::node::ZlibUtil::CompressionStream<api::node::BrotliDecoderContext>, \
868 api::node::ZlibUtil::CompressionStream<api::node::ZstdEncoderContext>, \
869 api::node::ZlibUtil::CompressionStream<api::node::ZstdDecoderContext>, \
870 api::node::ZlibContext::Options, api::node::BrotliContext::Options, \
871 api::node::ZstdContext::Options
872 
873} // namespace workerd::api::node
874 
875KJ_DECLARE_NON_POLYMORPHIC(BrotliEncoderStateStruct)
876KJ_DECLARE_NON_POLYMORPHIC(BrotliDecoderStateStruct)
877KJ_DECLARE_NON_POLYMORPHIC(ZSTD_CCtx)
878KJ_DECLARE_NON_POLYMORPHIC(ZSTD_DCtx)