Casio_asm/common/buffer.c

244 lines
4.8 KiB
C

#include "buffer.h"
#include "platform.h"
//define an assert macro
#define assert(a) if(!(a)) return 0
//free space at the end if we resize
#define BUFFER_EXT 256
//internal function to reallocate memory
int realloc_s(void** ptr, int size) {
void* allocated=realloc(*ptr, size);
if(!allocated) return 0;
*ptr=allocated;
return 1;
}
int checkBuffer(buffer_t *buffer) {
assert(buffer);
assert(buffer->size>=0);
assert(buffer->allocated>=0);
assert(buffer->size<=buffer->allocated);
assert(buffer->data);
return 1;
}
int allocBuffer(buffer_t *buffer, int size) {
//sanity check
assert(buffer);
assert(size>0);
//set size and allocated size
buffer->size=size;
buffer->allocated=size;
//malloc the buffer
buffer->data=malloc(size);
return buffer->data!=0;
}
int resizeBuffer(buffer_t *buffer, int size) {
//sanity check
assert(checkBuffer(buffer));
assert(size>=0);
//check if we have enough room already
if(size>buffer->allocated) {
//try realloc
int ok=realloc_s(&buffer->data, size+BUFFER_EXT);
if(ok) {
//realloc success
buffer->size=size;
buffer->allocated=size+BUFFER_EXT;
return 1;
} else {
//realloc fail
return 0;
}
} else {
//we have enough free space already, use it
buffer->size=size;
return 1;
}
}
int preallocBuffer(buffer_t *buffer, int size, int free) {
//sanity check
assert(checkBuffer(buffer));
assert(size>=0);
if(free<0) free=0;
//compute required size
int required=free+buffer->size;
if(size>required) required=size;
//check if we already have this allocated
if(required>buffer->allocated) {
//we need to enlarge the allocated area
int ok=realloc_s(&buffer->data, required);
if(ok) {
//realloc success
buffer->allocated=required;
return 1;
} else {
//realloc fail
return 0;
}
} else {
//we already have enough free space
return 1;
}
}
int freeBuffer(buffer_t *buffer) {
//sanity check
assert(buffer);
assert(buffer->data);
//free the memory
free(buffer->data);
//destroy the object
buffer->data=0;
buffer->size=0;
buffer->allocated=0;
return 1;
}
int copyBuffer(buffer_t *src, int srcPos, buffer_t *dest, int destPos, int len) {
//sanity check
assert(checkBuffer(src));
assert(checkBuffer(dest));
assert(len>=0&&srcPos>=0&&destPos>=0);
assert(srcPos+len<=src->size);
assert(destPos+len<=dest->size);
//get char pointers
char* srcPtr=(char*) src->data;
char* destPtr=(char*) dest->data;
char* maxPtr=srcPtr+len;
//copy the buffer
while(srcPtr<maxPtr) {
*(destPtr++)=*(srcPtr++);
}
return 1;
}
int appendBuffer(buffer_t *buffer, buffer_t *data, int len) {
//sanity check
assert(checkBuffer(buffer));
assert(checkBuffer(data));
assert(len>=0);
assert(len<=data->size);
//get the current size of buffer
int pos=buffer->size;
//resize the buffer to get some free space
if(!resizeBuffer(buffer, pos+len)) return 0;
//copy the buffer
return copyBuffer(data, 0, buffer, pos, len);
}
int wrapBuffer(buffer_t *buffer, char* data, int len) {
//sanity check
assert(buffer);
assert(len>0);
assert(data);
//set buffer data
buffer->size=len;
buffer->allocated=len;
buffer->data=(void*) data;
return 1;
}
int writeDataBuffer(buffer_t *buffer, int pos, void* data, int len) {
//sanity check
assert(checkBuffer(buffer));
assert(data);
assert(len>=0&&pos>=0);
assert(pos+len<=buffer->size);
//get char pointers
char* ptr=(char*) buffer->data;
char* dataPtr=(char*) dataPtr;
//copy the buffer
for(int i=0; i<len; i++) *(ptr++)=*(dataPtr++);
return 1;
}
int appendDataBuffer(buffer_t *buffer, void* data, int len) {
//sanity check
assert(checkBuffer(buffer));
assert(data);
assert(len>=0);
//get the current size of buffer
int pos=buffer->size;
//resize the buffer to get some free space
if(!resizeBuffer(buffer, pos+len)) return 0;
//get our pointers
char* dest=pos+(char*) buffer->data;
char* src=(char*) data;
for(int i=0; i<len; i++) *(dest++)=*(src++);
return 1;
}
int appendStringBuffer(buffer_t *buffer, char* str) {
//sanity check
assert(checkBuffer(buffer));
assert(str);
//get the current size of buffer and string length
int pos=buffer->size;
int len=strlend(str);
//resize the buffer to get some free space
if(!resizeBuffer(buffer, pos+len)) return 0;
//write the data
char* ptr=pos+(char*) buffer->data;
while(*str) *(ptr++)=*(str++);
return 1;
}
int toStringBuffer(buffer_t *buffer) {
//push a null at the end
if(!appendByteBuffer(buffer, '\0')) return 0;
//make it invisible
buffer->size--;
return 1;
}
int appendByteBuffer(buffer_t *buffer, int data) {
//sanity check
assert(checkBuffer(buffer));
//get the current size of buffer and string length
int pos=buffer->size;
//resize the buffer to get some free space
if(!resizeBuffer(buffer, pos+1)) return 0;
//write the data
char* ptr=(char*) buffer->data;
ptr[pos]=(char) data;
return 1;
}