@@ -324,7 +324,8 @@ class ZstdCompressContext final : public ZstdContext {
324
324
CompressionError ResetStream ();
325
325
326
326
// Zstd specific:
327
- CompressionError Init (uint64_t pledged_src_size);
327
+ CompressionError Init (uint64_t pledged_src_size,
328
+ std::string_view dictionary = {});
328
329
CompressionError SetParameter (int key, int value);
329
330
330
331
// Wrap ZSTD_freeCCtx to remove the return type.
@@ -349,7 +350,9 @@ class ZstdDecompressContext final : public ZstdContext {
349
350
CompressionError ResetStream ();
350
351
351
352
// Zstd specific:
352
- CompressionError Init (uint64_t pledged_src_size);
353
+ CompressionError Init (uint64_t pledged_src_size,
354
+ std::string_view dictionary = {});
355
+
353
356
CompressionError SetParameter (int key, int value);
354
357
355
358
// Wrap ZSTD_freeDCtx to remove the return type.
@@ -875,8 +878,10 @@ class ZstdStream final : public CompressionStream<CompressionContext> {
875
878
Environment* env = Environment::GetCurrent (args);
876
879
Local<Context> context = env->context ();
877
880
878
- CHECK (args.Length () == 4 &&
879
- " init(params, pledgedSrcSize, writeResult, writeCallback)" );
881
+ CHECK ((args.Length () == 4 || args.Length () == 5 ) &&
882
+ " init(params, pledgedSrcSize, writeResult, writeCallback[, "
883
+ " dictionary])" );
884
+
880
885
ZstdStream* wrap;
881
886
ASSIGN_OR_RETURN_UNWRAP (&wrap, args.This ());
882
887
@@ -904,7 +909,19 @@ class ZstdStream final : public CompressionStream<CompressionContext> {
904
909
}
905
910
906
911
AllocScope alloc_scope (wrap);
907
- CompressionError err = wrap->context ()->Init (pledged_src_size);
912
+ std::string_view dictionary;
913
+ ArrayBufferViewContents<char > contents;
914
+ if (args.Length () == 5 && !args[4 ]->IsUndefined ()) {
915
+ if (!args[4 ]->IsArrayBufferView ()) {
916
+ THROW_ERR_INVALID_ARG_TYPE (
917
+ wrap->env (), " dictionary must be an ArrayBufferView if provided" );
918
+ return ;
919
+ }
920
+ contents.ReadValue (args[4 ]);
921
+ dictionary = std::string_view (contents.data (), contents.length ());
922
+ }
923
+
924
+ CompressionError err = wrap->context ()->Init (pledged_src_size, dictionary);
908
925
if (err.IsError ()) {
909
926
wrap->EmitError (err);
910
927
THROW_ERR_ZLIB_INITIALIZATION_FAILED (wrap->env (), err.message );
@@ -1509,14 +1526,26 @@ CompressionError ZstdCompressContext::SetParameter(int key, int value) {
1509
1526
return {};
1510
1527
}
1511
1528
1512
- CompressionError ZstdCompressContext::Init (uint64_t pledged_src_size) {
1529
+ CompressionError ZstdCompressContext::Init (uint64_t pledged_src_size,
1530
+ std::string_view dictionary) {
1513
1531
pledged_src_size_ = pledged_src_size;
1514
1532
cctx_.reset (ZSTD_createCCtx ());
1515
1533
if (!cctx_) {
1516
1534
return CompressionError (" Could not initialize zstd instance" ,
1517
1535
" ERR_ZLIB_INITIALIZATION_FAILED" ,
1518
1536
-1 );
1519
1537
}
1538
+
1539
+ if (!dictionary.empty ()) {
1540
+ size_t ret = ZSTD_CCtx_loadDictionary (
1541
+ cctx_.get (), dictionary.data (), dictionary.size ());
1542
+ if (ZSTD_isError (ret)) {
1543
+ return CompressionError (" Failed to load zstd dictionary" ,
1544
+ " ERR_ZLIB_DICTIONARY_LOAD_FAILED" ,
1545
+ -1 );
1546
+ }
1547
+ }
1548
+
1520
1549
size_t result = ZSTD_CCtx_setPledgedSrcSize (cctx_.get (), pledged_src_size);
1521
1550
if (ZSTD_isError (result)) {
1522
1551
return CompressionError (
@@ -1549,13 +1578,24 @@ CompressionError ZstdDecompressContext::SetParameter(int key, int value) {
1549
1578
return {};
1550
1579
}
1551
1580
1552
- CompressionError ZstdDecompressContext::Init (uint64_t pledged_src_size) {
1581
+ CompressionError ZstdDecompressContext::Init (uint64_t pledged_src_size,
1582
+ std::string_view dictionary) {
1553
1583
dctx_.reset (ZSTD_createDCtx ());
1554
1584
if (!dctx_) {
1555
1585
return CompressionError (" Could not initialize zstd instance" ,
1556
1586
" ERR_ZLIB_INITIALIZATION_FAILED" ,
1557
1587
-1 );
1558
1588
}
1589
+
1590
+ if (!dictionary.empty ()) {
1591
+ size_t ret = ZSTD_DCtx_loadDictionary (
1592
+ dctx_.get (), dictionary.data (), dictionary.size ());
1593
+ if (ZSTD_isError (ret)) {
1594
+ return CompressionError (" Failed to load zstd dictionary" ,
1595
+ " ERR_ZLIB_DICTIONARY_LOAD_FAILED" ,
1596
+ -1 );
1597
+ }
1598
+ }
1559
1599
return {};
1560
1600
}
1561
1601
0 commit comments