1.1 --- a/ucx/buffer.h Mon Aug 12 14:43:22 2013 +0200 1.2 +++ b/ucx/buffer.h Tue Aug 13 14:20:12 2013 +0200 1.3 @@ -26,6 +26,23 @@ 1.4 * POSSIBILITY OF SUCH DAMAGE. 1.5 */ 1.6 1.7 +/** 1.8 + * @file buffer.h 1.9 + * 1.10 + * Advanced buffer implementation. 1.11 + * 1.12 + * Instances of UcxBuffer can be used to read from or to write to like one 1.13 + * would do with a stream. This allows the use of ucx_stream_copy() to copy 1.14 + * contents from one buffer to another. 1.15 + * 1.16 + * Some features for convenient use of the buffer 1.17 + * can be enabled. See the documentation of the macro constants for more 1.18 + * information. 1.19 + * 1.20 + * @author Mike Becker 1.21 + * @author Olaf Wintermann 1.22 + */ 1.23 + 1.24 #ifndef UCX_BUFFER_H 1.25 #define UCX_BUFFER_H 1.26 1.27 @@ -37,94 +54,208 @@ 1.28 extern "C" { 1.29 #endif 1.30 1.31 -/* no autoextend or autofree behaviour */ 1.32 +/** 1.33 + * No buffer features enabled (all flags cleared). 1.34 + */ 1.35 #define UCX_BUFFER_DEFAULT 0x00 1.36 -/* the buffer shall free the occupied memory space */ 1.37 +/** 1.38 + * If this flag is enabled, the buffer will automatically free its contents. 1.39 + */ 1.40 #define UCX_BUFFER_AUTOFREE 0x01 1.41 -/* the buffer may automatically double its size on write operations */ 1.42 +/** 1.43 + * If this flag is enabled, the buffer will automatically extends its capacity. 1.44 + */ 1.45 #define UCX_BUFFER_AUTOEXTEND 0x02 1.46 1.47 -/* the user shall not modify values, but may get the latest pointer */ 1.48 +/** UCX Buffer. */ 1.49 typedef struct { 1.50 + /** A pointer to the buffer contents. */ 1.51 char *space; 1.52 + /** Current position of the buffer. */ 1.53 size_t pos; 1.54 + /** Current capacity (i.e. maximum size) of the buffer. */ 1.55 size_t capacity; 1.56 + /** Current size of the buffer content. */ 1.57 size_t size; 1.58 + /** 1.59 + * Flag register for buffer features. 1.60 + * @see #UCX_BUFFER_DEFAULT 1.61 + * @see #UCX_BUFFER_AUTOFREE 1.62 + * @see #UCX_BUFFER_AUTOEXTEND 1.63 + */ 1.64 int flags; 1.65 } UcxBuffer; 1.66 1.67 -/* if space is NULL, new space is allocated and the autofree flag is enforced */ 1.68 +/** 1.69 + * Creates a new buffer. 1.70 + * 1.71 + * <b>Note:</b> you may provide <code>NULL</code> as argument for 1.72 + * <code>space</code>. Then this function will allocate the space and enforce 1.73 + * the #UCX_BUFFER_AUTOFREE flag. 1.74 + * 1.75 + * @param space pointer to the memory area, or <code>NULL</code> to allocate 1.76 + * new memory 1.77 + * @param size the size of the buffer 1.78 + * @param flags buffer features (see UcxBuffer.flags) 1.79 + * @return the new buffer 1.80 + */ 1.81 UcxBuffer *ucx_buffer_new(void *space, size_t size, int flags); 1.82 + 1.83 +/** 1.84 + * Destroys a buffer. 1.85 + * 1.86 + * If the #UCX_BUFFER_AUTOFREE feature is enabled, the contents of the buffer 1.87 + * are also freed. 1.88 + * 1.89 + * @param buffer the buffer to destroy 1.90 + */ 1.91 void ucx_buffer_free(UcxBuffer* buffer); 1.92 1.93 -/* 1.94 - * the autofree flag is enforced for the new buffer 1.95 - * if length is zero, the whole remaining buffer shall be extracted 1.96 - * the position of the new buffer is set to zero 1.97 +/** 1.98 + * Creates a new buffer and fills it with extracted content from another buffer. 1.99 + * 1.100 + * <b>Note:</b> the #UCX_BUFFER_AUTOFREE feature is enforced for the new buffer. 1.101 + * 1.102 + * @param src the source buffer 1.103 + * @param start the start position of extraction 1.104 + * @param length the count of bytes to extract or 0 if all of the remaining 1.105 + * bytes shall be extracted 1.106 + * @param flags feature mask for the new buffer 1.107 + * @return 1.108 */ 1.109 UcxBuffer* ucx_buffer_extract(UcxBuffer *src, 1.110 size_t start, size_t length, int flags); 1.111 + 1.112 +/** 1.113 + * A shorthand macro for the full extraction of the buffer. 1.114 + * 1.115 + * @param src the source buffer 1.116 + * @param flags feature mask for the new buffer 1.117 + * @return a new buffer with the extracted content 1.118 + */ 1.119 #define ucx_buffer_clone(src,flags) \ 1.120 ucx_buffer_extract(src, 0, 0, flags) 1.121 1.122 -/* 1.123 - * Moves the position of the buffer to a new position relative to whence. 1.124 +/** 1.125 + * Moves the position of the buffer. 1.126 + * 1.127 + * The new position is relative to the <code>whence</code> argument. 1.128 * 1.129 - * SEEK_SET marks the start of the buffer 1.130 - * SEEK_CUR marks the current position 1.131 - * SEEK_END marks the first 0-byte in the buffer 1.132 - * 1.133 - * ucx_buffer_seek returns 0 on success and -1 if the new position is beyond the 1.134 - * bounds of the allocated buffer. In that case the position of the buffer 1.135 - * remains unchanged. 1.136 + * SEEK_SET marks the start of the buffer. 1.137 + * SEEK_CUR marks the current position. 1.138 + * SEEK_END marks the first 0-byte in the buffer. 1.139 + * 1.140 + * @param buffer 1.141 + * @param offset position offset relative to <code>whence</code> 1.142 + * @param whence one of SEEK_SET, SEEK_CUR or SEEK_END 1.143 + * @return 0 on success, non-zero if the position is invalid 1.144 * 1.145 */ 1.146 int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence); 1.147 1.148 -#define ucx_buffer_clear(buffer) memset(buffer->space, 0, buffer->size); \ 1.149 - buffer->size = 0; buffer->pos = 0; 1.150 +/** 1.151 + * Clears the buffer by resetting the position and deleting the data. 1.152 + * 1.153 + * The data is deleted by a zeroing it with call to <code>memset()</code>. 1.154 + * 1.155 + * @param buffer the buffer to be cleared 1.156 + */ 1.157 +#define ucx_buffer_clear(buffer) memset(buffer->space, 0, buffer->size); \ 1.158 + buffer->size = 0; buffer->pos = 0; 1.159 1.160 -/* 1.161 - * returns non-zero, if the current buffer position has exceeded the last 1.162 - * available byte of the underlying buffer 1.163 - * 1.164 +/** 1.165 + * Tests, if the buffer position has exceeded the buffer capacity. 1.166 + * 1.167 + * @param buffer the buffer to test 1.168 + * @return non-zero, if the current buffer position has exceeded the last 1.169 + * available byte of the buffer. 1.170 */ 1.171 int ucx_buffer_eof(UcxBuffer *buffer); 1.172 1.173 1.174 -int ucx_buffere_extend(UcxBuffer *buffer, size_t len); 1.175 +/** 1.176 + * Extends the capacity of the buffer. 1.177 + * 1.178 + * <b>Note:</b> The buffer capacity increased by a power of two. I.e. 1.179 + * the buffer capacity is doubled, as long as it would not hold the current 1.180 + * content plus the additional required bytes. 1.181 + * 1.182 + * <b>Attention:</b> the argument provided is the count of <i>additional</i> 1.183 + * bytes the buffer shall hold. It is <b>NOT</b> the total count of bytes the 1.184 + * buffer shall hold. 1.185 + * 1.186 + * @param buffer the buffer to extend 1.187 + * @param additional_bytes the count of additional bytes the buffer shall 1.188 + * <i>at least</i> hold 1.189 + * @return 0 on success or a non-zero value on failure 1.190 + */ 1.191 +int ucx_buffer_extend(UcxBuffer *buffer, size_t additional_bytes); 1.192 1.193 +/** 1.194 + * Writes data to an UcxBuffer. 1.195 + * 1.196 + * The position of the buffer is increased by the number of bytes read. 1.197 + * 1.198 + * @param ptr a pointer to the memory area containing the bytes to be written 1.199 + * @param size the length of one element 1.200 + * @param nitems the element count 1.201 + * @param buffer the UcxBuffer to write to 1.202 + * @return the total count of bytes written 1.203 + */ 1.204 size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems, 1.205 UcxBuffer *buffer); 1.206 1.207 +/** 1.208 + * Reads data from an UcxBuffer. 1.209 + * 1.210 + * The position of the buffer is increased by the number of bytes read. 1.211 + * 1.212 + * @param ptr a pointer to the memory area where to store the read data 1.213 + * @param size the length of one element 1.214 + * @param nitems the element count 1.215 + * @param buffer the UcxBuffer to read from 1.216 + * @return the total count of bytes read 1.217 + */ 1.218 size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems, 1.219 UcxBuffer *buffer); 1.220 1.221 -int ucx_buffer_putc(UcxBuffer *b, int c); 1.222 -int ucx_buffer_getc(UcxBuffer *b); 1.223 +/** 1.224 + * Writes a character to a buffer. 1.225 + * 1.226 + * The least significant byte of the argument is written to the buffer. If the 1.227 + * end of the buffer is reached and #UCX_BUFFER_AUTOEXTEND feature is enabled, 1.228 + * the buffer capacity is extended by ucx_buffer_extend(). If the feature is 1.229 + * disabled or buffer extension fails, <code>EOF</code> is returned. 1.230 + * 1.231 + * On successful write the position of the buffer is increased. 1.232 + * 1.233 + * @param buffer the buffer to write to 1.234 + * @param c the character to write as <code>int</code> value 1.235 + * @return the byte that has bean written as <code>int</code> value or 1.236 + * <code>EOF</code> when the end of the stream is reached and automatic 1.237 + * extension is not enabled or not possible 1.238 + */ 1.239 +int ucx_buffer_putc(UcxBuffer *buffer, int c); 1.240 1.241 +/** 1.242 + * Gets a character from a buffer. 1.243 + * 1.244 + * The current position of the buffer is increased after a successful read. 1.245 + * 1.246 + * @param buffer the buffer to read from 1.247 + * @return the character as <code>int</code> value or <code>EOF</code>, if the 1.248 + * end of the buffer is reached 1.249 + */ 1.250 +int ucx_buffer_getc(UcxBuffer *buffer); 1.251 1.252 -/* 1.253 - * copies all bytes from s1 to s2 1.254 - * uses the read function r to read from s1 und writes the data using the 1.255 - * write function w to s2 1.256 - * returns the number of bytes copied 1.257 +/** 1.258 + * Writes a string to a buffer. 1.259 + * 1.260 + * @param buffer the buffer 1.261 + * @param str the string 1.262 + * @return the number of bytes written 1.263 */ 1.264 -size_t ucx_buffer_generic_copy(void *s1, void *s2, read_func r, write_func w, 1.265 - size_t bufsize); 1.266 - 1.267 -size_t ucx_buffer_generic_ncopy(void *s1, void *s2, read_func r, write_func w, 1.268 - size_t bufsize, size_t n); 1.269 - 1.270 -#define UCX_DEFAULT_BUFFER_SIZE 0x1000 1.271 - 1.272 -#define ucx_buffer_copy(s1,s2,r,w) \ 1.273 - ucx_buffer_generic_copy(s1, s2, (read_func)r, (write_func)w, \ 1.274 - UCX_DEFAULT_BUFFER_SIZE) 1.275 - 1.276 -#define ucx_buffer_ncopy(s1,s2,r,w, n) \ 1.277 - ucx_buffer_generic_ncopy(s1, s2, (read_func)r, (write_func)w, \ 1.278 - UCX_DEFAULT_BUFFER_SIZE, n) 1.279 +size_t ucx_buffer_puts(UcxBuffer *buffer, char *str); 1.280 1.281 #ifdef __cplusplus 1.282 }