#include "buffer.h"
#include <string.h>
#include <stdlib.h>

void buffer_init(buffer* b) {
	*b = (buffer) {
		.sz = 0,
		.run = 256,
	};
	b -> ptr = malloc(b -> run);
}

buffer buffer_mk() { buffer b; buffer_init(&b); return b; }

void buffer_push(buffer* b, strp const data) {
	size_t run = b->run;
	while (b -> sz + data.sz > run) run *= 2;
	if (run != b->run) {
		b->ptr = realloc(b->ptr, run);
		b->run = run;
	}
	memcpy(&b->ptr[b->sz], data.ptr, data.sz);
	b->sz += data.sz;
}

strp buffer_crush(buffer* b, size_t max) {
	if (b->run>max) {
		b->run = max;
		if (b->sz > max) {
			free(b->ptr);
			b->sz = 0;
			b->ptr = malloc(b->run);
		} else {
			b->ptr = realloc(b->ptr, b->run);
		}
	}
	return (strp){b->sz, b->ptr};
}

strp buffer_str(buffer* b) {
	return (strp){b->sz, b->ptr};
}

size_t buffer_pushs(buffer* b, char const* data) {
	size_t len = strlen(data);
	buffer_push(b, (strp){len, .cptr = data});
	return len;
}

void buffer_clear(buffer* b) {
	b -> sz = 0;
}
void buffer_del(buffer* b) {
	b -> sz = 0;
	b -> run = 0;
	free(b -> ptr);
}
