summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gzip.c131
-rw-r--r--src/gzip.h22
2 files changed, 51 insertions, 102 deletions
diff --git a/src/gzip.c b/src/gzip.c
index f3fbdb9..2596739 100644
--- a/src/gzip.c
+++ b/src/gzip.c
@@ -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);
- }
-}
diff --git a/src/gzip.h b/src/gzip.h
index bdab8f2..409de51 100644
--- a/src/gzip.h
+++ b/src/gzip.h
@@ -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_ */