Home | History | Annotate | Download | only in libupload
      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