Files
libucore/include/ucore/dbuf.h
T
2014-08-26 21:39:08 +02:00

129 lines
3.2 KiB
C

#ifndef UC_DBUF_H_
#define UC_DBUF_H_
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @file
* dbuf is a generic buffer that will grow automatically.
* call uc_buf_ensure() to reserve space, and don't write more data
* than you told uc_buf_ensure() to reserve.
*
* You write data to buf->end
* When finished writing data
* you call dbuf_added/( with the no. of bytes you've added.
*
* You read data from buf->start, the buffer has uc_dbuf_len() bytes of data
* When you've read and processed the data, call uc_dbuf_take()
* to indicate you're done with the data.
*
* typically(but add error checking)
* @code
* DBuf buf;
* uc_dbuf_init(&buf,4096);
* for(;;) {
* uc_dbuf_ensure(buf,4096);
* size_t len = fread(buf,4096,1,f);
* uc_dbuf_added(&buf,len);
* char *end;
* while((end = memchr(buf.start,'\n',uc_dbuf_len(&dbuf))) != NULL) { //look for a newline
* ++end;
* int linelen = end - buf.start;
* process_line(buf.start,linelen);
* uc_dbuf_take(&dbuf,linelen);
* }
* }
* @endcode
*/
typedef struct DBuf DBuf;
struct DBuf {
/** Start of user data */
unsigned char *start;
/** End of user data */
unsigned char *end;
/** Start of underlying buffer. Internal use.*/
unsigned char *bufstart;
/** End of underlying buffer. Internal use.*/
unsigned char *bufend;
};
/** Free the internals of a DBuf, does not free buf itself.
* Does nothing if buf == NULL
*
* @param buf buffer to free
*/
void uc_dbuf_free(DBuf *buf);
/** Initialize a dbuf.
*
* @param buf buffer to initialize
* @param initlen inital capacity of the buffer
* @return 0 on success
*/
int uc_dbuf_init(DBuf *buf,size_t initlen);
/** Get length of user data in the buffer
*
* @param buf buffer to get length of
* @return length of the user data
*/
size_t uc_dbuf_len(DBuf *buf);
/** Allocated size of the buffer
*
* @param buf buffer to get allocated length of
* @return allocated length of the underlying buffer
*/
size_t uc_dbuf_buflen(DBuf *buf);
/** Get remaining space in the buffer
*
* @param buf buffer
* @return remaining space (after buf->end) in the buffer
*/
size_t uc_dbuf_remaining(DBuf *buf);
/** ensure the buffer can hold 'capacity' no of bytes,
*
* @param buf buffer
* @param capacity ensure there is room for capacity bytes after buf->end
* @return 0 on success
*/
int uc_dbuf_ensure(DBuf *buf,size_t capacity);
/** Trim the buffer to hold no more space than needed.
*
* @param buf buffer to trum
*/
void uc_dbuf_trim(DBuf *buf);
/** Indicate you've taken 'len' bytes out of the buffer.
* Advances buf->start by len bytes
* This may re-set buf->start and buf->end if e.g. all data
* is taken out of the buffer.
*
* @param buf buffer
* @param len length that was taken out of the buffer
* @return 0 on success. Non-zero if len is larger than the bufer capacity
*/
int uc_dbuf_take(DBuf *buf,size_t len);
/** Indicate you've added 'len' bytes to the buffer
* Advances buf->end by len bytes
* User must always make sure (e.g. by using uc_dbuf_ensure)
* that the buffer has the capacity to add @len bytes
*
* @param buf buffer
* @param len length that was added to the buffer.
*/
void uc_dbuf_added(DBuf *buf,size_t len);
#ifdef __cplusplus
}
#endif
#endif