101 lines
2.0 KiB
C
101 lines
2.0 KiB
C
/*
|
|
* 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;
|
|
int err=-1;
|
|
|
|
while (rv != Z_STREAM_END) {
|
|
rv = do_deflate(be, Z_FINISH);
|
|
if (rv < 0)
|
|
return -1;
|
|
}
|
|
|
|
// printf("Uploading data, %u bytes... ", be->zbytes);
|
|
|
|
if ((err=be->write(be)) != 0)
|
|
return err;
|
|
|
|
free(be->outbuf);
|
|
be->outbuf = NULL;
|
|
be->dbytes = be->zbytes = be->alloc = 0;
|
|
|
|
// printf("done.\n");
|
|
return 0;
|
|
}
|