24 # include "compression.h"
51 #define MAIN_ERR_PREFIX "COMPR: "
61 ssize_t (*tx_send)(int,
const void*, size_t, int);
62 ssize_t (*rx_recv)(int,
void*, size_t, int);
83 # define CMPR_FLUSH_NO 0
84 # define CMPR_FLUSH_YES 1
85 # define CMPR_FLUSH_END 2
94 # define CMPR_BUFSIZE (size_t) 32768
114 # define CMPR_ZLIB_WINDOW_BITS -15
124 # define CMPR_ZLIB_MEM_LEVEL 9
134 static size_t tx_u = 0;
135 static size_t tx_c = 0;
136 static size_t rx_u = 0;
137 static size_t rx_c = 0;
158 static voidpf cmpr_zlib_alloc(voidpf opaque, uInt items, uInt size)
162 size_t len = (size_t) items * (
size_t) size;
164 rv = posix_malloc(len);
165 if(NULL != rv) { res = (voidpf) rv; }
178 static void cmpr_zlib_free(voidpf opaque, voidpf address)
180 posix_free((
void*) address);
202 static posix_ssize_t cmpr_send_i(
void* stream,
const void* buf,
size_t len,
205 struct cmpr_stream* s = (
struct cmpr_stream*) stream;
206 posix_ssize_t res = -1;
219 PRINT_ERROR(
"cmpr_send(): Invalid pointer to stream object");
222 else if(INT_MAX < len)
226 else if(!len && CMPR_FLUSH_NO == flush)
242 p = (z_streamp) s->tx;
249 memcpy((
void*) s->tx_buf_in, buf, len);
250 p->next_in = (Bytef*) s->tx_buf_in;
251 p->avail_in = (uInt) len;
252 res = (posix_ssize_t) len;
259 if(CMPR_FLUSH_NO != flush)
261 if(CMPR_FLUSH_END != flush) { zflush = Z_PARTIAL_FLUSH; }
262 else { zflush = Z_FINISH; }
264 rv = deflate(p, zflush);
274 if(CMPR_FLUSH_END != flush) { res = -1; }
280 "Stream object corrupted");
296 printf(
"%sSend %u compressed bytes\n",
301 while(!res && len2 > i)
306 rv2 = (*s->tx_send)(s->sd,
307 &s->tx_buf_out[i], len2 - i, 0);
309 while( (posix_ssize_t) -1 == rv2
310 && POSIX_EINTR == posix_errno );
311 if((posix_ssize_t) -1 == rv2)
314 "to underlaying protocol failed");
320 p->next_out = (Bytef*) s->tx_buf_out;
324 if(CMPR_FLUSH_NO != flush)
340 "Compression algorithm not supported");
362 posix_ssize_t
cmpr_send(
void* stream,
const void* buf,
size_t len)
370 return(cmpr_send_i(stream, buf, len, CMPR_FLUSH_NO));
393 rv = cmpr_send_i(stream, (
void*) &buf, (
size_t) 0, CMPR_FLUSH_YES);
394 if(0 <= rv) { res = 0; }
419 rv = cmpr_send_i(stream, (
void*) &buf, (
size_t) 0, CMPR_FLUSH_END);
420 if(0 <= rv) { res = 0; }
443 posix_ssize_t
cmpr_recv(
void* stream,
void* buf,
size_t len,
int peek)
445 struct cmpr_stream* s = (
struct cmpr_stream*) stream;
446 posix_ssize_t res = -1;
458 PRINT_ERROR(
"cmpr_recv(): Invalid pointer to stream object");
461 else if(INT_MAX < len)
467 PRINT_ERROR(
"cmpr_recv(): Zero data length not supported");
480 p = (z_streamp) s->rx;
487 rv = inflate(p, Z_SYNC_FLUSH);
499 "stream object corrupted");
523 memcpy(buf, (
void*) s->rx_buf_out, len2);
527 printf(
"%sProviding %u uncompressed bytes\n",
534 memmove((
void*) s->rx_buf_out,
535 (
void*) &s->rx_buf_out[len2], remain);
536 p->next_out = (Bytef*) &s->rx_buf_out[remain];
541 p->next_out = (Bytef*) s->rx_buf_out;
545 res = (posix_ssize_t) len2;
548 if(!res && !p->avail_in)
556 rv2 = (*s->rx_recv)(s->sd, s->rx_buf_in, len2, 0);
558 while( (posix_ssize_t) -1 == rv2
559 && POSIX_EINTR == posix_errno );
560 if((posix_ssize_t) -1 == rv2)
563 "from underlaying protocol failed");
568 printf(
"%s--- RX ------------------------\n");
569 printf(
"%sReceived %d compressed bytes\n",
571 rx_c += (size_t) rv2;
573 p->next_in = (Bytef*) s->rx_buf_in;
574 p->avail_in = (uInt) rv2;
586 "Compression algorithm not supported");
616 ssize_t (*tx_send)(
int,
const void*,
size_t,
int),
617 ssize_t (*rx_recv)(
int,
void*,
size_t,
int) )
619 struct cmpr_stream* res = NULL;
627 res = (
struct cmpr_stream*) posix_malloc(
sizeof(
struct cmpr_stream));
628 if(NULL == res) { error = 1; }
633 res->tx_send = tx_send;
634 res->rx_recv = rx_recv;
635 res->tx_buf_in = NULL;
636 res->tx_buf_out = NULL;
637 res->rx_buf_in = NULL;
638 res->rx_buf_out = NULL;
646 if(0 > sd || NULL == res->tx_send || NULL == res->rx_recv)
648 PRINT_ERROR(
"Invalid parameters to access underlaying protocol");
660 if(NULL == res->tx_buf_in || NULL == res->tx_buf_out
661 || NULL == res->rx_buf_in || NULL == res->rx_buf_out)
663 PRINT_ERROR(
"Memory allocation for data buffers failed");
676 res->tx = posix_malloc(
sizeof(z_stream));
677 res->rx = posix_malloc(
sizeof(z_stream));
678 if(NULL == res->tx || NULL == res->rx)
680 PRINT_ERROR(
"Memory allocation for zlib streams failed");
686 p = (z_streamp) res->tx;
687 p->zalloc = cmpr_zlib_alloc;
688 p->zfree = cmpr_zlib_free;
690 p->next_in = (Bytef*) res->tx_buf_in;
691 p->avail_in = (uInt) 0;
692 rv = deflateInit2(p, Z_BEST_COMPRESSION, Z_DEFLATED,
695 if(Z_OK != rv) { error = 1; }
698 p->next_out = (Bytef*) res->tx_buf_out;
702 p = (z_streamp) res->rx;
703 p->zalloc = cmpr_zlib_alloc;
704 p->zfree = cmpr_zlib_free;
706 p->next_in = (Bytef*) res->rx_buf_in;
707 p->avail_in = (uInt) 0;
716 p->next_out = (Bytef*) res->rx_buf_out;
723 PRINT_ERROR(
"Initialization of zlib streams failed");
731 PRINT_ERROR(
"Compression algorithm not supported");
743 posix_free((
void*) res->tx);
744 posix_free((
void*) res->rx);
745 posix_free((
void*) res->tx_buf_in);
746 posix_free((
void*) res->tx_buf_out);
747 posix_free((
void*) res->rx_buf_in);
748 posix_free((
void*) res->rx_buf_out);
749 posix_free((
void*) res);
770 struct cmpr_stream* s = (
struct cmpr_stream*) stream;
786 p = (z_streamp) s->rx;
788 if(Z_OK != rv) { error = 1; }
789 p = (z_streamp) s->tx;
791 if(Z_OK != rv && Z_DATA_ERROR != rv) { error = 1; }
792 if(error) {
PRINT_ERROR(
"Destroying zlib streams failed"); }
799 PRINT_ERROR(
"Compression algorithm not supported");
803 posix_free((
void*) s->rx);
804 posix_free((
void*) s->tx);
807 posix_free((
void*) s->rx_buf_out);
808 posix_free((
void*) s->rx_buf_in);
809 posix_free((
void*) s->tx_buf_out);
810 posix_free((
void*) s->tx_buf_in);
832 printf(
"%s: %szlib library version: %s\n", CFG_NAME,
MAIN_ERR_PREFIX, ver);
833 if(ZLIB_VERSION[0] != ver[0])
840 rv1 = sscanf(ZLIB_VERSION,
"%*d.%d", &minor_c);
841 rv2 = sscanf(ver,
"%*d.%d", &minor_r);
842 if(1 != rv1 || 1 != rv2)
846 else if(minor_r < minor_c)
848 printf(
"%s: %sWarning: Compiled for a newer zlib minor version "
856 printf(
"%s: %sDEFLATE: Using RX window size: %d bytes\n", CFG_NAME,
873 unsigned long int tx_ul = (
unsigned long int) tx_u;
874 unsigned long int tx_cl = (
unsigned long int) tx_c;
875 unsigned long int rx_cl = (
unsigned long int) rx_c;
876 unsigned long int rx_ul = (
unsigned long int) rx_u;
877 double tx_r = (double) tx_c / (
double) tx_u;
878 double rx_r = (double) rx_c / (
double) rx_u;
881 printf(
"%sUncompressed TX bytes accepted: %lu\n",
MAIN_ERR_PREFIX, tx_ul);
883 printf(
"%sCompressed RX bytes received : %lu\n",
MAIN_ERR_PREFIX, rx_cl);
884 printf(
"%sUncompressed RX bytes provided: %lu\n",
MAIN_ERR_PREFIX, rx_ul);