/*
 * Common buffered read/write io interface
 * $Id: bufio.h,v 1.2 2001/09/30 19:07:24 pasky Exp $
 */

#include "socket.h"		/* they will re-include us */

#ifndef __BUFIO_H
#define	__BUFIO_H

#include "util.h"


/* Per-socket buffers structure */

typedef struct {
                               /* old handlers, we are inserting ours in sock_t */
                               /* note that handler_e is kept as is there */
  void (*handler_r)(sock_t *, int, void *);
  void (*handler_w)(sock_t *);

  void (*handler_d)(sock_t *); /* !(NULL) == kill shedouled */
  
  int winlen;			/* wanted length */
  int inblen, outblen;		/* actual length */
  void *inbuf, *outbuf;		/* buffers itselves */
} buf_t;


/* Routines which make use of this */

/* Note that this is somewhat different from sock_t handlers. You won't
 * normally touch anything in the structure above directly. You just tell
 * bufio, what to do for you, and it will do it itself. And when enough
 * data are collected to give you 'em, it will.
 */

/* This function sets up buf_t structure. You prob. won't need to use it. */
/* Returns pointer to the allocated structure, or NULL if a problem. */
extern buf_t *bufio_get();

/* This function sets up bufio on specified socket. */
/* Returns 1 if ok, 0 otherwise */
extern int bufio_init(sock_t *);

/* This function lets you shedule reading specified amount of data, and
 * then passing it to specified function. Note that your handler can be
 * called immediatelly, if there is enough data buffered for it.
 * You cannot directly queue more reads, if there was already one sheduled,
 * it is cancelled (just replaced handler, buffer kept untouched). */
/* Returns 1 if ok, 0 otherwise */
extern int bufio_read(sock_t *, int, void (*)(sock_t *, int, void *));

/* This function lets you shedule writing specified amount of data, and
 * then calling your function to report it. You can queue more writes,
 * but only last's handler will be called at completion. You may specify
 * NULL handler here. */
/* Returns 1 if ok, 0 otherwise */
extern int bufio_write(sock_t *, int, void *, void (*)(sock_t *));

/* This function lets you shedule annihilation of the buffers. It will
 * wait until current reading and writing will be finished (won't let
 * you queue more), then it will release the buffer structures and
 * call your function to report it. You may NOT specify NULL handler here,
 * use 'dummy' rather ;-). Note that it obviously won't block. */
/* Returns 1 if ok, 0 otherwise */
extern int bufio_done(sock_t *, void (*)(sock_t *));

/* This function will imediatelly release all buffer structures. */
/* Returns always NULL */
extern buf_t *bufio_del(buf_t *);

#endif
