aboutsummaryrefslogtreecommitdiffstats
path: root/com32/libupload/zout.c
diff options
context:
space:
mode:
Diffstat (limited to 'com32/libupload/zout.c')
-rw-r--r--com32/libupload/zout.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/com32/libupload/zout.c b/com32/libupload/zout.c
new file mode 100644
index 00000000..b5575a9f
--- /dev/null
+++ b/com32/libupload/zout.c
@@ -0,0 +1,99 @@
+/*
+ * Compress input and feed it to a block-oriented back end.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <zlib.h>
+#include "upload_backend.h"
+#include "ctime.h"
+
+#define ALLOC_CHUNK 65536
+
+int init_data(struct upload_backend *be, const char *argv[])
+{
+ be->now = posix_time();
+ be->argv = argv;
+
+ memset(&be->zstream, 0, sizeof be->zstream);
+
+ be->zstream.next_out = NULL;
+ be->outbuf = NULL;
+ be->zstream.avail_out = be->alloc = 0;
+ be->dbytes = be->zbytes = 0;
+
+ /* Initialize a gzip data stream */
+ if (deflateInit2(&be->zstream, 9, Z_DEFLATED,
+ 16+15, 9, Z_DEFAULT_STRATEGY) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int do_deflate(struct upload_backend *be, int flush)
+{
+ int rv;
+ char *buf;
+
+ while (1) {
+ rv = deflate(&be->zstream, flush);
+ be->zbytes = be->alloc - be->zstream.avail_out;
+ if (be->zstream.avail_out)
+ return rv; /* Not an issue of output space... */
+
+ buf = realloc(be->outbuf, be->alloc + ALLOC_CHUNK);
+ if (!buf)
+ return Z_MEM_ERROR;
+ be->outbuf = buf;
+ be->alloc += ALLOC_CHUNK;
+ be->zstream.next_out = (void *)(buf + be->zbytes);
+ be->zstream.avail_out = be->alloc - be->zbytes;
+ }
+}
+
+
+int write_data(struct upload_backend *be, const void *buf, size_t len)
+{
+ int rv = Z_OK;
+
+ be->zstream.next_in = (void *)buf;
+ be->zstream.avail_in = len;
+
+ be->dbytes += len;
+
+ while (be->zstream.avail_in) {
+ rv = do_deflate(be, Z_NO_FLUSH);
+ if (rv < 0) {
+ printf("do_deflate returned %d\n", rv);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/* Output the data and shut down the stream */
+int flush_data(struct upload_backend *be)
+{
+ int rv = Z_OK;
+
+ while (rv != Z_STREAM_END) {
+ rv = do_deflate(be, Z_FINISH);
+ if (rv < 0)
+ return -1;
+ }
+
+ printf("Uploading data, %u bytes... ", be->zbytes);
+
+ if (be->write(be))
+ return -1;
+
+ free(be->outbuf);
+ be->outbuf = NULL;
+ be->dbytes = be->zbytes = be->alloc = 0;
+
+ printf("done.\n");
+ return 0;
+}