/* ==========================================================================
 * libevnet/src/bufio.h - Network server library for libevent.
 * --------------------------------------------------------------------------
 * Copyright (c) 2006  Barracuda Networks, Inc.
 * Copyright (c) 2006  William Ahern
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to permit
 * persons to whom the Software is furnished to do so, subject to the
 * following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
 * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 * ==========================================================================
 */
#ifndef EVNET_BUFIO_H
#define EVNET_BUFIO_H

struct timeval;


#define BUFIO_WOULDBLOCK(e)	((e) == BUFIO_EAGAIN)
#define BUFIO_BROKENPIPE(e)	((e) == BUFIO_EPIPE)

#define BUFIO_EOF(e)		((e) == BUFIO_EEOF)

#define BUFIO_SUCCESS(e)	((e) == 0 || BUFIO_WOULDBLOCK((e)) || BUFIO_EOF((e)))
#define BUFIO_FAILURE(e)	(!BUFIO_SUCCESS((e)))

enum bufio_errno {
	BUFIO_ESUCCESS		= 0,
	BUFIO_ESYSTEM,
	BUFIO_ECANCELLED,
	BUFIO_EEOF,
	BUFIO_ETIMEDOUT,
	BUFIO_ENOTPOLLING,
	BUFIO_EAGAIN,
	BUFIO_EPIPE,

	BUFIO_NERR
}; /* enum bufio_errno */


extern const char *bufio_errlist[BUFIO_NERR];
extern const size_t bufio_nerr;


enum bufio_flags {
	BUFIO_FLUSH	= 1 << 0,
	BUFIO_DRAIN	= BUFIO_FLUSH,
	BUFIO_PEEK	= 1 << 1,
	BUFIO_NOFRAG	= 1 << 2,
}; /* enum bufio_errno */


struct bufio_source;
struct bufio_sink;

typedef void (*bufio_source_poll_cb)(struct bufio_source *, enum bufio_errno, void *);

struct bufio_source {
	size_t (*copyto)(struct bufio_source *, struct bufio_sink *, int, enum bufio_errno *);
	size_t (*copyout)(struct bufio_source *, void *, size_t, int, enum bufio_errno *);

	size_t (*buffered)(struct bufio_source *);

	enum bufio_errno (*poll)(struct bufio_source *, void (*)(struct bufio_source *, enum bufio_errno, void *), void *, struct timeval *);
	enum bufio_errno (*cancel)(struct bufio_source *, int);

	enum bufio_errno (*lasterr)(struct bufio_source *);
	void (*clearerr)(struct bufio_source *);
}; /* struct bufio_source */


typedef void (*bufio_sink_poll_cb)(struct bufio_sink *, enum bufio_errno, void *);

struct bufio_sink {
	size_t (*copyfrom)(struct bufio_sink *, struct bufio_source *, int, enum bufio_errno *);
	size_t (*copyin)(struct bufio_sink *, void *, size_t, int, enum bufio_errno *);

	size_t (*buffered)(struct bufio_sink *);

	enum bufio_errno (*poll)(struct bufio_sink *, void (*)(struct bufio_sink *, enum bufio_errno, void *), void *, struct timeval *);
	enum bufio_errno (*cancel)(struct bufio_sink *, int);

	enum bufio_errno (*lasterr)(struct bufio_sink *);
	void (*clearerr)(struct bufio_sink *);
}; /* struct bufio_sink */


#define BUFIO_SOURCE_INITIALIZER	(bufio_source_initializer)

extern struct bufio_source bufio_source_initializer;

#define BUFIO_SINK_INITIALIZER		(bufio_sink_initializer)

extern struct bufio_sink bufio_sink_initializer;


/*
 * Simple inheritance API. `p' is a pointer to an object of the base type
 * (BUFIO_CAST_TO), or to an object of the interface type whose storage
 * exists within the base object (BUFIO_CAST_FROM). So, in this context `b'
 * is the base type (which must be qualifiable w/ "struct"), and similarly
 * `i' is the interface type.
 *
 * This provides code for structure objects which can "export" a `struct
 * bufio_sink' or `struct bufio_source' interface to cast between the
 * exported object and the local object. This preserves type safety in the
 * public interface, and makes the implementation easier to write (w/o
 * resorting to hand rolling member offset calculations--or other such
 * magic--for each function implementation).
 *
 * BUFIO_IMPLEMENTS must be called alongside the member definitions of a
 * structure definition. Semantically it works similar to the Java
 * "provides" syntax. Expanded it creates a member that look like:
 *
 * 	struct bar {
 * 		...
 *
 * 		struct struct_bar_struct_foo { struct foo super; struct bar *self; } struct_foo;
 * 	};
 *
 * Thus, the interface structure definition must already be in-scope.  The
 * magic is that this depends on the ISO C rule that a pointer to a
 * structure is also a pointer to the first member of that structure. So,
 * technically casting between the exported type and the generated container
 * type should be completely portable, while offset calculations might not
 * necessarily be so.
 */
#define BUFIO_IMPLEMENTS(b, i)		struct struct_##b##_struct_##i { struct i super; struct b *self; } struct_##i
#define BUFIO_CAST_FROM(p, b, i)	(((struct struct_##b##_struct_##i *)(p))->self)
#define BUFIO_CAST_TO(p, b, i) 		((p)->struct_##i.self = (p), &(p)->struct_##i.super)


struct bufio_options {
	size_t max_bufsiz;
	size_t max_recurse;
}; /* struct bufio_options */

extern const struct bufio_options bufio_defaults;


struct bufio;
struct arena_prototype;

struct bufio *bufio_open(const struct bufio_options *, const struct arena_prototype *, enum bufio_errno *);
void bufio_close(struct bufio *);

enum bufio_errno bufio_set_sink(struct bufio *, struct bufio_sink *);
enum bufio_errno bufio_set_source(struct bufio *, struct bufio_source *);

struct bufio_sink *bufio_get_sink(struct bufio *);
struct bufio_source *bufio_get_source(struct bufio *);

struct bufio_sink *bufio_to_sink(struct bufio *);
struct bufio_source *bufio_to_source(struct bufio *);

typedef void (*bufio_rdwr_cb)(struct bufio *, void *, size_t, enum bufio_errno, void *);

typedef bufio_rdwr_cb bufio_read_cb;
typedef bufio_rdwr_cb bufio_gets_cb;

typedef bufio_rdwr_cb bufio_write_cb;
typedef void (*bufio_flush_cb)(struct bufio *, enum bufio_errno, void *);


void bufio_read(struct bufio *, void *, size_t, bufio_read_cb, void *, struct timeval *);
void bufio_gets(struct bufio *, char *, size_t, bufio_gets_cb, void *, struct timeval *);

void bufio_write(struct bufio *, const void *, size_t, bufio_write_cb, void *, struct timeval *);
void bufio_flush(struct bufio *, bufio_flush_cb, void *, struct timeval *);

void bufio_readn(struct bufio *, void *, size_t, bufio_read_cb, void *, struct timeval *);
void bufio_writen(struct bufio *, const void *, size_t, bufio_write_cb, void *, struct timeval *);


#include "bufio/pagebuf.h"

#include "bufio/membuf.h"

#include "bufio/socket.h"

#include "bufio/pipe.h"

#include "bufio/drain.h"


#endif /* EVNET_BUFIO_H */


syntax highlighted by Code2HTML, v. 0.9.1