#include #include #include #include #include "al.h" #include "sio.h" 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 };