@@ -324,7 +324,8 @@ class ZstdCompressContext final : public ZstdContext {
324324 CompressionError ResetStream ();
325325
326326 // Zstd specific:
327- CompressionError Init (uint64_t pledged_src_size);
327+ CompressionError Init (uint64_t pledged_src_size,
328+ std::string_view dictionary = {});
328329 CompressionError SetParameter (int key, int value);
329330
330331 // Wrap ZSTD_freeCCtx to remove the return type.
@@ -349,7 +350,9 @@ class ZstdDecompressContext final : public ZstdContext {
349350 CompressionError ResetStream ();
350351
351352 // Zstd specific:
352- CompressionError Init (uint64_t pledged_src_size);
353+ CompressionError Init (uint64_t pledged_src_size,
354+ std::string_view dictionary = {});
355+
353356 CompressionError SetParameter (int key, int value);
354357
355358 // Wrap ZSTD_freeDCtx to remove the return type.
@@ -874,8 +877,10 @@ class ZstdStream final : public CompressionStream<CompressionContext> {
874877 Environment* env = Environment::GetCurrent (args);
875878 Local<Context> context = env->context ();
876879
877- CHECK (args.Length () == 4 &&
878- " init(params, pledgedSrcSize, writeResult, writeCallback)" );
880+ CHECK ((args.Length () == 4 || args.Length () == 5 ) &&
881+ " init(params, pledgedSrcSize, writeResult, writeCallback[, "
882+ " dictionary])" );
883+
879884 ZstdStream* wrap;
880885 ASSIGN_OR_RETURN_UNWRAP (&wrap, args.This ());
881886
@@ -903,7 +908,19 @@ class ZstdStream final : public CompressionStream<CompressionContext> {
903908 }
904909
905910 AllocScope alloc_scope (wrap);
906- CompressionError err = wrap->context ()->Init (pledged_src_size);
911+ std::string_view dictionary;
912+ ArrayBufferViewContents<char > contents;
913+ if (args.Length () == 5 && !args[4 ]->IsUndefined ()) {
914+ if (!args[4 ]->IsArrayBufferView ()) {
915+ THROW_ERR_INVALID_ARG_TYPE (
916+ wrap->env (), " dictionary must be an ArrayBufferView if provided" );
917+ return ;
918+ }
919+ contents.ReadValue (args[4 ]);
920+ dictionary = std::string_view (contents.data (), contents.length ());
921+ }
922+
923+ CompressionError err = wrap->context ()->Init (pledged_src_size, dictionary);
907924 if (err.IsError ()) {
908925 wrap->EmitError (err);
909926 THROW_ERR_ZLIB_INITIALIZATION_FAILED (wrap->env (), err.message );
@@ -1508,14 +1525,26 @@ CompressionError ZstdCompressContext::SetParameter(int key, int value) {
15081525 return {};
15091526}
15101527
1511- CompressionError ZstdCompressContext::Init (uint64_t pledged_src_size) {
1528+ CompressionError ZstdCompressContext::Init (uint64_t pledged_src_size,
1529+ std::string_view dictionary) {
15121530 pledged_src_size_ = pledged_src_size;
15131531 cctx_.reset (ZSTD_createCCtx ());
15141532 if (!cctx_) {
15151533 return CompressionError (" Could not initialize zstd instance" ,
15161534 " ERR_ZLIB_INITIALIZATION_FAILED" ,
15171535 -1 );
15181536 }
1537+
1538+ if (!dictionary.empty ()) {
1539+ size_t ret = ZSTD_CCtx_loadDictionary (
1540+ cctx_.get (), dictionary.data (), dictionary.size ());
1541+ if (ZSTD_isError (ret)) {
1542+ return CompressionError (" Failed to load zstd dictionary" ,
1543+ " ERR_ZLIB_DICTIONARY_LOAD_FAILED" ,
1544+ -1 );
1545+ }
1546+ }
1547+
15191548 size_t result = ZSTD_CCtx_setPledgedSrcSize (cctx_.get (), pledged_src_size);
15201549 if (ZSTD_isError (result)) {
15211550 return CompressionError (
@@ -1548,13 +1577,24 @@ CompressionError ZstdDecompressContext::SetParameter(int key, int value) {
15481577 return {};
15491578}
15501579
1551- CompressionError ZstdDecompressContext::Init (uint64_t pledged_src_size) {
1580+ CompressionError ZstdDecompressContext::Init (uint64_t pledged_src_size,
1581+ std::string_view dictionary) {
15521582 dctx_.reset (ZSTD_createDCtx ());
15531583 if (!dctx_) {
15541584 return CompressionError (" Could not initialize zstd instance" ,
15551585 " ERR_ZLIB_INITIALIZATION_FAILED" ,
15561586 -1 );
15571587 }
1588+
1589+ if (!dictionary.empty ()) {
1590+ size_t ret = ZSTD_DCtx_loadDictionary (
1591+ dctx_.get (), dictionary.data (), dictionary.size ());
1592+ if (ZSTD_isError (ret)) {
1593+ return CompressionError (" Failed to load zstd dictionary" ,
1594+ " ERR_ZLIB_DICTIONARY_LOAD_FAILED" ,
1595+ -1 );
1596+ }
1597+ }
15581598 return {};
15591599}
15601600
0 commit comments