#ifndef IO_BUF__H__
#define IO_BUF__H__

#define LF ((char)10)
#define CR ((char)13)
#define CRLF "\015\012"

struct str;

#define IOBUF_EOF 1
#define IOBUF_ERROR 2
#define IOBUF_TIMEOUT 4
#define IOBUF_BADFLAGS 0xf
#define IOBUF_SEEKABLE 0x10	/* The fd can be lseek'ed */
#define IOBUF_NEEDSCLOSE 0x20	/* The fd needs to be closed */
#define IOBUF_NEEDSFREE 0x40	/* The buffer needs to be freed */

extern unsigned iobuf_bufsize;

struct iobuf
{
  int fd;
  char* buffer;
  unsigned bufsize;		/* Total buffer size */
  unsigned buflen;		/* Length of the data in the buffer */
  unsigned bufstart;		/* Start of the data in the buffer */
  unsigned offset;		/* Current file read/write offset */
  unsigned timeout;		/* I/O timeout in ms */
  unsigned flags;		/* Status flags */
  int errnum;			/* Saved errno flag */
};
typedef struct iobuf iobuf;

#define IOBUF_SET_ERROR(io) \
do{ \
  io->flags |= IOBUF_ERROR; \
  io->errnum = errno; \
  return 0; \
}while(0)

int iobuf_init(iobuf* io, int fd, unsigned bufsize, char* buffer,
	       unsigned flags);
int iobuf_close(iobuf* io);
#define iobuf_closed(io) ((io)->fd == -1)
#define iobuf_error(io) ((io)->flags & IOBUF_ERROR)
#define iobuf_timedout(io) ((io)->flags & IOBUF_TIMEOUT)
#define iobuf_bad(io) ((io)->flags & IOBUF_BADFLAGS)
int iobuf_timeout(iobuf* io, int poll_out);

typedef int (*ibuf_fn)(int, void*, unsigned long);

struct ibuf
{
  iobuf io;
  unsigned count;
  ibuf_fn readfn;
};
typedef struct ibuf ibuf;

extern ibuf inbuf;

int ibuf_init(ibuf* in, int fd, ibuf_fn fn, unsigned flags, unsigned bufsize);
int ibuf_open(ibuf* in, const char* filename, unsigned bufsize);
int ibuf_eof(ibuf* in);
#define ibuf_close(in) iobuf_close(&((in)->io))
#define ibuf_closed(in) iobuf_closed(&((in)->io))
#define ibuf_error(in) iobuf_error(&((in)->io))
#define ibuf_timedout(in) iobuf_timedout(&((in)->io))
int ibuf_refill(ibuf* in);
int ibuf_read_large(ibuf* in, char* data, unsigned datalen);
int ibuf_read(ibuf* in, char* data, unsigned datalen);
unsigned ibuf_tell(ibuf* in);
int ibuf_seek(ibuf* in, unsigned offset);
#define ibuf_rewind(in) ibuf_seek(in,0)
#define ibuf_seekfwd(in,off) ibuf_seek(ibuf_tell(in)+(offset))

int ibuf_peek(ibuf* in, char* ch);
int ibuf_getc(ibuf* in, char* ch);
int ibuf_getu(ibuf* in, unsigned long* data);
int ibuf_gets(ibuf* in, char* data, unsigned datalen, char boundary);
int ibuf_getstr(ibuf* in, struct str* s, char boundary);
int ibuf_getstr_crlf(ibuf* in, struct str* s);

typedef int (*obuf_fn)(int, const void*, unsigned long);

struct obuf
{
  iobuf io;
  unsigned bufpos;
  unsigned count;
  obuf_fn writefn;
};
typedef struct obuf obuf;

extern obuf outbuf;
extern obuf errbuf;

#include <fcntl.h>
#define OBUF_CREATE O_CREAT
#define OBUF_EXCLUSIVE O_EXCL
#define OBUF_TRUNCATE O_TRUNC
#define OBUF_APPEND O_APPEND

int obuf_init(obuf* out, int fd, obuf_fn fn, unsigned flags, unsigned bufsize);
int obuf_open(obuf* out, const char* filename, int oflags, int mode, unsigned bufsize);
int obuf_close(obuf* out);
#define obuf_error(out) iobuf_error(&(out)->io)
#define obuf_closed(out) iobuf_closed(&(out)->io)
#define obuf_timedout(out) iobuf_timedout(&((out)->io))
int obuf_flush(obuf* out);
int obuf_sync(obuf* out);
int obuf_write_large(obuf* out, const char* data, unsigned datalen);
int obuf_write(obuf* out, const char* data, unsigned datalen);
int obuf_seek(obuf* out, unsigned offset);
#define obuf_rewind(out) obuf_seek(out,0)
#define obuf_tell(out) ((out)->io.offset+(out)->bufpos)

int obuf_pad(obuf* out, unsigned width, char ch);
int obuf_endl(obuf* out);
int obuf_putc(obuf* out, char ch);
#define obuf_puts(out,str) obuf_write(out,str,strlen(str))
int obuf_put2s(obuf* out, const char* s1, const char* s2);
int obuf_put3s(obuf* out, const char* s1, const char* s2, const char* s3);
int obuf_put4s(obuf* out, const char* s1, const char* s2, const char* s3,
	       const char* s4);
int obuf_put5s(obuf* out, const char* s1, const char* s2, const char* s3,
	       const char* s4, const char* s5);
int obuf_put6s(obuf* out, const char* s1, const char* s2, const char* s3,
	       const char* s4, const char* s5, const char* s6);
int obuf_put7s(obuf* out, const char* s1, const char* s2, const char* s3,
	       const char* s4, const char* s5, const char* s6, const char* s7);
#define obuf_putstr(out,str) obuf_write(out,(str)->s,(str)->len)
int obuf_putsflush(obuf* out, const char* str);
int obuf_putiw(obuf* out, long data, unsigned width, char pad);
#define obuf_puti(out,data) obuf_putiw(out, data, 0, 0)
int obuf_putuw(obuf* out, unsigned long data, unsigned width, char pad);
#define obuf_putu(out,data) obuf_putuw(out, data, 0, 0)
int obuf_putnetstring(obuf* out, const char* data, unsigned datalen);

int iobuf_copy(ibuf* in, obuf* out);
int iobuf_copyflush(ibuf* in, obuf* out);

#endif


syntax highlighted by Code2HTML, v. 0.9.1