/* ==========================================================================
 * libevnet/src/bufio-pagebuf.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_PAGEBUF_H
#define EVNET_BUFIO_PAGEBUF_H


#define bufio_page_initialized(p)	((p)->base)

#define bufio_page_len(p)	(size_t)((p)->cursor.put - (p)->cursor.get)
#define bufio_page_nfree(p)	(size_t)((p)->cursor.end - (p)->cursor.put)
#define bufio_page_size(p)	(size_t)((p)->cursor.end - (unsigned char *)(p)->base)


struct bufio_page {
	void *base;

	struct {
		unsigned char *get;
		unsigned char *put;
		unsigned char *end;
	} cursor;


#if defined TAILQ_ENTRY
	TAILQ_ENTRY(bufio_page) tqe;
#else
	struct {
		struct bufio_page *tqe_next;
		struct bufio_page **tqe_prev;
	} tqe;
#endif
}; /* bufio_page */

#if defined TAILQ_HEAD
TAILQ_HEAD(bufio_pages, bufio_page);
#else
struct bufio_pages {
	struct bufio_page *tqh_first;
	struct bufio_page **tqh_last;
};
#endif


static __inline struct bufio_page *bufio_page_init(struct bufio_page *p, void *buf, size_t bufsiz) {
	p->base		= buf;
	p->cursor.get	= buf;
	p->cursor.put	= buf;
	p->cursor.end	= (unsigned char *)(buf) + (bufsiz);

	return p;
} /* bufio_page_init() */


extern const struct bufio_pagebuf_options {
	size_t page_size;
	size_t keep_lowat;
	size_t keep_hiwat;
} bufio_pagebuf_defaults;


struct bufio_pagebuf;

struct bufio_pagebuf_frame {
	struct bufio_pagebuf **bp;

#if defined SLIST_ENTRY && !_WIN32
	SLIST_ENTRY(bufio_pagebuf_frame) sle;
#else
	struct { struct bufio_pagebuf_frame *sle_next; } sle;
#endif
}; /* struct bufio_pagebuf_frame */

struct bufio_pagebuf {
	struct bufio_pagebuf_options opts;

	const struct arena_prototype *ap;

	struct bufio_source *source;
	struct bufio_sink *sink;

	struct bufio_pages pages;

	size_t npages;
	size_t nbytes;

#if defined SLIST_HEAD
	SLIST_HEAD(, bufio_pagebuf_frame) stack;
#else
	struct { struct bufio_pagebuf_frame *slh_first; } stack;
#endif

	BUFIO_IMPLEMENTS(bufio_pagebuf, bufio_source);
	BUFIO_IMPLEMENTS(bufio_pagebuf, bufio_sink);

	struct {
		enum bufio_errno source;
		enum bufio_errno sink;
	} lasterr;

	struct {
		struct bufio_source *source;
		struct bufio_sink *sink;
	} next;
}; /* struct bufio_pagebuf */


struct bufio_pagebuf *bufio_pagebuf_init(struct bufio_pagebuf *, const struct bufio_pagebuf_options *, const struct arena_prototype *);

void bufio_pagebuf_destroy(struct bufio_pagebuf *);

void bufio_pagebuf_clear(struct bufio_pagebuf *);

void bufio_pagebuf_set_sink(struct bufio_pagebuf *, struct bufio_sink *);
void bufio_pagebuf_set_source(struct bufio_pagebuf *, struct bufio_source *);

struct bufio_sink *bufio_pagebuf_to_sink(struct bufio_pagebuf *);
struct bufio_source *bufio_pagebuf_to_source(struct bufio_pagebuf *);

size_t bufio_pagebuf_gets(struct bufio_pagebuf *, void *, size_t, int, enum bufio_errno *);


#endif /* EVNET_BUFIO_PAGEBUF_H */


syntax highlighted by Code2HTML, v. 0.9.1