void * k5_buf_get_space(struct k5buf *buf, size_t len) { if (!ensure_space(buf, len)) return NULL; buf->len += len; *endptr(buf) = '\0'; return endptr(buf) - len; }
void k5_buf_add_len(struct k5buf *buf, const void *data, size_t len) { if (!ensure_space(buf, len)) return; if (len > 0) memcpy(endptr(buf), data, len); buf->len += len; *endptr(buf) = '\0'; }
void k5_buf_truncate(struct k5buf *buf, size_t len) { if (buf->buftype == K5BUF_ERROR) return; assert(len <= buf->len); buf->len = len; *endptr(buf) = '\0'; }
void k5_buf_init_fixed(struct k5buf *buf, char *data, size_t space) { assert(space > 0); buf->buftype = K5BUF_FIXED; buf->data = data; buf->space = space; buf->len = 0; *endptr(buf) = '\0'; }
void k5_buf_init_dynamic(struct k5buf *buf) { buf->buftype = K5BUF_DYNAMIC; buf->space = 128; buf->data = malloc(buf->space); if (buf->data == NULL) { set_error(buf); return; } buf->len = 0; *endptr(buf) = '\0'; }
iterator end() {return endptr();}
/// \brief Get the an iterator on the end of the list of elements const_iterator end() const {return endptr();}
void k5_buf_add_vfmt(struct k5buf *buf, const char *fmt, va_list ap) { va_list apcopy; int r; size_t remaining; char *tmp; if (buf->buftype == K5BUF_ERROR) return; remaining = buf->space - buf->len; if (buf->buftype == K5BUF_FIXED) { /* Format the data directly into the fixed buffer. */ r = vsnprintf(endptr(buf), remaining, fmt, ap); if (SNPRINTF_OVERFLOW(r, remaining)) set_error(buf); else buf->len += (unsigned int) r; return; } /* Optimistically format the data directly into the dynamic buffer. */ assert(buf->buftype == K5BUF_DYNAMIC || buf->buftype == K5BUF_DYNAMIC_ZAP); va_copy(apcopy, ap); r = vsnprintf(endptr(buf), remaining, fmt, apcopy); va_end(apcopy); if (!SNPRINTF_OVERFLOW(r, remaining)) { buf->len += (unsigned int) r; return; } if (r >= 0) { /* snprintf correctly told us how much space is required. */ if (!ensure_space(buf, r)) return; remaining = buf->space - buf->len; r = vsnprintf(endptr(buf), remaining, fmt, ap); if (SNPRINTF_OVERFLOW(r, remaining)) /* Shouldn't ever happen. */ k5_buf_free(buf); else buf->len += (unsigned int) r; return; } /* It's a pre-C99 snprintf implementation, or something else went wrong. * Fall back to asprintf. */ r = vasprintf(&tmp, fmt, ap); if (r < 0) { k5_buf_free(buf); return; } if (ensure_space(buf, r)) { /* Copy the temporary string into buf, including terminator. */ memcpy(endptr(buf), tmp, r + 1); buf->len += r; } if (buf->buftype == K5BUF_DYNAMIC_ZAP) zap(tmp, strlen(tmp)); free(tmp); }