diff -r dddb9348ea42 -r 15f871f50bfd ucx/buffer.h --- a/ucx/buffer.h Mon Aug 12 14:43:22 2013 +0200 +++ b/ucx/buffer.h Tue Aug 13 14:20:12 2013 +0200 @@ -26,6 +26,23 @@ * POSSIBILITY OF SUCH DAMAGE. */ +/** + * @file buffer.h + * + * Advanced buffer implementation. + * + * Instances of UcxBuffer can be used to read from or to write to like one + * would do with a stream. This allows the use of ucx_stream_copy() to copy + * contents from one buffer to another. + * + * Some features for convenient use of the buffer + * can be enabled. See the documentation of the macro constants for more + * information. + * + * @author Mike Becker + * @author Olaf Wintermann + */ + #ifndef UCX_BUFFER_H #define UCX_BUFFER_H @@ -37,94 +54,208 @@ extern "C" { #endif -/* no autoextend or autofree behaviour */ +/** + * No buffer features enabled (all flags cleared). + */ #define UCX_BUFFER_DEFAULT 0x00 -/* the buffer shall free the occupied memory space */ +/** + * If this flag is enabled, the buffer will automatically free its contents. + */ #define UCX_BUFFER_AUTOFREE 0x01 -/* the buffer may automatically double its size on write operations */ +/** + * If this flag is enabled, the buffer will automatically extends its capacity. + */ #define UCX_BUFFER_AUTOEXTEND 0x02 -/* the user shall not modify values, but may get the latest pointer */ +/** UCX Buffer. */ typedef struct { + /** A pointer to the buffer contents. */ char *space; + /** Current position of the buffer. */ size_t pos; + /** Current capacity (i.e. maximum size) of the buffer. */ size_t capacity; + /** Current size of the buffer content. */ size_t size; + /** + * Flag register for buffer features. + * @see #UCX_BUFFER_DEFAULT + * @see #UCX_BUFFER_AUTOFREE + * @see #UCX_BUFFER_AUTOEXTEND + */ int flags; } UcxBuffer; -/* if space is NULL, new space is allocated and the autofree flag is enforced */ +/** + * Creates a new buffer. + * + * Note: you may provide NULL as argument for + * space. Then this function will allocate the space and enforce + * the #UCX_BUFFER_AUTOFREE flag. + * + * @param space pointer to the memory area, or NULL to allocate + * new memory + * @param size the size of the buffer + * @param flags buffer features (see UcxBuffer.flags) + * @return the new buffer + */ UcxBuffer *ucx_buffer_new(void *space, size_t size, int flags); + +/** + * Destroys a buffer. + * + * If the #UCX_BUFFER_AUTOFREE feature is enabled, the contents of the buffer + * are also freed. + * + * @param buffer the buffer to destroy + */ void ucx_buffer_free(UcxBuffer* buffer); -/* - * the autofree flag is enforced for the new buffer - * if length is zero, the whole remaining buffer shall be extracted - * the position of the new buffer is set to zero +/** + * Creates a new buffer and fills it with extracted content from another buffer. + * + * Note: the #UCX_BUFFER_AUTOFREE feature is enforced for the new buffer. + * + * @param src the source buffer + * @param start the start position of extraction + * @param length the count of bytes to extract or 0 if all of the remaining + * bytes shall be extracted + * @param flags feature mask for the new buffer + * @return */ UcxBuffer* ucx_buffer_extract(UcxBuffer *src, size_t start, size_t length, int flags); + +/** + * A shorthand macro for the full extraction of the buffer. + * + * @param src the source buffer + * @param flags feature mask for the new buffer + * @return a new buffer with the extracted content + */ #define ucx_buffer_clone(src,flags) \ ucx_buffer_extract(src, 0, 0, flags) -/* - * Moves the position of the buffer to a new position relative to whence. +/** + * Moves the position of the buffer. + * + * The new position is relative to the whence argument. * - * SEEK_SET marks the start of the buffer - * SEEK_CUR marks the current position - * SEEK_END marks the first 0-byte in the buffer - * - * ucx_buffer_seek returns 0 on success and -1 if the new position is beyond the - * bounds of the allocated buffer. In that case the position of the buffer - * remains unchanged. + * SEEK_SET marks the start of the buffer. + * SEEK_CUR marks the current position. + * SEEK_END marks the first 0-byte in the buffer. + * + * @param buffer + * @param offset position offset relative to whence + * @param whence one of SEEK_SET, SEEK_CUR or SEEK_END + * @return 0 on success, non-zero if the position is invalid * */ int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence); -#define ucx_buffer_clear(buffer) memset(buffer->space, 0, buffer->size); \ - buffer->size = 0; buffer->pos = 0; +/** + * Clears the buffer by resetting the position and deleting the data. + * + * The data is deleted by a zeroing it with call to memset(). + * + * @param buffer the buffer to be cleared + */ +#define ucx_buffer_clear(buffer) memset(buffer->space, 0, buffer->size); \ + buffer->size = 0; buffer->pos = 0; -/* - * returns non-zero, if the current buffer position has exceeded the last - * available byte of the underlying buffer - * +/** + * Tests, if the buffer position has exceeded the buffer capacity. + * + * @param buffer the buffer to test + * @return non-zero, if the current buffer position has exceeded the last + * available byte of the buffer. */ int ucx_buffer_eof(UcxBuffer *buffer); -int ucx_buffere_extend(UcxBuffer *buffer, size_t len); +/** + * Extends the capacity of the buffer. + * + * Note: The buffer capacity increased by a power of two. I.e. + * the buffer capacity is doubled, as long as it would not hold the current + * content plus the additional required bytes. + * + * Attention: the argument provided is the count of additional + * bytes the buffer shall hold. It is NOT the total count of bytes the + * buffer shall hold. + * + * @param buffer the buffer to extend + * @param additional_bytes the count of additional bytes the buffer shall + * at least hold + * @return 0 on success or a non-zero value on failure + */ +int ucx_buffer_extend(UcxBuffer *buffer, size_t additional_bytes); +/** + * Writes data to an UcxBuffer. + * + * The position of the buffer is increased by the number of bytes read. + * + * @param ptr a pointer to the memory area containing the bytes to be written + * @param size the length of one element + * @param nitems the element count + * @param buffer the UcxBuffer to write to + * @return the total count of bytes written + */ size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems, UcxBuffer *buffer); +/** + * Reads data from an UcxBuffer. + * + * The position of the buffer is increased by the number of bytes read. + * + * @param ptr a pointer to the memory area where to store the read data + * @param size the length of one element + * @param nitems the element count + * @param buffer the UcxBuffer to read from + * @return the total count of bytes read + */ size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems, UcxBuffer *buffer); -int ucx_buffer_putc(UcxBuffer *b, int c); -int ucx_buffer_getc(UcxBuffer *b); +/** + * Writes a character to a buffer. + * + * The least significant byte of the argument is written to the buffer. If the + * end of the buffer is reached and #UCX_BUFFER_AUTOEXTEND feature is enabled, + * the buffer capacity is extended by ucx_buffer_extend(). If the feature is + * disabled or buffer extension fails, EOF is returned. + * + * On successful write the position of the buffer is increased. + * + * @param buffer the buffer to write to + * @param c the character to write as int value + * @return the byte that has bean written as int value or + * EOF when the end of the stream is reached and automatic + * extension is not enabled or not possible + */ +int ucx_buffer_putc(UcxBuffer *buffer, int c); +/** + * Gets a character from a buffer. + * + * The current position of the buffer is increased after a successful read. + * + * @param buffer the buffer to read from + * @return the character as int value or EOF, if the + * end of the buffer is reached + */ +int ucx_buffer_getc(UcxBuffer *buffer); -/* - * copies all bytes from s1 to s2 - * uses the read function r to read from s1 und writes the data using the - * write function w to s2 - * returns the number of bytes copied +/** + * Writes a string to a buffer. + * + * @param buffer the buffer + * @param str the string + * @return the number of bytes written */ -size_t ucx_buffer_generic_copy(void *s1, void *s2, read_func r, write_func w, - size_t bufsize); - -size_t ucx_buffer_generic_ncopy(void *s1, void *s2, read_func r, write_func w, - size_t bufsize, size_t n); - -#define UCX_DEFAULT_BUFFER_SIZE 0x1000 - -#define ucx_buffer_copy(s1,s2,r,w) \ - ucx_buffer_generic_copy(s1, s2, (read_func)r, (write_func)w, \ - UCX_DEFAULT_BUFFER_SIZE) - -#define ucx_buffer_ncopy(s1,s2,r,w, n) \ - ucx_buffer_generic_ncopy(s1, s2, (read_func)r, (write_func)w, \ - UCX_DEFAULT_BUFFER_SIZE, n) +size_t ucx_buffer_puts(UcxBuffer *buffer, char *str); #ifdef __cplusplus }