X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Frbuf%2Frbuf.h;h=7b5306c4a285318b679f23b36242e726fec28dd7;hp=ab1504a7c910d3d636cf2fd36922294f48fa2c17;hb=d8a270fdfc57ffe7603028ecda99eeab3889ca70;hpb=86d30436820cacfc872de2ba518dd0b54b544647 diff --git a/ccan/rbuf/rbuf.h b/ccan/rbuf/rbuf.h index ab1504a7..7b5306c4 100644 --- a/ccan/rbuf/rbuf.h +++ b/ccan/rbuf/rbuf.h @@ -5,41 +5,36 @@ #include // For UCHAR_MAX #include #include +#include struct rbuf { int fd; - - /* Where to read next. */ - char *start; - /* How much of what is there is valid. */ - size_t len; - - /* The entire buffer memory we have to work with. */ - char *buf, *buf_end; + MEMBUF(char) m; }; /** * rbuf_init - set up a buffer. - * @buf: the struct rbuf. + * @rbuf: the struct rbuf. * @fd: the file descriptor. * @buf: the buffer to use. * @buf_max: the size of the buffer. + * @expandfn: usually membuf_realloc. */ -static inline void rbuf_init(struct rbuf *buf, - int fd, char *buffer, size_t buf_max) +static inline void rbuf_init(struct rbuf *rbuf, + int fd, char *buffer, size_t buf_max, + void *(*expandfn)(struct membuf *, void *, size_t)) { - buf->fd = fd; - buf->start = buf->buf = buffer; - buf->len = 0; - buf->buf_end = buffer + buf_max; + rbuf->fd = fd; + membuf_init(&rbuf->m, buffer, buf_max, expandfn); } /** * rbuf_open - set up a buffer by opening a file. - * @buf: the struct rbuf. + * @rbuf: the struct rbuf. * @filename: the filename * @buf: the buffer to use. * @buf_max: the size of the buffer. + * @expandfn: usually membuf_realloc. * * Returns false if the open fails. If @buf_max is 0, then the buffer * will be resized to rbuf_good_size() on first rbuf_fill. @@ -47,10 +42,11 @@ static inline void rbuf_init(struct rbuf *buf, * Example: * struct rbuf in; * - * if (!rbuf_open(&in, "foo", NULL, 0)) + * if (!rbuf_open(&in, "foo", NULL, 0, membuf_realloc)) * err(1, "Could not open foo"); */ -bool rbuf_open(struct rbuf *rbuf, const char *name, char *buf, size_t buf_max); +bool rbuf_open(struct rbuf *rbuf, const char *name, char *buf, size_t buf_max, + void *(*expandfn)(struct membuf *, void *, size_t)); /** * rbuf_good_size - get a good buffer size for this fd. @@ -62,73 +58,82 @@ size_t rbuf_good_size(int fd); /** * rbuf_fill - read into a buffer if it's empty. - * @buf: the struct rbuf - * @resize: the call to resize the buffer. + * @rbuf: the struct rbuf * - * If @resize is needed and is NULL, or returns false, rbuf_read will - * return NULL (with errno set to ENOMEM). If a read fails, then NULL - * is also returned. If there is nothing more to read, it will return - * NULL with errno set to 0. Otherwise, returns @buf->start; @buf->len - * is the valid length of the buffer. + * If @expandfn fails, rbuf_fill will return NULL (with errno set to ENOMEM). + * If a read fails, then NULL is also returned. If there is nothing more to + * read, it will return NULL with errno set to 0. Otherwise, returns first + * populated bytes (aka. rbuf_start()); rbuf_len() is the valid length of the + * buffer. * * You need to call rbuf_consume() to mark data in the buffer as * consumed. * * Example: - * while (rbuf_fill(&in, realloc)) { - * printf("%.*s\n", (int)in.len, in.start); - * rbuf_consume(&in, in.len); + * while (rbuf_fill(&in)) { + * printf("%.*s\n", (int)rbuf_len(&in), rbuf_start(&in)); + * rbuf_consume(&in, rbuf_len(&in)); * } * if (errno) * err(1, "reading foo"); */ -void *rbuf_fill(struct rbuf *rbuf, void *(*resize)(void *buf, size_t len)); +void *rbuf_fill(struct rbuf *rbuf); /** * rbuf_consume - helper to use up data in a buffer. - * @buf: the struct rbuf + * @rbuf: the struct rbuf * @len: the length (from @buf->start) you used. * * After rbuf_fill() you should indicate the data you've used with * rbuf_consume(). That way rbuf_fill() will know if it has anything * to do. */ -static inline void rbuf_consume(struct rbuf *buf, size_t len) +static inline void rbuf_consume(struct rbuf *rbuf, size_t len) +{ + membuf_consume(&rbuf->m, len); +} + +/** + * rbuf_len - helper to determine how many bytes in rbuf + * @rbuf: the struct rbuf + */ +static inline size_t rbuf_len(const struct rbuf *rbuf) +{ + return membuf_num_elems(&rbuf->m); +} + +/** + * rbuf_start - helper to get pointert to unconsumed bytes in rbuf + * @rbuf: the struct rbuf + */ +static inline char *rbuf_start(const struct rbuf *rbuf) { - buf->len -= len; - buf->start += len; + return membuf_elems(&rbuf->m); } /** * rbuf_fill_all - read rest of file into a buffer. - * @buf: the struct rbuf - * @resize: the call to resize the buffer. + * @rbuf: the struct rbuf * - * If @resize is needed and is NULL, or returns false, rbuf_read_all - * will return NULL (with errno set to ENOMEM). If a read fails, - * then NULL is also returned, otherwise returns @buf->start. + * If a read or @expandfn fails then NULL returned, otherwise returns + * @rbuf->start. * * Example: - * if (!rbuf_fill_all(&in, realloc)) { - * if (errno) - * err(1, "reading foo"); - * } + * if (!rbuf_fill_all(&in)) + * err(1, "reading foo"); */ -void *rbuf_fill_all(struct rbuf *rbuf, void *(*resize)(void *buf, size_t len)); +void *rbuf_fill_all(struct rbuf *rbuf); /** * rbuf_read_str - fill into a buffer up to a terminator, and consume string. - * @buf: the struct rbuf + * @rbuf: the struct rbuf * @term: the character to terminate the read. - * @resize: the call to resize the buffer. * - * If @resize is needed and is NULL, or returns false, rbuf_read_str - * will return NULL (with errno set to ENOMEM). If a read fails, - * then NULL is also returned, otherwise the next string. It - * replaces the terminator @term (if any) with NUL, otherwise NUL + * If a read or @expandfn fails, then NULL is returned, otherwise the next + * string. It replaces the terminator @term (if any) with NUL, otherwise NUL * is placed after EOF. If you need to, you can tell this has happened - * because the nul terminator will be at @buf->start (normally it will - * be at @buf->start - 1). + * because the nul terminator will be at rbuf_start(@rbuf) (normally it will be + * at rbuf_start(@rbuf) - 1). * * If there is nothing remaining to be read, NULL is returned with * errno set to 0, unless @term is NUL, in which case it returns the @@ -140,7 +145,7 @@ void *rbuf_fill_all(struct rbuf *rbuf, void *(*resize)(void *buf, size_t len)); * Example: * char *line; * - * line = rbuf_read_str(&in, '\n', realloc); + * line = rbuf_read_str(&in, '\n'); * if (!line) { * if (errno) * err(1, "reading foo"); @@ -150,7 +155,20 @@ void *rbuf_fill_all(struct rbuf *rbuf, void *(*resize)(void *buf, size_t len)); * printf("First line is %s\n", line); * */ -char *rbuf_read_str(struct rbuf *rbuf, char term, - void *(*resize)(void *buf, size_t len)); +char *rbuf_read_str(struct rbuf *rbuf, char term); +/** + * rbuf_cleanup - reset rbuf, return buffer for freeing. + * @rbuf: the struct rbuf + * + * The rbuf will be empty after this, and crash if you try to use it. + * You can rbuf_init() it again, however. + * + * Example: + * free(rbuf_cleanup(&in)); + */ +static inline char *rbuf_cleanup(struct rbuf *rbuf) +{ + return membuf_cleanup(&rbuf->m); +} #endif /* CCAN_RBUF_H */