From a72bbb26973d73ce98c1dde62f3a114e2bb6589c Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Fri, 11 Jan 2008 23:01:32 +0100 Subject: [PATCH] More buffer functions. --- lib-lib/buffer.c | 74 +++++++++++++++++++++++------------------------- lib-lib/buffer.h | 11 ++++++- lib-lib/mem.h | 14 +++++++++ 3 files changed, 60 insertions(+), 39 deletions(-) diff --git a/lib-lib/buffer.c b/lib-lib/buffer.c index 25f930d..f27dc51 100644 --- a/lib-lib/buffer.c +++ b/lib-lib/buffer.c @@ -28,20 +28,48 @@ #include "lib-lib.h" -#define BUFSIZ_INCREMENT 1024 - -void buffer_resize(buffer_t *buf, ssize_t newsize) +void buffer_splice(buffer_t *buf, ssize_t pos, ssize_t len, + const void *data, ssize_t dlen) { - if (newsize >= buf->size) { - /* rounds newsize to the 1024 multiple just after newsize+1 */ - newsize = (newsize + BUFSIZ_INCREMENT) & ~(BUFSIZ_INCREMENT - 1); - p_realloc(&buf->data, newsize); - } + if (dlen >= len) + buffer_extend(buf, dlen - len); + memmove(buf->data + pos + dlen, + buf->data + pos + len, + buf->len - pos - len); + memcpy(buf->data + pos, data, dlen); + buffer_setlen(buf, buf->len + dlen - len); } +ssize_t buffer_addvf(buffer_t *buf, const char *fmt, va_list args) +{ + ssize_t len; + va_list ap; + va_copy(ap, args); + buffer_ensure(buf, BUFSIZ); + + len = vsnprintf(buf->data + buf->len, buf->size - buf->len, fmt, args); + if (len < 0) + return len; + if (len >= buf->size - buf->len) { + buffer_ensure(buf, len); + vsnprintf(buf->data + buf->len, buf->size - buf->len, fmt, ap); + } + buf->len += len; + buf->data[buf->len] = '\0'; + return len; +} +ssize_t buffer_addf(buffer_t *buf, const char *fmt, ...) +{ + ssize_t res; + va_list args; + va_start(args, fmt); + res = buffer_addvf(buf, fmt, args); + va_end(args); + return res; +} /****** LEGACY BUFFERS *******/ /* @@ -107,33 +135,3 @@ void mutt_buffer_add(BUFFER *buf, const char *s, ssize_t len) *buf->dptr = '\0'; } -ssize_t buffer_addvf(buffer_t *buf, const char *fmt, va_list args) -{ - ssize_t len; - va_list ap; - - va_copy(ap, args); - buffer_ensure(buf, BUFSIZ); - - len = vsnprintf(buf->data + buf->len, buf->size - buf->len, fmt, args); - if (len < 0) - return len; - if (len >= buf->size - buf->len) { - buffer_ensure(buf, len); - vsnprintf(buf->data + buf->len, buf->size - buf->len, fmt, ap); - } - buf->len += len; - buf->data[buf->len] = '\0'; - - return len; -} - -ssize_t buffer_addf(buffer_t *buf, const char *fmt, ...) -{ - ssize_t res; - va_list args; - va_start(args, fmt); - res = buffer_addvf(buf, fmt, args); - va_end(args); - return res; -} diff --git a/lib-lib/buffer.h b/lib-lib/buffer.h index 6d62f2a..41f9ccf 100644 --- a/lib-lib/buffer.h +++ b/lib-lib/buffer.h @@ -50,13 +50,20 @@ static inline char *buffer_unwrap(buffer_t **buf) { } -void buffer_resize(buffer_t *, ssize_t newsize); +static inline void buffer_resize(buffer_t *buf, ssize_t newsize) { + p_allocgrow(&buf->data, newsize + 1, &buf->size); +} static inline void buffer_ensure(buffer_t *buf, ssize_t extra) { assert (extra >= 0); if (buf->len + extra >= buf->size) { buffer_resize(buf, buf->len + extra); } } +static inline void buffer_setlen(buffer_t *buf, ssize_t len) { + assert (buf->size > len); + buf->len = len; + buf->data[len] = '\0'; +} static inline void buffer_extend(buffer_t *buf, ssize_t extra) { buffer_ensure(buf, extra); buf->len += extra; @@ -93,6 +100,8 @@ static inline void buffer_reset(buffer_t *buf) { } } +void buffer_splice(buffer_t *, ssize_t pos, ssize_t len, const void *, ssize_t); + ssize_t buffer_addvf(buffer_t *buf, const char *fmt, va_list) __attribute__((format(printf, 2, 0))); diff --git a/lib-lib/mem.h b/lib-lib/mem.h index ca9712b..8d904b3 100644 --- a/lib-lib/mem.h +++ b/lib-lib/mem.h @@ -29,6 +29,20 @@ #define p_dupstr(p, len) xmemdupstr((p), (len)) #define p_realloc(pp, count) xrealloc((void*)(pp), sizeof(**(pp)) * (count)) +#define p_alloc_nr(x) (((x) + 16) * 3 / 2) + +#define p_allocgrow(pp, goalnb, allocnb) \ + do { \ + if ((goalnb) > *(allocnb)) { \ + if (p_alloc_nr(*(allocnb)) < (goalnb)) { \ + *(allocnb) = (goalnb); \ + } else { \ + *(allocnb) = p_alloc_nr(*(allocnb)); \ + } \ + p_realloc(pp, *(allocnb)); \ + } \ + } while (0) + #ifdef __GNUC__ # define p_delete(mem_pp) \ -- 2.20.1