head 1.10; access; symbols SIO_0_9_3:1.10 SIO_0_9_2:1.9 SIO_0_9_1:1.8 SIO_0_9_0:1.8; locks; strict; comment @ * @; 1.10 date 2005.10.03.09.06.11; author rse; state Exp; branches; next 1.9; 1.9 date 2003.06.30.10.36.52; author rse; state Exp; branches; next 1.8; 1.8 date 2003.02.03.17.18.46; author mlelstv; state Exp; branches; next 1.7; 1.7 date 2003.02.03.15.31.59; author mlelstv; state Exp; branches; next 1.6; 1.6 date 2003.01.20.15.34.13; author mlelstv; state Exp; branches; next 1.5; 1.5 date 2003.01.06.19.04.56; author rse; state Exp; branches; next 1.4; 1.4 date 2002.12.18.14.58.29; author mlelstv; state Exp; branches; next 1.3; 1.3 date 2002.11.29.13.00.19; author mlelstv; state Exp; branches; next 1.2; 1.2 date 2002.11.27.13.18.36; author mlelstv; state Exp; branches; next 1.1; 1.1 date 2002.11.27.13.00.44; author mlelstv; state Exp; branches; next ; desc @@ 1.10 log @adjust copyright messages @ text @/* ** OSSP sio - Stream I/O ** Copyright (c) 2002-2005 Cable & Wireless ** Copyright (c) 2002-2005 The OSSP Project ** Copyright (c) 2002-2005 Ralf S. Engelschall ** ** This file is part of OSSP sio, a layered stream I/O library ** which can be found at http://www.ossp.org/pkg/lib/sio/. ** ** Permission to use, copy, modify, and distribute this software for ** any purpose with or without fee is hereby granted, provided that ** the above copyright notice and this permission notice appear in all ** copies. ** ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ** SUCH DAMAGE. ** ** sio_zlib.c: zlib compression stage */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if ENABLE_ZLIB #include #include #include #include "al.h" #include "sio.h" #include typedef struct { z_stream zs; int lvl; al_t *ibuf; char *obuf; size_t olen; al_t *al; void *u; } data_t; typedef struct { data_t input; data_t output; int inputlevel; int outputlevel; size_t inputsize; size_t outputsize; al_label_t data_label; } private_t; /* * create stage * * allocate private instance data */ static sio_rc_t zlib_init(sio_t *sio, void **up) { private_t *my; my = (private_t *)malloc(sizeof(private_t)); if (my == NULL) return SIO_ERR_MEM; my->inputsize = 0; my->outputsize = 0; my->inputlevel = 0; my->outputlevel = 0; sio_label(sio, SIO_LN_DATA, &my->data_label); *up = my; return SIO_OK; } /* * configure stage * * pass two void pointers */ static sio_rc_t zlib_configure(sio_t *sio, void *u, void *obj, void *val) { private_t *my = (private_t *)u; const char *name = (const char *)obj; if (!strcmp(name, "inputlevel")) { my->inputlevel = *(int *)val; } else if (!strcmp(name, "outputlevel")) { my->outputlevel = *(int *)val; } else if (!strcmp(name, "inputsize")) { my->inputsize = *(size_t *)val; } else if (!strcmp(name, "outputsize")) { my->outputsize = *(size_t *)val; } else { return SIO_ERR_ARG; } return SIO_OK; } /* * destroy stage */ static sio_rc_t zlib_cleanup(sio_t *sio, void *u) { private_t *my = (private_t *)u; free(my); return SIO_OK; } static int zlib_alloc_data(private_t *my, data_t *dt) { al_rc_t arc; int zrc; dt->u = (void *)my; dt->zs.zalloc = Z_NULL; dt->zs.zfree = Z_NULL; dt->zs.opaque = NULL; dt->zs.next_in = NULL; dt->zs.next_out = NULL; dt->zs.avail_in = 0; dt->zs.avail_out = 0; if (dt->lvl >= 0) zrc = deflateInit(&dt->zs, dt->lvl); else zrc = inflateInit(&dt->zs); if (zrc != Z_OK) return -1; arc = al_create(&dt->ibuf); if (arc != AL_OK) return -1; dt->obuf = NULL; return 0; } static void zlib_free_data(data_t *dt) { al_destroy(dt->ibuf); dt->ibuf = NULL; if (dt->obuf != NULL) { free(dt->obuf); dt->obuf = NULL; } if (dt->lvl >= 0) deflateEnd(&dt->zs); else inflateEnd(&dt->zs); } static sio_rc_t zlib_openr(sio_t *sio, al_t *al, void *u) { private_t *my = (private_t *)u; if (my->inputsize <= 0) return SIO_ERR_ARG; my->input.lvl = my->inputlevel; my->input.olen = my->inputsize; my->input.al = al; if (zlib_alloc_data(my, &my->input)) return SIO_ERR_INT; return SIO_OK; } static sio_rc_t zlib_closer(sio_t *sio, al_t *al, void *u) { private_t *my = (private_t *)u; zlib_free_data(&my->input); return SIO_OK; } static sio_rc_t zlib_openw(sio_t *sio, al_t *al, void *u) { private_t *my = (private_t *)u; if (my->outputsize <= 0) return SIO_ERR_ARG; my->output.lvl = my->outputlevel; my->output.olen = my->outputsize; my->output.al = al; if (zlib_alloc_data(my, &my->output)) return SIO_ERR_INT; return SIO_OK; } static sio_rc_t zlib_closew(sio_t *sio, al_t *al, void *u) { private_t *my = (private_t *)u; if (my->output.lvl >= 0) deflateEnd(&my->output.zs); else inflateEnd(&my->output.zs); free(my->output.obuf); my->output.obuf = NULL; al_destroy(my->output.ibuf); my->output.ibuf = NULL; return SIO_OK; } static void freezlibbuf(char *p, size_t n, void *u) { free(p); } /* * buffer logic * * gather data from producer * if buffer size reached or label changes then push data to consumer * (read -> downstream, write -> upstream) * * buffer size depends on label type * */ static al_rc_t zlib_inout_cb(al_chunk_t *alcp, void *u) { data_t *dt = (data_t *)u; private_t *my = (private_t *)dt->u; z_stream *zs = &dt->zs; int level = dt->lvl; int zrc, flush; al_rc_t arc; char *p; size_t n; arc = AL_OK; p = al_chunk_ptr(alcp, 0); n = al_chunk_len(alcp); if (al_same_label(alcp, my->data_label)) { zs->next_in = (unsigned char *)p; zs->avail_in = n; flush = 0; } else { zs->next_in = (unsigned char *)""; zs->avail_in = 0; flush = Z_FINISH; } do { if (zs->avail_out == 0) { if (dt->obuf == NULL && (dt->obuf = malloc(dt->olen)) == NULL) { arc = AL_ERR_INT; break; } zs->next_out = (unsigned char *)dt->obuf; zs->avail_out = dt->olen; zs->total_out = 0; } if (level >= 0) zrc = deflate(zs, flush); else zrc = inflate(zs, flush); if (zrc != Z_OK && zrc != Z_STREAM_END) { arc = AL_ERR_INT; break; } if (zs->avail_out == 0 || zrc == Z_STREAM_END || flush) { if (zs->total_out > 0) { arc = al_attach_buffer(dt->al, dt->obuf, zs->total_out, my->data_label, freezlibbuf, NULL); dt->obuf = NULL; zs->avail_out = 0; if (arc != AL_OK) break; } } } while (zs->avail_in > 0 || (zrc == Z_OK && zs->avail_out == 0)); if (arc != AL_OK) return arc; if (flush) arc = al_append_bytes(dt->al, p, n, al_chunk_label(alcp)); return arc; } static sio_rc_t zlib_inout(sio_t *sio, al_t *al, private_t *my, data_t *dt) { al_rc_t arc; arc = al_splice(al, 0, al_bytes(al), NULL, dt->ibuf); if (arc != AL_OK) return SIO_ERR_INT; arc = al_traverse_cb(dt->ibuf, 0, al_bytes(dt->ibuf), AL_FORWARD, NULL, zlib_inout_cb, (void *)dt); if (arc != AL_OK) return SIO_ERR_INT; arc = al_splice(dt->ibuf, 0, al_bytes(dt->ibuf), NULL, NULL); if (arc != AL_OK) return SIO_ERR_INT; return SIO_OK; } static sio_rc_t zlib_input(sio_t *sio, al_t *al, void *u, sio_rc_t orc) { private_t *my = (private_t *)u; return zlib_inout(sio, al, my, &my->input); } static sio_rc_t zlib_output(sio_t *sio, al_t *al, void *u, sio_rc_t orc) { private_t *my = (private_t *)u; return zlib_inout(sio, al, my, &my->output); } sio_module_t sio_module_zlib = { "zlib", zlib_init, zlib_configure, zlib_cleanup, zlib_openr, zlib_closer, zlib_openw, zlib_closew, zlib_input, zlib_output, NULL }; #else const char __sio_zlib_c[] = ""; #endif /* ENABLE_ZLIB */ @ 1.9 log @*) Correctly check the "status" return value of waitpid(3) in the test suite. *) Change in the test suite "%08lx" format string to "%d" because the ts library only has a minimal formatting engine and the argument is "int" and not "long" anyway. *) Make sure that sio_{bio,sa,zlib}.c are not empty compilation units (not allowed in ISO C) even if BIO, SA or ZLIB support is not activated. *) Changed SIZE_T_MAX fallback definition to a more portable variant based on sizeof(size_t) instead of relying on the existance of (non portable) UINT_MAX. *) Added GNU autoconf checks for libnsl/libsocket under Solaris. *) Upgraded to GNU libtool 1.5 @ text @d3 3 a5 3 ** Copyright (c) 2002-2003 Cable & Wireless Deutschland ** Copyright (c) 2002-2003 The OSSP Project ** Copyright (c) 2002-2003 Ralf S. Engelschall @ 1.8 log @paranoia @ text @d381 4 @ 1.7 log @correctly initialize zlib @ text @d142 2 @ 1.6 log @make external references optional @ text @d139 6 @ 1.5 log @- consistently use standard OSSP copyright message everywhere - strip trailing whitespaces @ text @d31 6 d373 1 @ 1.4 log @snapshot PR: Submitted by: Reviewed by: Approved by: Obtained from: @ text @d1 30 d69 1 a69 1 @ 1.3 log @input/output now gets another parameter where scheduler tells them from where they methods called by passing the return value of the previously called stage. PR: Submitted by: Reviewed by: Approved by: Obtained from: @ text @d235 1 a235 1 zs->next_in = p; d239 1 a239 1 zs->next_in = ""; d252 1 a252 1 zs->next_out = dt->obuf; @ 1.2 log @use locally allocated buffers that can be passed to al without extra copying. PR: Submitted by: Reviewed by: Approved by: Obtained from: @ text @d308 1 a308 1 sio_rc_t zlib_input(sio_t *sio, al_t *al, void *u) d316 1 a316 1 sio_rc_t zlib_output(sio_t *sio, al_t *al, void *u) @ 1.1 log @zlib processing PR: Submitted by: Reviewed by: Approved by: Obtained from: @ text @d114 1 a114 6 dt->obuf = malloc(dt->olen); if (dt->obuf == NULL) { al_destroy(dt->ibuf); dt->ibuf = NULL; return -1; } d125 4 a128 2 free(dt->obuf); dt->obuf = NULL; d201 6 d246 6 d265 8 a272 5 arc = al_append_bytes(dt->al, dt->obuf, zs->total_out, my->data_label); zs->avail_out = 0; if (arc != AL_OK) break; @