}
}
+static ssize_t zstd_write(void* data, const char* buffer, size_t size) {
+ struct zstd_cookie* cookie = (struct zstd_cookie*)data;
+ if (!cookie)
+ return -1;
+
+ // Do not write when mode is "r"
+ if (cookie->mode == 'r')
+ return -1;
+
+ // Return nothing when there is no input
+ if (size == 0)
+ return 0;
+
+ // Configure input buffer
+ cookie->in.src = buffer;
+ cookie->in.pos = 0;
+ cookie->in.size = size;
+
+ while (1) {
+ cookie->out.pos = 0;
+
+ size_t r = ZSTD_compressStream(cookie->cstream, &cookie->out, &cookie->in);
+ if (ZSTD_isError(r))
+ return -1;
+
+ if (cookie->out.pos > 0) {
+ size_t bytes_written = fwrite(cookie->buffer, 1, cookie->out.pos, cookie->f);
+
+ if (bytes_written != cookie->out.pos)
+ return -1;
+ }
+
+ // Return when all input has been written
+ if (cookie->in.pos == size)
+ return size;
+ }
+}
+
static int zstd_close(void* data) {
struct zstd_cookie* cookie = (struct zstd_cookie*)data;
if (!cookie)
return -1;
- // XXX handle write
+ if (cookie->mode == 'w') {
+ while (1) {
+ // Reset output buffer
+ cookie->out.pos = 0;
+
+ size_t r = ZSTD_endStream(cookie->cstream, &cookie->out);
+ if (ZSTD_isError(r))
+ return -1;
+
+ if (cookie->out.pos > 0) {
+ size_t bytes_written = fwrite(cookie->buffer, 1, cookie->out.pos, cookie->f);
+
+ if (bytes_written != cookie->out.pos)
+ return -1;
+ }
+
+ if (r == 0)
+ break;
+ }
+ }
int r = fclose(cookie->f);
static cookie_io_functions_t zstd_functions = {
.read = zstd_read,
- //.write = zstd_write,
+ .write = zstd_write,
.seek = NULL,
.close = zstd_close,
};
return EXIT_SUCCESS;
}
-static int test_xzfopen_read(const struct test* t) {
- return read_test(t, pakfire_xzfopen, "data/compress/data.xz");
-}
-
-static int test_xzfopen_write(const struct test* t) {
+static int write_test(const struct test* t, FILE* (function)(FILE* f, const char* mode)) {
// Create a backend storage file
FILE* f = test_mktemp();
ASSERT(f);
// Open compressed file for writing
- f = pakfire_xzfopen(f, "w");
+ f = function(f, "w");
ASSERT(f);
// Write some data and close fwrite
return EXIT_SUCCESS;
}
+static int test_xzfopen_read(const struct test* t) {
+ return read_test(t, pakfire_xzfopen, "data/compress/data.xz");
+}
+
+static int test_xzfopen_write(const struct test* t) {
+ return write_test(t, pakfire_xzfopen);
+}
+
static int test_zstdfopen_read(const struct test* t) {
return read_test(t, pakfire_zstdfopen, "data/compress/data.zst");
}
+static int test_zstdfopen_write(const struct test* t) {
+ return write_test(t, pakfire_zstdfopen);
+}
+
static int test_xfopen(const struct test* t) {
return read_test(t, pakfire_xfopen, "data/compress/data.xz");
}
// ZSTD
testsuite_add_test(test_zstdfopen_read);
+ testsuite_add_test(test_zstdfopen_write);
testsuite_add_test(test_xfopen);