X-Git-Url: http://git.thejh.net/?p=libjh.git;a=blobdiff_plain;f=bufio.h;fp=bufio.h;h=3ad08614a28d655940875cf7dccba590cd678bf5;hp=0000000000000000000000000000000000000000;hb=6d9303c441fe1d8b473d24f40421d70058e2d2e5;hpb=64999b98e2c98ab92d60ac625fc3ea3a1ec630ec diff --git a/bufio.h b/bufio.h new file mode 100644 index 0000000..3ad0861 --- /dev/null +++ b/bufio.h @@ -0,0 +1,100 @@ +#ifndef _BUFIO_HEADER +#define _BUFIO_HEADER + +#include + +/* BUFFER CHAIN */ +typedef struct bufio_chain_entry bufio_chain_entry; + +struct bufio_chain_entry { + bufio_chain_entry *next; + void *buf; + size_t len; + off_t used; +}; + +typedef struct { + bufio_chain_entry *head, *tail; +} bufio_chain; + +/** + * Enqueues the given buffer for writing. After writing, it will be freed. + * Returns -1 if calloc failed. + */ +int bufio_chain_append(bufio_chain *bc, void *buf, size_t len); + +/** + * Flush as much data as possible into the given FD. + * Returns -1 for errors, 0 for ok. errno is left + * intact on errors, so you might want to check for + * EAGAIN or so. + */ +int bufio_chain_flush(bufio_chain *bc, int fd); + +/** + * Clear the buffer chain without sending any data. + */ +void bufio_chain_clear(bufio_chain *bc); + + + +/* CONNECTION */ +typedef struct bufio_connection bufio_connection; + +typedef void (*bufio_connection_error_cb_t)(bufio_connection *con); +typedef void (*bufio_connection_data_cb_t)(bufio_connection *con); + +struct bufio_connection { + ev_io rw; /* readonly */ + ev_io ww; /* readonly */ + struct ev_loop *loop; /* readonly */ + void *inbuf; /* readonly */ + size_t inbuf_size; /* readonly */ + size_t inbuf_used; /* readonly */ + bufio_chain outbuf; /* readonly */ + + /** + * Called when an error has occured. You should react to it by destroying + * the connection. This property can be changed manually at any time. + */ + bufio_connection_error_cb_t err_cb; + + /** + * Called when your read buffer has been filled completely. When this is + * called, nothing will be read anymore until you set a new read buffer. + * This property can be changed manually at any time. + */ + bufio_connection_data_cb_t data_cb; + + /** + * Not touched by this library. + */ + void *data; +}; + +/** + * Creates a bufio connection around an existing file descriptor. + * This call already activates the watcher without initializing some + * important stuff, so set it before returning to the eventloop/entering + * it: + * + * - the input buffer – set it using `bufio_connection_set_read_buffer` + * - the callbacks (`err_cb` and `data_cb`) – set them directly + */ +bufio_connection *bufio_connection_create(struct ev_loop *loop, int fd); + +void bufio_connection_set_read_buffer(bufio_connection *con, void *buf, size_t size); + +/** + * This stops our watcher and clears and frees the output buffers and the + * connection struct, but it doesn't touch the input buffer or the fd. + */ +void bufio_connection_destroy(bufio_connection *con); + +/** + * This enqueues a chunk of data to be written. You are not allowed to + * touch the buffer anymore after calling this function! + */ +int bufio_connection_write(bufio_connection *con, void *buf, size_t len); + +#endif