In preparation for introducing a new manifest format.
src/compopt.c \
src/compr_none.c \
src/compr_zlib.c \
+ src/compression.c \
src/conf.c \
src/confitems.c \
src/counters.c \
}
struct stat orig_dest_st;
bool orig_dest_existed = stat(cached_result, &orig_dest_st) == 0;
- int compression_level = conf->compression ? conf->compression_level : 0;
- result_put(cached_result, filelist, compression_level);
+ result_put(cached_result, filelist);
filelist_free(filelist);
cc_log("Stored in cache: %s", cached_result);
return ferror(output) == 0;
}
-struct compressor compr_none = {
+struct compressor compressor_none_impl = {
compr_none_init,
compr_none_write,
compr_none_free
return success;
}
-struct compressor compr_zlib = {
+struct compressor compressor_zlib_impl = {
compr_zlib_init,
compr_zlib_write,
compr_zlib_free
--- /dev/null
+// Copyright (C) 2019 Joel Rosdahl
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "compression.h"
+#include "conf.h"
+
+extern struct conf *conf;
+
+int8_t compression_level_from_config(void)
+{
+ return conf->compression ? conf->compression_level : 0;
+}
+
+enum compression_type compression_type_from_config(void)
+{
+ return conf->compression ? COMPR_TYPE_ZLIB : COMPR_TYPE_NONE;
+}
+
+const char *compression_type_to_string(enum compression_type type)
+{
+ switch (type) {
+ case COMPR_TYPE_NONE:
+ return "none";
+
+ case COMPR_TYPE_ZLIB:
+ return "zlib";
+ }
+
+ return "unknown";
+}
+
+struct compressor *compressor_from_type(enum compression_type type)
+{
+ switch (type) {
+ case COMPR_TYPE_NONE:
+ return &compressor_none_impl;
+
+ case COMPR_TYPE_ZLIB:
+ return &compressor_zlib_impl;
+ }
+
+ return NULL;
+}
+
+struct decompressor *decompressor_from_type(enum compression_type type)
+{
+ switch (type) {
+ case COMPR_TYPE_NONE:
+ return &decompressor_none_impl;
+
+ case COMPR_TYPE_ZLIB:
+ return &decompressor_zlib_impl;
+
+ }
+
+ return NULL;
+}
+
+
bool (*free)(struct decompr_state *state);
};
-extern struct compressor compr_none;
-extern struct decompressor decompr_none;
+enum compression_type {
+ COMPR_TYPE_NONE = 0,
+ COMPR_TYPE_ZLIB = 1
+};
+
+extern struct compressor compressor_none_impl;
+extern struct decompressor decompressor_none_impl;
+
+extern struct compressor compressor_zlib_impl;
+extern struct decompressor decompressor_zlib_impl;
-extern struct compressor compr_zlib;
-extern struct decompressor decompr_zlib;
+int8_t compression_level_from_config(void);
+enum compression_type compression_type_from_config(void);
+const char *compression_type_to_string(enum compression_type type);
+struct compressor *compressor_from_type(enum compression_type type);
+struct decompressor *decompressor_from_type(enum compression_type type);
#endif
return ferror(input) == 0;
}
-struct decompressor decompr_none = {
+struct decompressor decompressor_none_impl = {
decompr_none_init,
decompr_none_read,
decompr_none_free
return success;
}
-struct decompressor decompr_zlib = {
+struct decompressor decompressor_zlib_impl = {
decompr_zlib_init,
decompr_zlib_read,
decompr_zlib_free
REF_MARKER = 1
};
-enum {
- COMPR_TYPE_NONE = 0,
- COMPR_TYPE_ZLIB = 1
-};
-
struct file {
char *suffix;
char *path;
MAGIC[0], MAGIC[1], MAGIC[2], MAGIC[3]);
fprintf(dump_stream, "Version: %u\n", version);
fprintf(dump_stream, "Compression type: %s\n",
- compr_type == COMPR_TYPE_NONE ? "none" : "zlib");
+ compression_type_to_string(compr_type));
fprintf(dump_stream, "Compression level: %d\n", compr_level);
fprintf(dump_stream, "Content size: %" PRIu64 "\n", content_len);
}
}
}
- switch (compr_type) {
- case COMPR_TYPE_NONE:
- decompressor = &decompr_none;
- break;
-
- case COMPR_TYPE_ZLIB:
- decompressor = &decompr_zlib;
- break;
-
- default:
+ decompressor = decompressor_from_type(compr_type);
+ if (!decompressor) {
*errmsg = format("Unknown compression type: %u", compr_type);
goto out;
}
return success;
}
-bool result_put(const char *path, struct filelist *list, int compression_level)
+bool result_put(const char *path, struct filelist *list)
{
bool ret = false;
char *tmp_file = format("%s.tmp", path);
goto out;
}
+ int8_t compr_level = compression_level_from_config();
+ enum compression_type compr_type = compression_type_from_config();
+
char header[15];
memcpy(header, MAGIC, sizeof(MAGIC));
header[4] = RESULT_VERSION;
- header[5] = compression_level == 0 ? COMPR_TYPE_NONE : COMPR_TYPE_ZLIB;
- header[6] = compression_level;
+ header[5] = compr_type;
+ header[6] = compr_level;
uint64_t content_size = sizeof(header);
content_size += 1; // n_entries
for (uint32_t i = 0; i < list->n_files; i++) {
goto out;
}
- struct compressor *compressor;
- if (compression_level == 0) {
- compressor = &compr_none;
- } else {
- compressor = &compr_zlib;
- }
-
- struct compr_state *compr_state = compressor->init(f, compression_level);
+ struct compressor *compressor = compressor_from_type(compr_type);
+ assert(compressor);
+ struct compr_state *compr_state = compressor->init(f, compr_level);
if (!compr_state) {
cc_log("Failed to initialize compressor");
goto out;
void filelist_free(struct filelist *c);
bool result_get(const char *path, struct filelist *list);
-bool result_put(const char *path, struct filelist *list, int compression_level);
+bool result_put(const char *path, struct filelist *list);
bool result_dump(const char *path, FILE *stream);
#endif
TEST(zlib_small_roundtrip)
{
FILE *f = fopen("data.zlib", "w");
- struct compr_state *c_state = compr_zlib.init(f, -1);
+ struct compressor *compr_zlib = compressor_from_type(COMPR_TYPE_ZLIB);
+ struct compr_state *c_state = compr_zlib->init(f, -1);
CHECK(c_state);
- CHECK(compr_zlib.write(c_state, "foobar", 6));
+ CHECK(compr_zlib->write(c_state, "foobar", 6));
- CHECK(compr_zlib.free(c_state));
+ CHECK(compr_zlib->free(c_state));
fclose(f);
f = fopen("data.zlib", "r");
- struct decompr_state *d_state = decompr_zlib.init(f);
+ struct decompressor *decompr_zlib = decompressor_from_type(COMPR_TYPE_ZLIB);
+ struct decompr_state *d_state = decompr_zlib->init(f);
CHECK(d_state);
char buffer[4];
- CHECK(decompr_zlib.read(d_state, buffer, 4));
+ CHECK(decompr_zlib->read(d_state, buffer, 4));
CHECK(memcmp(buffer, "foob", 4) == 0);
- CHECK(decompr_zlib.read(d_state, buffer, 2));
+ CHECK(decompr_zlib->read(d_state, buffer, 2));
CHECK(memcmp(buffer, "ar", 2) == 0);
// Nothing left to read.
- CHECK(!decompr_zlib.read(d_state, buffer, 1));
+ CHECK(!decompr_zlib->read(d_state, buffer, 1));
// Error state is remembered.
- CHECK(!decompr_zlib.free(d_state));
+ CHECK(!decompr_zlib->free(d_state));
fclose(f);
}
char data[] = "The quick brown fox jumps over the lazy dog";
FILE *f = fopen("data.zlib", "w");
- struct compr_state *c_state = compr_zlib.init(f, 1);
+ struct compressor *compr_zlib = compressor_from_type(COMPR_TYPE_ZLIB);
+ struct compr_state *c_state = compr_zlib->init(f, 1);
CHECK(c_state);
for (size_t i = 0; i < 1000; i++) {
- CHECK(compr_zlib.write(c_state, data, sizeof(data)));
+ CHECK(compr_zlib->write(c_state, data, sizeof(data)));
}
- CHECK(compr_zlib.free(c_state));
+ CHECK(compr_zlib->free(c_state));
fclose(f);
f = fopen("data.zlib", "r");
- struct decompr_state *d_state = decompr_zlib.init(f);
+ struct decompressor *decompr_zlib = decompressor_from_type(COMPR_TYPE_ZLIB);
+ struct decompr_state *d_state = decompr_zlib->init(f);
CHECK(d_state);
char buffer[sizeof(data)];
for (size_t i = 0; i < 1000; i++) {
- CHECK(decompr_zlib.read(d_state, buffer, sizeof(buffer)));
+ CHECK(decompr_zlib->read(d_state, buffer, sizeof(buffer)));
CHECK(memcmp(buffer, data, sizeof(data)) == 0);
}
// Nothing left to read.
- CHECK(!decompr_zlib.read(d_state, buffer, 1));
+ CHECK(!decompr_zlib->read(d_state, buffer, 1));
// Error state is remembered.
- CHECK(!decompr_zlib.free(d_state));
+ CHECK(!decompr_zlib->free(d_state));
fclose(f);
}
}
FILE *f = fopen("data.zlib", "w");
- struct compr_state *c_state = compr_zlib.init(f, 1);
+ struct compressor *compr_zlib = compressor_from_type(COMPR_TYPE_ZLIB);
+ struct compr_state *c_state = compr_zlib->init(f, 1);
CHECK(c_state);
- CHECK(compr_zlib.write(c_state, data, sizeof(data)));
+ CHECK(compr_zlib->write(c_state, data, sizeof(data)));
- CHECK(compr_zlib.free(c_state));
+ CHECK(compr_zlib->free(c_state));
fclose(f);
f = fopen("data.zlib", "r");
- struct decompr_state *d_state = decompr_zlib.init(f);
+ struct decompressor *decompr_zlib = decompressor_from_type(COMPR_TYPE_ZLIB);
+ struct decompr_state *d_state = decompr_zlib->init(f);
CHECK(d_state);
char buffer[sizeof(data)];
- CHECK(decompr_zlib.read(d_state, buffer, sizeof(buffer)));
+ CHECK(decompr_zlib->read(d_state, buffer, sizeof(buffer)));
CHECK(memcmp(buffer, data, sizeof(data)) == 0);
- CHECK(decompr_zlib.free(d_state));
+ CHECK(decompr_zlib->free(d_state));
fclose(f);
}