/* ** 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_sio.c: OSSP sio to OSSP sio stage */ #include #include #include #include #include "al.h" #include "sio.h" #ifndef SIZE_T_MAX #define SIZE_T_MAX (((((size_t)1 << ((sizeof(size_t) * 8) - 1)) - 1) << 1) + 1) #endif typedef struct { sio_t *upstream; al_label_t my_data_label; al_label_t my_eof_label; al_label_t my_error_label; al_label_t data_label; al_label_t eof_label; al_label_t error_label; char eof; } private_t; /* * create stage * * allocate private instance data */ static sio_rc_t siosio_init(sio_t *sio, void **up) { private_t *my; my = (private_t *)malloc(sizeof(private_t)); if (my == NULL) return SIO_ERR_MEM; my->upstream = NULL; my->my_data_label = NULL; my->my_error_label = NULL; my->my_eof_label = NULL; my->eof = '\0'; sio_label(sio, SIO_LN_DATA, &my->data_label); sio_label(sio, SIO_LN_ERROR, &my->error_label); sio_label(sio, SIO_LN_EOF, &my->eof_label); *up = my; return SIO_OK; } /* * configure stage * * pass two void pointers */ static sio_rc_t siosio_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, "upstream")) { my->upstream = (sio_t *)val; } else if (!strcmp(name, "mydatalabel")) { my->my_data_label = (al_label_t)val; } else if (!strcmp(name, "myerrorlabel")) { my->my_error_label = (al_label_t)val; } else if (!strcmp(name, "myeoflabel")) { my->my_eof_label = (al_label_t)val; } else { return SIO_ERR_ARG; } return SIO_OK; } /* * destroy stage */ static sio_rc_t siosio_cleanup(sio_t *sio, void *u) { private_t *my = (private_t *)u; free(my); return SIO_OK; } static sio_rc_t siosio_openr(sio_t *sio, al_t *al, void *u) { private_t *my = (private_t *)u; if (my->upstream == NULL) return SIO_ERR_ARG; return SIO_OK; } static sio_rc_t siosio_closer(sio_t *sio, al_t *al, void *u) { return SIO_OK; } static sio_rc_t siosio_openw(sio_t *sio, al_t *al, void *u) { private_t *my = (private_t *)u; if (my->upstream == NULL) return SIO_ERR_ARG; return SIO_OK; } static sio_rc_t siosio_closew(sio_t *sio, al_t *al, void *u) { return SIO_OK; } static sio_rc_t siosio_input(sio_t *sio, al_t *al, void *u, sio_rc_t orc) { private_t *my = (private_t *)u; if (al_bytes(al) == 0) { if (my->my_data_label != NULL) { sio_input(my->upstream, al, SIZE_T_MAX, my->my_data_label); if (my->my_data_label != my->data_label) al_setlabel(al, 0, al_bytes(al), my->my_data_label, my->data_label); } if (my->my_error_label != NULL) { sio_input(my->upstream, al, SIZE_T_MAX, my->my_error_label); if (my->my_error_label != my->error_label) al_setlabel(al, 0, al_bytes(al), my->my_error_label, my->error_label); } if (my->my_eof_label != NULL) { sio_input(my->upstream, al, SIZE_T_MAX, my->my_eof_label); if (my->my_eof_label != my->eof_label) al_setlabel(al, 0, al_bytes(al), my->my_eof_label, my->eof_label); } } return SIO_SCHED_DOWN; } static sio_rc_t siosio_output(sio_t *sio, al_t *al, void *u, sio_rc_t orc) { private_t *my = (private_t *)u; if (al_bytes(al) > 0) { if (my->my_data_label != NULL && my->my_data_label != my->data_label) al_setlabel(al, 0, al_bytes(al), my->data_label, my->my_data_label); if (my->my_error_label != NULL && my->my_error_label != my->error_label) al_setlabel(al, 0, al_bytes(al), my->error_label, my->my_error_label); if (my->my_eof_label != NULL && my->my_eof_label != my->eof_label) al_setlabel(al, 0, al_bytes(al), my->eof_label, my->my_eof_label); /* XXX error handling ? */ sio_output(my->upstream, al); } return SIO_SCHED_DOWN; } sio_module_t sio_module_sio = { "sio", siosio_init, siosio_configure, siosio_cleanup, siosio_openr, siosio_closer, siosio_openw, siosio_closew, siosio_input, siosio_output, NULL };