/*
$NiH: stream.c,v 1.7 2002/04/22 22:12:31 dillo Exp $
stream.c -- stream interface
Copyright (C) 2002 Dieter Baron and Thomas Klausner
This file is part of cg, a program to assemble and decode binary Usenet
postings. The authors can be contacted at <nih@giga.or.at>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "stream.h"
#include "util.h"
static token _tok_eof = { TOK_EOF, 0, 0, NULL };
token * TOKEN_EOF = &_tok_eof;
token *
stream_get(stream *st)
{
token *t;
if (st->tok_cleanup) {
token_clean(st->tok_cleanup);
st->tok_cleanup = NULL;
}
if (st->queue_cleanup) {
stream_dequeue(st);
st->queue_cleanup = 0;
}
if (st->eof)
return TOKEN_EOF;
if (st->queue_len == 0)
t = st->get(st);
else
t = NULL;
if (st->queue_len > 0) {
if (t)
token_copy(stream_enqueue(st), t);
t = stream_queue_peek(st);
st->queue_cleanup = 1;
}
else
st->tok_cleanup = t;
if (t->type == TOK_EOF)
st->eof = 1;
#if STREAM_TRACE
printf("stream_get(%p) = %d [%s]\n", st, t->type, t->line);
fflush(stdout);
#endif
return t;
}
int
stream_close(stream *st)
{
if (st->tok_cleanup)
token_clean(st->tok_cleanup);
while (st->queue_len > 0)
stream_dequeue(st);
return st->close(st);
}
stream *
stream_new(size_t size, token *(*get)(), int (*close)(), stream *source)
{
stream *st;
st = xmalloc(size);
st->close = close;
st->get = get;
st->source = source;
st->eof = 0;
st->tok_cleanup = NULL;
st->queue.next = NULL;
st->queue_tail = &st->queue;
st->queue_len = 0;
st->queue_cleanup = 0;
return st;
}
void
stream_free(stream *st)
{
if (st == NULL)
return;
free(st);
}
int
stream_eof(stream *st)
{
return st->eof;
}
token *
stream_enqueue(stream *st)
{
token_list *e;
e = xmalloc(sizeof(*e));
e->next = NULL;
st->queue_tail->next = e;
st->queue_tail = e;
st->queue_len++;
return &e->tok;
}
void
stream_dequeue(stream *st)
{
token_list *e;
if (st->queue_len <= 0)
return;
e = st->queue.next;
st->queue.next = e->next;
if (--st->queue_len == 0)
st->queue_tail = &st->queue;
token_clean(&(e->tok));
free(e);
}
token *
stream_queue_peek(stream *st)
{
if (st->queue_len <= 0)
return NULL;
return &st->queue.next->tok;
}
syntax highlighted by Code2HTML, v. 0.9.1