/* ========================================================================== * 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 */