void buffer_compact(buffer *b) { void *data; if (b->capacity > b->size) { data = realloc(b->data, b->size); if (b->size) buffer_assert(data != NULL); b->data = data; b->capacity = b->size; } }
void buffer_reserve(buffer *b, size_t capacity) { void *data; if (capacity > b->capacity) { capacity = buffer_roundup(capacity); data = realloc(b->data, capacity); buffer_assert(data != NULL); b->data = data; b->capacity = capacity; } }
size_t buffer_unshift(struct Buffer *buf, size_t size) { buffer_assert(buf); if (buffer_len(buf) < size) size = buffer_len(buf); buf->dataLen -= size; /* If we have no data we can easily move our pointer down */ if (buf->dataLen == 0) buf->data = 0; else buf->data += size; return size; }
struct Buffer * buffer_reserve(struct Buffer *buf, size_t size) { buffer_assert(buf); /* We must always have at least 1 byte, otherwise realloc will free the pointer */ if (size == 0) size = 1; if (size > buf->bufLen) { /* If the size is bigger than we can handle, just realloc */ buf->buf = realloc(buf->buf, size); if (buf->buf == NULL) return NULL; buf->bufLen = size; } if (size > (buf->bufLen - buf->data)) { /* If the size is larger than our effective size (then move stuff down) */ memmove(buf->buf, &buf->buf[buf->data], buf->dataLen); buf->data = 0; } return buf; }
size_t buffer_available(const struct Buffer *buf) { buffer_assert(buf); return buf->bufLen - buf->data - buf->dataLen; }
size_t buffer_len(const struct Buffer *buf) { buffer_assert(buf); return buf->dataLen; }
char *buffer_end(const struct Buffer *buf) { buffer_assert(buf); return &buf->buf[buf->data + buf->dataLen]; }
char *buffer_start(const struct Buffer *buf) { buffer_assert(buf); return &buf->buf[buf->data]; }
void buffer_cleanup(struct Buffer *buf) { buffer_assert(buf); free(buf->buf); }