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;
165 rv = api_posix_malloc(len);
166 if(NULL != rv) { res = (voidpf) rv; }
179 static void cmpr_zlib_free(voidpf opaque, voidpf address)
182 api_posix_free((
void*) address);
204 static api_posix_ssize_t cmpr_send_i(
void* stream,
const void* buf,
205 size_t len,
int flush)
207 struct cmpr_stream* s = (
struct cmpr_stream*) stream;
208 api_posix_ssize_t res = -1;
212 api_posix_ssize_t rv2;
221 PRINT_ERROR(
"cmpr_send(): Invalid pointer to stream object");
224 else if(INT_MAX < len)
228 else if(!len && CMPR_FLUSH_NO == flush)
244 p = (z_streamp) s->tx;
251 memcpy((
void*) s->tx_buf_in, buf, len);
252 p->next_in = (Bytef*) s->tx_buf_in;
253 p->avail_in = (uInt) len;
254 res = (api_posix_ssize_t) len;
261 if(CMPR_FLUSH_NO != flush)
263 if(CMPR_FLUSH_END != flush) { zflush = Z_PARTIAL_FLUSH; }
264 else { zflush = Z_FINISH; }
266 rv = deflate(p, zflush);
276 if(CMPR_FLUSH_END != flush) { res = -1; }
282 "Stream object corrupted");
299 printf(
"%sSend %u compressed bytes\n",
304 while(!res && len2 > i)
309 rv2 = (*s->tx_send)(s->sd,
310 &s->tx_buf_out[i], len2 - i, 0);
312 while( (api_posix_ssize_t) -1 == rv2
313 && API_POSIX_EINTR == api_posix_errno );
314 if((api_posix_ssize_t) -1 == rv2)
317 "to underlaying protocol failed");
323 p->next_out = (Bytef*) s->tx_buf_out;
327 if(CMPR_FLUSH_NO != flush)
343 "Compression algorithm not supported");
365 api_posix_ssize_t
cmpr_send(
void* stream,
const void* buf,
size_t len)
373 return(cmpr_send_i(stream, buf, len, CMPR_FLUSH_NO));
391 api_posix_ssize_t rv;
396 rv = cmpr_send_i(stream, (
void*) &buf, (
size_t) 0, CMPR_FLUSH_YES);
397 if(0 <= rv) { res = 0; }
417 api_posix_ssize_t rv;
422 rv = cmpr_send_i(stream, (
void*) &buf, (
size_t) 0, CMPR_FLUSH_END);
423 if(0 <= rv) { res = 0; }
446 api_posix_ssize_t
cmpr_recv(
void* stream,
void* buf,
size_t len,
int peek)
448 struct cmpr_stream* s = (
struct cmpr_stream*) stream;
449 api_posix_ssize_t res = -1;
453 api_posix_ssize_t rv2;
461 PRINT_ERROR(
"cmpr_recv(): Invalid pointer to stream object");
464 else if(INT_MAX < len)
470 PRINT_ERROR(
"cmpr_recv(): Zero data length not supported");
483 p = (z_streamp) s->rx;
490 rv = inflate(p, Z_SYNC_FLUSH);
502 "stream object corrupted");
527 memcpy(buf, (
void*) s->rx_buf_out, len2);
531 printf(
"%sProviding %u uncompressed bytes\n",
538 memmove((
void*) s->rx_buf_out,
539 (
void*) &s->rx_buf_out[len2], remain);
540 p->next_out = (Bytef*) &s->rx_buf_out[remain];
545 p->next_out = (Bytef*) s->rx_buf_out;
549 res = (api_posix_ssize_t) len2;
552 if(!res && !p->avail_in)
560 rv2 = (*s->rx_recv)(s->sd, s->rx_buf_in, len2, 0);
562 while( (api_posix_ssize_t) -1 == rv2
563 && API_POSIX_EINTR == api_posix_errno );
564 if((api_posix_ssize_t) -1 == rv2)
567 "from underlaying protocol failed");
572 printf(
"%s--- RX ------------------------\n");
573 printf(
"%sReceived %d compressed bytes\n",
575 rx_c += (size_t) rv2;
577 p->next_in = (Bytef*) s->rx_buf_in;
578 p->avail_in = (uInt) rv2;
590 "Compression algorithm not supported");
620 ssize_t (*tx_send)(
int,
const void*,
size_t,
int),
621 ssize_t (*rx_recv)(
int,
void*,
size_t,
int) )
623 struct cmpr_stream* res = NULL;
631 res = (
struct cmpr_stream*) api_posix_malloc(
sizeof(
struct cmpr_stream));
632 if(NULL == res) { error = 1; }
637 res->tx_send = tx_send;
638 res->rx_recv = rx_recv;
639 res->tx_buf_in = NULL;
640 res->tx_buf_out = NULL;
641 res->rx_buf_in = NULL;
642 res->rx_buf_out = NULL;
650 if(0 > sd || NULL == res->tx_send || NULL == res->rx_recv)
652 PRINT_ERROR(
"Invalid parameters to access underlaying protocol");
660 res->tx_buf_in = (
char*) api_posix_malloc(
CMPR_BUFSIZE);
661 res->tx_buf_out = (
char*) api_posix_malloc(
CMPR_BUFSIZE);
662 res->rx_buf_in = (
char*) api_posix_malloc(
CMPR_BUFSIZE);
663 res->rx_buf_out = (
char*) api_posix_malloc(
CMPR_BUFSIZE);
664 if(NULL == res->tx_buf_in || NULL == res->tx_buf_out
665 || NULL == res->rx_buf_in || NULL == res->rx_buf_out)
667 PRINT_ERROR(
"Memory allocation for data buffers failed");
680 res->tx = api_posix_malloc(
sizeof(z_stream));
681 res->rx = api_posix_malloc(
sizeof(z_stream));
682 if(NULL == res->tx || NULL == res->rx)
684 PRINT_ERROR(
"Memory allocation for zlib streams failed");
690 p = (z_streamp) res->tx;
691 p->zalloc = cmpr_zlib_alloc;
692 p->zfree = cmpr_zlib_free;
694 p->next_in = (Bytef*) res->tx_buf_in;
695 p->avail_in = (uInt) 0;
696 rv = deflateInit2(p, Z_BEST_COMPRESSION, Z_DEFLATED,
699 if(Z_OK != rv) { error = 1; }
702 p->next_out = (Bytef*) res->tx_buf_out;
706 p = (z_streamp) res->rx;
707 p->zalloc = cmpr_zlib_alloc;
708 p->zfree = cmpr_zlib_free;
710 p->next_in = (Bytef*) res->rx_buf_in;
711 p->avail_in = (uInt) 0;
720 p->next_out = (Bytef*) res->rx_buf_out;
727 PRINT_ERROR(
"Initialization of zlib streams failed");
735 PRINT_ERROR(
"Compression algorithm not supported");
747 api_posix_free((
void*) res->tx);
748 api_posix_free((
void*) res->rx);
749 api_posix_free((
void*) res->tx_buf_in);
750 api_posix_free((
void*) res->tx_buf_out);
751 api_posix_free((
void*) res->rx_buf_in);
752 api_posix_free((
void*) res->rx_buf_out);
753 api_posix_free((
void*) res);
774 struct cmpr_stream* s = (
struct cmpr_stream*) stream;
790 p = (z_streamp) s->rx;
792 if(Z_OK != rv) { error = 1; }
793 p = (z_streamp) s->tx;
795 if(Z_OK != rv && Z_DATA_ERROR != rv) { error = 1; }
796 if(error) {
PRINT_ERROR(
"Destroying zlib streams failed"); }
803 PRINT_ERROR(
"Compression algorithm not supported");
807 api_posix_free((
void*) s->rx);
808 api_posix_free((
void*) s->tx);
811 api_posix_free((
void*) s->rx_buf_out);
812 api_posix_free((
void*) s->rx_buf_in);
813 api_posix_free((
void*) s->tx_buf_out);
814 api_posix_free((
void*) s->tx_buf_in);
817 api_posix_free(stream);
836 printf(
"%s: %szlib library version: %s\n", CFG_NAME,
MAIN_ERR_PREFIX, ver);
837 if(ZLIB_VERSION[0] != ver[0])
844 rv1 = sscanf(ZLIB_VERSION,
"%*d.%d", &minor_c);
845 rv2 = sscanf(ver,
"%*d.%d", &minor_r);
846 if(1 != rv1 || 1 != rv2)
850 else if(minor_r < minor_c)
852 printf(
"%s: %sWarning: Compiled for a newer zlib minor version "
860 printf(
"%s: %sDEFLATE: Using RX window size: %d bytes\n", CFG_NAME,
877 unsigned long int tx_ul = (
unsigned long int) tx_u;
878 unsigned long int tx_cl = (
unsigned long int) tx_c;
879 unsigned long int rx_cl = (
unsigned long int) rx_c;
880 unsigned long int rx_ul = (
unsigned long int) rx_u;
881 double tx_r = (double) tx_c / (
double) tx_u;
882 double rx_r = (double) rx_c / (
double) rx_u;
885 printf(
"%sUncompressed TX bytes accepted: %lu\n",
MAIN_ERR_PREFIX, tx_ul);
887 printf(
"%sCompressed RX bytes received : %lu\n",
MAIN_ERR_PREFIX, rx_cl);
888 printf(
"%sUncompressed RX bytes provided: %lu\n",
MAIN_ERR_PREFIX, rx_ul);