#include "buffer.h"
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#define DMID 14
#include "debug.h"

#include "vsnprintf.h"

#ifndef FALSE
#define FALSE 0
#endif

#ifndef TRUE
#define TRUE 1
#endif

struct BUFFER {
	char *data;
	size_t size;
	size_t bytes;
};

Buffer *buffer_new(size_t sz) {
	Buffer *b = calloc(1,sizeof(Buffer));
	b->data = calloc(1,sz+1);
	b->size = sz;
	return b;
}

void buffer_free(Buffer **b) {
	if (!b || !*b) return ;
	free((*b)->data);
	free(*b); *b = NULL;
}

int buffer_printf(Buffer *b, char *format, ...)
{
	char bf[2000];
	va_list args;
	int x;
	
	va_start(args,format);
	x = vsnprintf(bf,2000,format,args);
	if (x == 2000 || x == -1) bf[(x = 2000-1)] = 0;
	return (int) buffer_write(bf,1,x,b);
}

size_t buffer_write(const void *buffer, size_t size, size_t count, Buffer *b) {	
	const char *dest = buffer;
	size_t bytes = 0;
	size_t left;	
	size_t i;

	if (!b) return 0;
	left = b->size - b->bytes;

	for(i = 0; i < count; i++) {
		if (bytes+size > left) break;
		memcpy(b->data+b->bytes+bytes,dest+bytes,size);
		bytes += size;
	}

	b->bytes += bytes;
	
	return i;
}

size_t buffer_read(void *buffer, size_t size, size_t count, Buffer *b) {
	char *dest = buffer;
	size_t bytes = 0;
	size_t i;

	for(i = 0; i < count; i++) {
		if (bytes+size > b->bytes) break;		// MW: if there is nothing in the input buffer drop out
		memcpy(dest+bytes,b->data+bytes,size);
		bytes += size;
	}
	buffer_skip(b,bytes);
	return i;
}

size_t buffer_skip(Buffer *b, size_t bytes)
{
	if (bytes) {
		memmove(b->data,b->data+bytes,b->bytes-bytes);
		b->bytes -= bytes;
	}
	return b->bytes;
}

int buffer_error(Buffer *b) {
	if (b) return FALSE;
	return TRUE;
}

int buffer_eof(Buffer *b) {
	if (b) return b->bytes == 0;
	return TRUE;
}

char *buffer_raw(Buffer *b) {
	if (b) return b->data;
	return NULL;
}

int buffer_size(Buffer *b) {
	if (b) return (int) b->size;
	return 0;
}

int buffer_bytes(Buffer *b) {
	if (b) return (int) b->bytes;
	return 0;
}
