struct private_data {
int compression_level;
int threads;
+ int long_distance;
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
enum {
running,
#define CLEVEL_STD_MAX 19 /* without using --ultra */
#define CLEVEL_MAX 22
+#define LONG_STD 27
+
#define MINVER_NEGCLEVEL 10304
#define MINVER_MINCLEVEL 10306
+#define MINVER_LONG 10302
static int archive_compressor_zstd_options(struct archive_write_filter *,
const char *, const char *);
f->name = "zstd";
data->compression_level = CLEVEL_DEFAULT;
data->threads = 0;
+ data->long_distance = 0;
#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR
data->frame_per_file = 0;
data->min_frame_size = 0;
return (ARCHIVE_OK);
#endif
}
+ else if (strcmp(key, "long") == 0) {
+ intmax_t long_distance;
+ if (string_to_number(value, &long_distance) != ARCHIVE_OK) {
+ return (ARCHIVE_WARN);
+ }
+#if HAVE_ZSTD_H && HAVE_LIBZSTD_COMPRESSOR && ZSTD_VERSION_NUMBER >= MINVER_LONG
+ ZSTD_bounds bounds = ZSTD_cParam_getBounds(ZSTD_c_windowLog);
+ if (ZSTD_isError(bounds.error)) {
+ int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31));
+ if (((int)long_distance) < 10 || (int)long_distance > max_distance)
+ return (ARCHIVE_WARN);
+ } else {
+ if ((int)long_distance < bounds.lowerBound || (int)long_distance > bounds.upperBound)
+ return (ARCHIVE_WARN);
+ }
+#else
+ int max_distance = ((int)(sizeof(size_t) == 4 ? 30 : 31));
+ if (((int)long_distance) < 10 || (int)long_distance > max_distance)
+ return (ARCHIVE_WARN);
+#endif
+ data->long_distance = (int)long_distance;
+ return (ARCHIVE_OK);
+ }
/* Note: The "warn" return is just to inform the options
* supervisor that we didn't handle it. It will generate
ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_nbWorkers, data->threads);
+#if ZSTD_VERSION_NUMBER >= MINVER_LONG
+ ZSTD_CCtx_setParameter(data->cstream, ZSTD_c_windowLog, data->long_distance);
+#endif
+
return (ARCHIVE_OK);
}
archive_string_sprintf(&as, " --threads=%d", data->threads);
}
+ if (data->long_distance != 0) {
+ archive_string_sprintf(&as, " --long=%d", data->long_distance);
+ }
+
f->write = archive_compressor_zstd_write;
r = __archive_write_program_open(f, data->pdata, as.s);
archive_string_free(&as);
The value is interpreted as a decimal integer specifying the
compression level. Supported values depend on the library version,
common values are from 1 to 22.
+.It Cm long
+Enables long distance matching. The value is interpreted as a
+decimal integer specifying log2 window size in bytes. Values from
+10 to 30 for 32 bit, or 31 for 64 bit, are supported.
.It Cm threads
The value is interpreted as a decimal integer specifying the
number of threads for multi-threaded zstd compression.
archive_write_set_filter_option(a, NULL, "max-frame-size", "1024"));
assertEqualIntA(a, ARCHIVE_OK,
archive_write_set_filter_option(a, NULL, "max-frame-size", "1048576"));
+#endif
+#if ZSTD_VERSION_NUMBER >= MINVER_LONG
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_write_set_filter_option(a, NULL, "long", "27"));
+ assertEqualIntA(a, ARCHIVE_FAILED,
+ archive_write_set_filter_option(a, NULL, "long", "-1")); /* negative */
#endif
assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
for (i = 0; i < 100; i++) {