Last active
November 13, 2018 03:05
-
-
Save leowhitehead/8859ae247dd50e62831ef8fcfd6cb16b to your computer and use it in GitHub Desktop.
stretchy buffer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <stddef.h> | |
#include <assert.h> | |
#include <ctype.h> | |
#include <string.h> | |
#include <stdarg.h> | |
#define MAX(x, y) ((x) >= (y) ? (x) : (y)) | |
typedef struct BufHdr { | |
size_t len; | |
size_t cap; | |
char buf[0]; | |
} BufHdr; | |
/* Sean Barrett's stretchy buffer */ | |
/*backend*/ | |
#define buf__hdr(b) ((BufHdr *)((char *)b - offsetof(BufHdr, buf))) | |
#define buf__fits(b, n) (buf_len(b) + (n) <= buf_cap(b)) | |
#define buf__fit(b, n) (buf__fits(b, n) ? 0 : ((b) = buf__grow((b), buf_len(b) + (n), sizeof(*(b))))) | |
/* api */ | |
#define buf_len(b) ((b) ? buf__hdr(b)->len : 0) | |
#define buf_cap(b) ((b) ? buf__hdr(b)->cap : 0) | |
#define buf_push(b, x) (buf__fit((b), 1), (b)[buf__hdr(b)->len++] = (x)) | |
#define buf_free(b) ((b) ? (free(buf__hdr(b)), (b) = NULL) : 0) | |
void *buf__grow(const void *buf, size_t new_len, size_t elem_size) { | |
size_t new_cap = MAX(1 + 2 * buf_cap(buf), new_len); | |
assert(new_len <= new_cap); | |
size_t new_size = offsetof(BufHdr, buf) + new_cap*elem_size; | |
BufHdr *new_hdr; | |
if (buf) { | |
new_hdr = realloc(buf__hdr(buf), new_size); | |
} | |
else { | |
new_hdr = malloc(new_size); | |
new_hdr->len = 0; | |
} | |
new_hdr->cap = new_cap; | |
return new_hdr->buf; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment