71 lines
1.3 KiB
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;
|
|
}
|