buffer.c (1520B)
1 #include <string.h> 2 #include <stdlib.h> 3 4 #include "buffer.h" 5 6 #ifndef MAX 7 #define MAX(a,b) ((a)>(b)?(a):(b)) 8 #endif 9 10 #ifndef MIN 11 #define MIN(a,b) ((a)<(b)?(a):(b)) 12 #endif 13 14 void {{buffer_prefix}}_append(struct {{buffer_prefix}} *subject, const char *source, size_t length) { 15 if (!subject) return; 16 17 // Initial alloc if blank buffer 18 if (!subject->alloc) { 19 size_t l = MAX(32, length); 20 subject->alloc = malloc(l); 21 subject->dat = subject->alloc; 22 subject->cap = l; 23 subject->len = 0; 24 goto lbl_{{buffer_prefix}}_append_copy; // Simply skips cap checks 25 } 26 27 // Eject consumed data if we need space 28 if ( 29 (subject->dat != subject->alloc) && 30 ((subject->len + length) > subject->cap) 31 ) { 32 size_t diff = subject->dat - subject->alloc; 33 memmove(subject->alloc, subject->dat, subject->len); 34 subject->cap += diff; 35 subject->dat = subject->alloc; 36 } 37 38 // Grow buffer if still not enough space 39 if ((subject->len + length) > subject->cap) { 40 subject->cap = MAX(32, subject->cap * 2); 41 subject->alloc = realloc(subject->alloc, subject->cap); 42 subject->dat = subject->alloc; 43 } 44 45 // Add the data to the end 46 lbl_{{buffer_prefix}}_append_copy: 47 memcpy(subject->dat + subject->len, source, length); 48 subject->len += length; 49 } 50 51 size_t {{buffer_prefix}}_consume(struct {{buffer_prefix}} *subject, size_t length) { 52 if (!subject) return 0; 53 54 size_t n = MIN(length, subject->len); 55 subject->dat += n; 56 subject->len -= n; 57 subject->cap -= n; 58 59 return n; 60 }