ossp-pkg/l2/l2_channel.c
1.1.1.1
/*
** L2 - OSSP Logging Library
** Copyright (c) 2001 The OSSP Project (http://www.ossp.org/)
** Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/)
**
** This file is part of OSSP L2, a flexible logging library which
** can be found at http://www.ossp.com/pkg/l2/.
**
** 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.
**
** l2_channel.c: channel handling
**
*/
#include "l2.h"
#include "l2_p.h"
l2_channel_t *l2_channel_create(l2_handler_t *h)
{
l2_channel_t *ch;
if (h == NULL)
return NULL;
if ((ch = (l2_channel_t *)malloc(sizeof(l2_channel_t))) == NULL)
return NULL;
ch->below = NULL;
ch->context.vp = NULL;
ch->handler.create = h->create;
ch->handler.configure = h->configure;
ch->handler.open = h->open;
ch->handler.write = h->write;
ch->handler.flush = h->flush;
ch->handler.close = h->close;
ch->handler.destroy = h->destroy;
if (ch->handler.create(&ch->context) == L2_ERROR) {
free(ch);
return NULL;
}
return ch;
}
l2_channel_t *l2_channel_stack(l2_channel_t *ch1, l2_channel_t *ch2)
{
if (ch1 == NULL || ch2 == NULL)
return NULL;
ch2->below = ch1;
return ch2;
}
int l2_channel_configure(l2_channel_t *ch, const char *fmt, ...)
{
int rv;
va_list ap;
if (ch == NULL || fmt == NULL)
return L2_ERROR;
va_start(ap, fmt);
rv = ch->handler.configure(&ch->context, fmt, ap);
va_end(ap);
return rv;
}
int l2_channel_open(l2_channel_t *ch)
{
if (ch == NULL)
return L2_ERROR;
while (ch != NULL && ch->handler.open == NULL)
ch = ch->below;
if (ch == NULL)
return L2_ERROR;
return ch->handler.open(&ch->context, ch->below);
}
int l2_channel_write(l2_channel_t *ch, const char *buf, size_t bufsize)
{
if (ch == NULL || buf == NULL || bufsize <= 0)
return L2_ERROR;
while (ch != NULL && ch->handler.write == NULL)
ch = ch->below;
if (ch == NULL)
return L2_ERROR;
return ch->handler.write(&ch->context, ch->below, buf, bufsize);
}
int l2_channel_flush(l2_channel_t *ch)
{
if (ch == NULL)
return L2_ERROR;
while (ch != NULL && ch->handler.flush == NULL)
ch = ch->below;
if (ch == NULL)
return L2_ERROR;
return ch->handler.flush(&ch->context, ch->below);
}
int l2_channel_close(l2_channel_t *ch)
{
if (ch == NULL)
return L2_ERROR;
while (ch != NULL && ch->handler.close == NULL)
ch = ch->below;
if (ch == NULL)
return L2_ERROR;
return ch->handler.close(&ch->context, ch->below);
}
int l2_channel_destroy(l2_channel_t *ch)
{
int rv = L2_OK;
if (ch == NULL)
return L2_ERROR;
while (ch != NULL && ch->handler.destroy == NULL)
ch = ch->below;
if (ch != NULL)
rv = ch->handler.destroy(&ch->context);
free(ch);
return rv;
}