forked from PlaneteCasio/Casio_asm
244 lines
4.8 KiB
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;
|
|
}
|