universe@39: /* universe@39: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. universe@39: * universe@39: * Copyright 2015 Olaf Wintermann. All rights reserved. universe@39: * universe@39: * Redistribution and use in source and binary forms, with or without universe@39: * modification, are permitted provided that the following conditions are met: universe@39: * universe@39: * 1. Redistributions of source code must retain the above copyright universe@39: * notice, this list of conditions and the following disclaimer. universe@39: * universe@39: * 2. Redistributions in binary form must reproduce the above copyright universe@39: * notice, this list of conditions and the following disclaimer in the universe@39: * documentation and/or other materials provided with the distribution. universe@39: * universe@39: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" universe@39: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE universe@39: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE universe@39: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE universe@39: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR universe@39: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF universe@39: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS universe@39: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN universe@39: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) universe@39: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE universe@39: * POSSIBILITY OF SUCH DAMAGE. universe@39: */ universe@39: universe@39: /** universe@39: * @file buffer.h universe@39: * universe@39: * Advanced buffer implementation. universe@39: * universe@39: * Instances of UcxBuffer can be used to read from or to write to like one universe@39: * would do with a stream. This allows the use of ucx_stream_copy() to copy universe@39: * contents from one buffer to another. universe@39: * universe@39: * Some features for convenient use of the buffer universe@39: * can be enabled. See the documentation of the macro constants for more universe@39: * information. universe@39: * universe@39: * @author Mike Becker universe@39: * @author Olaf Wintermann universe@39: */ universe@39: universe@39: #ifndef UCX_BUFFER_H universe@39: #define UCX_BUFFER_H universe@39: universe@39: #include "ucx.h" universe@39: #include universe@39: #include universe@39: universe@39: #ifdef __cplusplus universe@39: extern "C" { universe@39: #endif universe@39: universe@39: /** universe@39: * No buffer features enabled (all flags cleared). universe@39: */ universe@39: #define UCX_BUFFER_DEFAULT 0x00 universe@39: universe@39: /** universe@39: * If this flag is enabled, the buffer will automatically free its contents. universe@39: */ universe@39: #define UCX_BUFFER_AUTOFREE 0x01 universe@39: universe@39: /** universe@39: * If this flag is enabled, the buffer will automatically extends its capacity. universe@39: */ universe@39: #define UCX_BUFFER_AUTOEXTEND 0x02 universe@39: universe@39: /** UCX Buffer. */ universe@39: typedef struct { universe@39: /** A pointer to the buffer contents. */ universe@39: char *space; universe@39: /** Current position of the buffer. */ universe@39: size_t pos; universe@39: /** Current capacity (i.e. maximum size) of the buffer. */ universe@39: size_t capacity; universe@39: /** Current size of the buffer content. */ universe@39: size_t size; universe@39: /** universe@39: * Flag register for buffer features. universe@39: * @see #UCX_BUFFER_DEFAULT universe@39: * @see #UCX_BUFFER_AUTOFREE universe@39: * @see #UCX_BUFFER_AUTOEXTEND universe@39: */ universe@39: int flags; universe@39: } UcxBuffer; universe@39: universe@39: /** universe@39: * Creates a new buffer. universe@39: * universe@39: * Note: you may provide NULL as argument for universe@39: * space. Then this function will allocate the space and enforce universe@39: * the #UCX_BUFFER_AUTOFREE flag. universe@39: * universe@39: * @param space pointer to the memory area, or NULL to allocate universe@39: * new memory universe@39: * @param capacity the capacity of the buffer universe@39: * @param flags buffer features (see UcxBuffer.flags) universe@39: * @return the new buffer universe@39: */ universe@39: UcxBuffer *ucx_buffer_new(void *space, size_t capacity, int flags); universe@39: universe@39: /** universe@39: * Destroys a buffer. universe@39: * universe@39: * If the #UCX_BUFFER_AUTOFREE feature is enabled, the contents of the buffer universe@39: * are also freed. universe@39: * universe@39: * @param buffer the buffer to destroy universe@39: */ universe@39: void ucx_buffer_free(UcxBuffer* buffer); universe@39: universe@39: /** universe@39: * Creates a new buffer and fills it with extracted content from another buffer. universe@39: * universe@39: * Note: the #UCX_BUFFER_AUTOFREE feature is enforced for the new buffer. universe@39: * universe@39: * @param src the source buffer universe@39: * @param start the start position of extraction universe@39: * @param length the count of bytes to extract (must not be zero) universe@39: * @param flags feature mask for the new buffer universe@39: * @return a new buffer containing the extraction universe@39: */ universe@39: UcxBuffer* ucx_buffer_extract(UcxBuffer *src, universe@39: size_t start, size_t length, int flags); universe@39: universe@39: /** universe@39: * A shorthand macro for the full extraction of the buffer. universe@39: * universe@39: * @param src the source buffer universe@39: * @param flags feature mask for the new buffer universe@39: * @return a new buffer with the extracted content universe@39: */ universe@39: #define ucx_buffer_clone(src,flags) \ universe@39: ucx_buffer_extract(src, 0, (src)->capacity, flags) universe@39: universe@39: /** universe@39: * Moves the position of the buffer. universe@39: * universe@39: * The new position is relative to the whence argument. universe@39: * universe@39: * SEEK_SET marks the start of the buffer. universe@39: * SEEK_CUR marks the current position. universe@39: * SEEK_END marks the end of the buffer. universe@39: * universe@39: * With an offset of zero, this function sets the buffer position to zero universe@39: * (SEEK_SET), the buffer size (SEEK_END) or leaves the buffer position universe@39: * unchanged (SEEK_CUR). universe@39: * universe@39: * @param buffer universe@39: * @param offset position offset relative to whence universe@39: * @param whence one of SEEK_SET, SEEK_CUR or SEEK_END universe@39: * @return 0 on success, non-zero if the position is invalid universe@39: * universe@39: */ universe@39: int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence); universe@39: universe@39: /** universe@39: * Clears the buffer by resetting the position and deleting the data. universe@39: * universe@39: * The data is deleted by a zeroing it with call to memset(). universe@39: * universe@39: * @param buffer the buffer to be cleared universe@39: */ universe@39: #define ucx_buffer_clear(buffer) memset(buffer->space, 0, buffer->size); \ universe@39: buffer->size = 0; buffer->pos = 0; universe@39: universe@39: /** universe@39: * Tests, if the buffer position has exceeded the buffer capacity. universe@39: * universe@39: * @param buffer the buffer to test universe@39: * @return non-zero, if the current buffer position has exceeded the last universe@39: * available byte of the buffer. universe@39: */ universe@39: int ucx_buffer_eof(UcxBuffer *buffer); universe@39: universe@39: universe@39: /** universe@39: * Extends the capacity of the buffer. universe@39: * universe@39: * Note: The buffer capacity increased by a power of two. I.e. universe@39: * the buffer capacity is doubled, as long as it would not hold the current universe@39: * content plus the additional required bytes. universe@39: * universe@39: * Attention: the argument provided is the number of additional universe@39: * bytes the buffer shall hold. It is NOT the total number of bytes the universe@39: * buffer shall hold. universe@39: * universe@39: * @param buffer the buffer to extend universe@39: * @param additional_bytes the number of additional bytes the buffer shall universe@39: * at least hold universe@39: * @return 0 on success or a non-zero value on failure universe@39: */ universe@39: int ucx_buffer_extend(UcxBuffer *buffer, size_t additional_bytes); universe@39: universe@39: /** universe@39: * Writes data to an UcxBuffer. universe@39: * universe@39: * The position of the buffer is increased by the number of bytes written. universe@39: * universe@39: * @param ptr a pointer to the memory area containing the bytes to be written universe@39: * @param size the length of one element universe@39: * @param nitems the element count universe@39: * @param buffer the UcxBuffer to write to universe@39: * @return the total count of bytes written universe@39: */ universe@39: size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems, universe@39: UcxBuffer *buffer); universe@39: universe@39: /** universe@39: * Reads data from an UcxBuffer. universe@39: * universe@39: * The position of the buffer is increased by the number of bytes read. universe@39: * universe@39: * @param ptr a pointer to the memory area where to store the read data universe@39: * @param size the length of one element universe@39: * @param nitems the element count universe@39: * @param buffer the UcxBuffer to read from universe@39: * @return the total number of elements read universe@39: */ universe@39: size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems, universe@39: UcxBuffer *buffer); universe@39: universe@39: /** universe@39: * Writes a character to a buffer. universe@39: * universe@39: * The least significant byte of the argument is written to the buffer. If the universe@39: * end of the buffer is reached and #UCX_BUFFER_AUTOEXTEND feature is enabled, universe@39: * the buffer capacity is extended by ucx_buffer_extend(). If the feature is universe@39: * disabled or buffer extension fails, EOF is returned. universe@39: * universe@39: * On successful write the position of the buffer is increased. universe@39: * universe@39: * @param buffer the buffer to write to universe@39: * @param c the character to write as int value universe@39: * @return the byte that has bean written as int value or universe@39: * EOF when the end of the stream is reached and automatic universe@39: * extension is not enabled or not possible universe@39: */ universe@39: int ucx_buffer_putc(UcxBuffer *buffer, int c); universe@39: universe@39: /** universe@39: * Gets a character from a buffer. universe@39: * universe@39: * The current position of the buffer is increased after a successful read. universe@39: * universe@39: * @param buffer the buffer to read from universe@39: * @return the character as int value or EOF, if the universe@39: * end of the buffer is reached universe@39: */ universe@39: int ucx_buffer_getc(UcxBuffer *buffer); universe@39: universe@39: /** universe@39: * Writes a string to a buffer. universe@39: * universe@39: * @param buffer the buffer universe@39: * @param str the string universe@39: * @return the number of bytes written universe@39: */ universe@39: size_t ucx_buffer_puts(UcxBuffer *buffer, char *str); universe@39: universe@39: #ifdef __cplusplus universe@39: } universe@39: #endif universe@39: universe@39: #endif /* UCX_BUFFER_H */ universe@39: