@@ -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.
@@ -874,8 +877,10 @@ class ZstdStream final : public CompressionStream<CompressionContext> {
874
877
Environment* env = Environment::GetCurrent (args);
875
878
Local<Context> context = env->context ();
876
879
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
+
879
884
ZstdStream* wrap;
880
885
ASSIGN_OR_RETURN_UNWRAP (&wrap, args.This ());
881
886
@@ -903,7 +908,19 @@ class ZstdStream final : public CompressionStream<CompressionContext> {
903
908
}
904
909
905
910
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);
907
924
if (err.IsError ()) {
908
925
wrap->EmitError (err);
909
926
THROW_ERR_ZLIB_INITIALIZATION_FAILED (wrap->env (), err.message );
@@ -1508,14 +1525,26 @@ CompressionError ZstdCompressContext::SetParameter(int key, int value) {
1508
1525
return {};
1509
1526
}
1510
1527
1511
- CompressionError ZstdCompressContext::Init (uint64_t pledged_src_size) {
1528
+ CompressionError ZstdCompressContext::Init (uint64_t pledged_src_size,
1529
+ std::string_view dictionary) {
1512
1530
pledged_src_size_ = pledged_src_size;
1513
1531
cctx_.reset (ZSTD_createCCtx ());
1514
1532
if (!cctx_) {
1515
1533
return CompressionError (" Could not initialize zstd instance" ,
1516
1534
" ERR_ZLIB_INITIALIZATION_FAILED" ,
1517
1535
-1 );
1518
1536
}
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
+
1519
1548
size_t result = ZSTD_CCtx_setPledgedSrcSize (cctx_.get (), pledged_src_size);
1520
1549
if (ZSTD_isError (result)) {
1521
1550
return CompressionError (
@@ -1548,13 +1577,24 @@ CompressionError ZstdDecompressContext::SetParameter(int key, int value) {
1548
1577
return {};
1549
1578
}
1550
1579
1551
- CompressionError ZstdDecompressContext::Init (uint64_t pledged_src_size) {
1580
+ CompressionError ZstdDecompressContext::Init (uint64_t pledged_src_size,
1581
+ std::string_view dictionary) {
1552
1582
dctx_.reset (ZSTD_createDCtx ());
1553
1583
if (!dctx_) {
1554
1584
return CompressionError (" Could not initialize zstd instance" ,
1555
1585
" ERR_ZLIB_INITIALIZATION_FAILED" ,
1556
1586
-1 );
1557
1587
}
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
+ }
1558
1598
return {};
1559
1599
}
1560
1600
0 commit comments