1 /* 2 * Compress input and feed it to a block-oriented back end. 3 */ 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <inttypes.h> 9 #include <stdbool.h> 10 #include <zlib.h> 11 #include "upload_backend.h" 12 #include "ctime.h" 13 14 #define ALLOC_CHUNK 65536 15 16 int init_data(struct upload_backend *be, const char *argv[]) 17 { 18 be->now = posix_time(); 19 be->argv = argv; 20 21 memset(&be->zstream, 0, sizeof be->zstream); 22 23 be->zstream.next_out = NULL; 24 be->outbuf = NULL; 25 be->zstream.avail_out = be->alloc = 0; 26 be->dbytes = be->zbytes = 0; 27 28 /* Initialize a gzip data stream */ 29 if (deflateInit2(&be->zstream, 9, Z_DEFLATED, 30 16+15, 9, Z_DEFAULT_STRATEGY) < 0) 31 return -1; 32 33 return 0; 34 } 35 36 static int do_deflate(struct upload_backend *be, int flush) 37 { 38 int rv; 39 char *buf; 40 41 while (1) { 42 rv = deflate(&be->zstream, flush); 43 be->zbytes = be->alloc - be->zstream.avail_out; 44 if (be->zstream.avail_out) 45 return rv; /* Not an issue of output space... */ 46 47 buf = realloc(be->outbuf, be->alloc + ALLOC_CHUNK); 48 if (!buf) 49 return Z_MEM_ERROR; 50 be->outbuf = buf; 51 be->alloc += ALLOC_CHUNK; 52 be->zstream.next_out = (void *)(buf + be->zbytes); 53 be->zstream.avail_out = be->alloc - be->zbytes; 54 } 55 } 56 57 58 int write_data(struct upload_backend *be, const void *buf, size_t len) 59 { 60 int rv = Z_OK; 61 62 be->zstream.next_in = (void *)buf; 63 be->zstream.avail_in = len; 64 65 be->dbytes += len; 66 67 while (be->zstream.avail_in) { 68 rv = do_deflate(be, Z_NO_FLUSH); 69 if (rv < 0) { 70 printf("do_deflate returned %d\n", rv); 71 return -1; 72 } 73 } 74 return 0; 75 } 76 77 /* Output the data and shut down the stream */ 78 int flush_data(struct upload_backend *be) 79 { 80 int rv = Z_OK; 81 int err=-1; 82 83 while (rv != Z_STREAM_END) { 84 rv = do_deflate(be, Z_FINISH); 85 if (rv < 0) 86 return -1; 87 } 88 89 // printf("Uploading data, %u bytes... ", be->zbytes); 90 91 if ((err=be->write(be)) != 0) 92 return err; 93 94 free(be->outbuf); 95 be->outbuf = NULL; 96 be->dbytes = be->zbytes = be->alloc = 0; 97 98 // printf("done.\n"); 99 return 0; 100 } 101