diff options
author | Patrick McDermott <patrick.mcdermott@libiquity.com> | 2023-04-13 10:48:12 (EDT) |
---|---|---|
committer | Patrick McDermott <patrick.mcdermott@libiquity.com> | 2023-04-14 14:33:37 (EDT) |
commit | 8ff8f191845a76aca15ce1f1bdbf1d28087d2bc5 (patch) | |
tree | e71d16b44875c97626bcf181baa5fb0887be4e72 | |
parent | 6c5ea040feeab83ad27f58b5c5c5edb699fa545e (diff) |
gzip: Rewrite
-rw-r--r-- | src/gzip.c | 131 | ||||
-rw-r--r-- | src/gzip.h | 22 |
2 files changed, 51 insertions, 102 deletions
@@ -17,115 +17,78 @@ * along with opkg-opkg. If not, see <http://www.gnu.org/licenses/>. */ -#include <stdio.h> +#include <stdlib.h> #include <zlib.h> #include "defs.h" #include "gzip.h" -static int -_opkg_opk_gzip_init(struct opkg_opk_gzip_state *state) -{ - state->stream.zalloc = Z_NULL; - state->stream.zfree = Z_NULL; - state->stream.opaque = Z_NULL; - if (inflateInit2(&state->stream, 15 + 16) != Z_OK) { - return OPKG_OPK_ERROR; - } - return OPKG_OPK_OK; -} +struct opkg_opk_gzip { + int (*read)(void *, char **, size_t *); + void *user_data; + z_stream stream; +}; -int -opkg_opk_gzip_init_from_file(struct opkg_opk_gzip_state *state, - const char *file_name) +struct opkg_opk_gzip * +opkg_opk_gzip_init(int (*read)(void *, char **, size_t *), void *user_data) { - state->input_file = fopen(file_name, "rb"); - if (state->input_file == NULL) { - return OPKG_OPK_ERROR; + struct opkg_opk_gzip *gzip; + + gzip = malloc(sizeof(*gzip)); + if (gzip == NULL) { + return NULL; } - state->stream.next_in = Z_NULL; - state->stream.avail_in = 0; - if (_opkg_opk_gzip_init(state) < OPKG_OPK_OK) { - fclose(state->input_file); - return OPKG_OPK_ERROR; + + gzip->read = read; + gzip->user_data = user_data; + + gzip->stream.next_in = Z_NULL; + gzip->stream.avail_in = 0; + gzip->stream.zalloc = Z_NULL; + gzip->stream.zfree = Z_NULL; + gzip->stream.opaque = Z_NULL; + if (inflateInit2(&gzip->stream, 15 + 16) != Z_OK) { + free(gzip); + return NULL; } - return OPKG_OPK_OK; + + return gzip; } int -opkg_opk_gzip_init_from_memory(struct opkg_opk_gzip_state *state, - unsigned char *input, size_t input_size) +opkg_opk_gzip_read(struct opkg_opk_gzip *gzip, void *record) { - state->input_file = NULL; - state->stream.next_in = input; - state->stream.avail_in = input_size; - return _opkg_opk_gzip_init(state); -} + gzip->stream.next_out = record; + gzip->stream.avail_out = 512; -static int -_opkg_opk_gzip_next_record_from_file(struct opkg_opk_gzip_state *state) -{ for (;;) { - if (state->stream.avail_in == 0) { - if (feof(state->input_file)) { - fclose(state->input_file); - state->input_file = NULL; - inflateEnd(&state->stream); - return OPKG_OPK_ERROR; + if (gzip->stream.avail_in == 0) { + /* Input buffer is empty and needs refilled. */ + switch (gzip->read(gzip->user_data, + &gzip->stream.next_in, + &gzip->stream.avail_in)) { + case OPKG_OPK_OK: + case OPKG_OPK_END: + break; + case OPKG_OPK_ERROR: + default: + inflateEnd(&gzip->stream); + return OPKG_OPK_ERROR; } - state->stream.avail_in = fread(state->input_buffer, - 1, OPKG_OPK_GZIP_BUFFER_SIZE, - state->input_file); - if (ferror(state->input_file)) { - fclose(state->input_file); - state->input_file = NULL; - inflateEnd(&state->stream); - return OPKG_OPK_ERROR; - } - state->stream.next_in = state->input_buffer; } - if (state->stream.avail_out == 0) { + if (gzip->stream.avail_out == 0) { + /* Output buffer is filled and ready for use. */ return OPKG_OPK_OK; } - switch (inflate(&state->stream, Z_SYNC_FLUSH)) { + switch (inflate(&gzip->stream, Z_SYNC_FLUSH)) { case Z_OK: case Z_BUF_ERROR: break; case Z_STREAM_END: - fclose(state->input_file); - state->input_file = NULL; - inflateEnd(&state->stream); + inflateEnd(&gzip->stream); return OPKG_OPK_END; default: - fclose(state->input_file); - state->input_file = NULL; - inflateEnd(&state->stream); + inflateEnd(&gzip->stream); return OPKG_OPK_ERROR; } } } - -static int -_opkg_opk_gzip_next_record_from_memory(struct opkg_opk_gzip_state *state) -{ - switch (inflate(&state->stream, Z_SYNC_FLUSH)) { - case Z_OK: - return OPKG_OPK_OK; - case Z_STREAM_END: - return OPKG_OPK_END; - default: - inflateEnd(&state->stream); - return OPKG_OPK_ERROR; - } -} - -int -opkg_opk_gzip_next_record(struct opkg_opk_gzip_state *state, void *record) -{ - state->stream.next_out = record; - state->stream.avail_out = 512; - if (state->input_file != NULL) { - return _opkg_opk_gzip_next_record_from_file(state); - } else { - return _opkg_opk_gzip_next_record_from_memory(state); - } -} @@ -20,26 +20,12 @@ #ifndef OPKG_OPK_GZIP_H_ #define OPKG_OPK_GZIP_H_ -#include <stdio.h> -#include <zlib.h> +struct opkg_opk_gzip; -#define OPKG_OPK_GZIP_BUFFER_SIZE 8192 - -struct opkg_opk_gzip_state { - FILE *input_file; - unsigned char input_buffer[OPKG_OPK_GZIP_BUFFER_SIZE]; - z_stream stream; -}; - -int -opkg_opk_gzip_init_from_file(struct opkg_opk_gzip_state *state, - const char *file_name); - -int -opkg_opk_gzip_init_from_memory(struct opkg_opk_gzip_state *state, - unsigned char *input, size_t input_size); +struct opkg_opk_gzip * +opkg_opk_gzip_init(int (*read)(void *, char **, size_t *), void *user_data); int -opkg_opk_gzip_next_record(struct opkg_opk_gzip_state *state, void *record); +opkg_opk_gzip_read(struct opkg_opk_gzip *gzip, void *record); #endif /* OPKG_OPK_GZIP_H_ */ |