@@ -38,11 +38,13 @@ struct ZSTDDCtxDeleter {
38
38
struct ZstdCCtxWithBuffer {
39
39
ZSTD_CCtx* cctx;
40
40
ZSTD_outBuffer out;
41
+ ZSTD_CDict** dict;
41
42
};
42
43
43
44
struct ZstdDCtxWithBuffer {
44
45
ZSTD_DCtx* dctx;
45
46
ZSTD_outBuffer out;
47
+ ZSTD_DDict** dict;
46
48
};
47
49
48
50
void zstd_nif_compress_dictionary_destructor (ErlNifEnv *env, void *res) {
@@ -61,13 +63,19 @@ void zstd_nif_compression_context_destructor(ErlNifEnv *env, void *res) {
61
63
UNUSED (env);
62
64
ZstdCCtxWithBuffer* ctx_resource = static_cast <ZstdCCtxWithBuffer*>(res);
63
65
ZSTD_freeCCtx (ctx_resource->cctx );
66
+ if (ctx_resource->dict != nullptr ) {
67
+ enif_release_resource (ctx_resource->dict );
68
+ }
64
69
enif_free (ctx_resource->out .dst );
65
70
}
66
71
67
72
void zstd_nif_decompression_context_destructor (ErlNifEnv *env, void *res) {
68
73
UNUSED (env);
69
74
ZstdDCtxWithBuffer* ctx_resource = static_cast <ZstdDCtxWithBuffer*>(res);
70
75
ZSTD_freeDCtx (ctx_resource->dctx );
76
+ if (ctx_resource->dict != nullptr ) {
77
+ enif_release_resource (ctx_resource->dict );
78
+ }
71
79
enif_free (ctx_resource->out .dst );
72
80
}
73
81
@@ -197,6 +205,7 @@ static ERL_NIF_TERM zstd_nif_create_compression_context(ErlNifEnv* env, int argc
197
205
resource->out .dst = buffer;
198
206
resource->out .pos = 0 ;
199
207
resource->out .size = out_buffer_size;
208
+ resource->dict = nullptr ;
200
209
201
210
ERL_NIF_TERM result = enif_make_resource (env, resource);
202
211
@@ -234,6 +243,7 @@ static ERL_NIF_TERM zstd_nif_create_decompression_context(ErlNifEnv* env, int ar
234
243
resource->out .dst = buffer;
235
244
resource->out .pos = 0 ;
236
245
resource->out .size = out_buffer_size;
246
+ resource->dict = nullptr ;
237
247
238
248
ERL_NIF_TERM result = enif_make_resource (env, resource);
239
249
@@ -253,6 +263,12 @@ static ERL_NIF_TERM zstd_nif_select_cdict(ErlNifEnv* env, int argc, const ERL_NI
253
263
}
254
264
255
265
size_t result = ZSTD_CCtx_refCDict (ctx_resource->cctx , *dict_resource);
266
+ if (ctx_resource->dict != nullptr ) {
267
+ // refCDict replaces the dictionary for this context, so we can't use the old one.
268
+ enif_release_resource (ctx_resource->dict );
269
+ }
270
+ ctx_resource->dict = dict_resource;
271
+ enif_keep_resource (dict_resource);
256
272
257
273
if (ZSTD_isError (result)) {
258
274
return make_error (env, " failed to set dictionary" );
@@ -273,6 +289,13 @@ static ERL_NIF_TERM zstd_nif_select_ddict(ErlNifEnv* env, int argc, const ERL_NI
273
289
}
274
290
275
291
size_t result = ZSTD_DCtx_refDDict (ctx_resource->dctx , *dict_resource);
292
+ if (ctx_resource->dict != nullptr ) {
293
+ // We do not support ZSTD_d_refMultipleDDicts so setting a new one means we no longer could want
294
+ // to use the old dictionary.
295
+ enif_release_resource (ctx_resource->dict );
296
+ }
297
+ ctx_resource->dict = dict_resource;
298
+ enif_keep_resource (dict_resource);
276
299
277
300
if (ZSTD_isError (result)) {
278
301
return make_error (env, " failed to set dictionary" );
0 commit comments