ossp-pkg/sio/sio_sio.c
/*
** OSSP sio - Stream I/O
** Copyright (c) 2002-2005 Cable & Wireless <http://www.cw.com/>
** Copyright (c) 2002-2005 The OSSP Project <http://www.ossp.org/>
** Copyright (c) 2002-2005 Ralf S. Engelschall <rse@engelschall.com>
**
** 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 <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#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
};