mrk/src/buf.c

71 lines
1.3 KiB
C

#include <string.h>
#include "mrk/buf.h"
mrk_err mrk_buf_init(mrk_buf *buf) {
MRK_MALLOC(&buf->s, 2);
// 2 ^ 0
buf->cap = 1;
buf->len = 0;
buf->s[buf->len] = '\0';
return mrk_err_ok;
}
mrk_err mrk_buf_expand(mrk_buf *buf, size_t required) {
size_t new_cap = buf->cap;
while (buf->len + required >= new_cap) {
// Grow buffer size in powers of two
new_cap <<= 1;
}
// No need to reallocate if there's already enough space
if (new_cap == buf->cap) {
return mrk_err_ok;
}
char *new_buf = realloc(buf->s, new_cap + 1);
if (new_buf == NULL) {
return mrk_err_failed_alloc;
}
buf->s = new_buf;
buf->cap = new_cap;
return mrk_err_ok;
}
mrk_err mrk_buf_compact(mrk_buf *buf) {
char *new_buf = realloc(buf->s, buf->len + 1);
if (new_buf == NULL) {
return mrk_err_failed_alloc;
}
buf->s = new_buf;
buf->cap = buf->len;
return mrk_err_ok;
}
mrk_err mrk_buf_append(mrk_buf *buf, const char *s) {
size_t len = strlen(s);
return mrk_buf_append_n(buf, s, len);
}
mrk_err mrk_buf_append_n(mrk_buf *buf, const char *s, size_t len) {
MRK_RES(mrk_buf_expand(buf, len));
memcpy(&buf->s[buf->len], s, len);
buf->len += len;
// Keep the buffer nul-terminated
buf->s[buf->len] = '\0';
return mrk_err_ok;
}