Xmd/libXmd/src/Buffer.c
Sasha Koshka e57e93c8b6 Oh my jod
2023-11-07 03:13:13 -05:00

98 lines
2.2 KiB
C

#include <Xmd/Buffer.h>
#include <string.h>
#include <stdio.h>
#define XmdBUFFER_GROWTH_FACTOR 2
#define XmdBUFFER_INITIAL_CAPACITY 8
struct _XmdBuffer {
void * data;
Cardinal size;
Cardinal length;
Cardinal capacity;
};
static void XmdBufferResize (XmdBuffer *buffer, Cardinal length);
static void XmdBufferFit (XmdBuffer *buffer);
static void *XmdBufferOffset (XmdBuffer *buffer, Cardinal index);
XmdBuffer *_XmdBufferNew (Cardinal size) {
XmdBuffer *buffer = XtNew(XmdBuffer);
if (buffer == NULL) return NULL;
buffer->size = size;
buffer->length = 0;
buffer->capacity = XmdBUFFER_INITIAL_CAPACITY;
buffer->data = XtCalloc(buffer->capacity, buffer->size);
if (buffer->data == NULL) {
XmdBufferFree(buffer);
return NULL;
}
XmdBufferFit(buffer);
return buffer;
}
void XmdBufferResize (XmdBuffer *buffer, Cardinal length) {
buffer->length = length;
XmdBufferFit(buffer);
}
void XmdBufferFit (XmdBuffer *buffer) {
if (buffer->length > buffer->capacity) {
buffer->capacity *= XmdBUFFER_GROWTH_FACTOR;
buffer->data = XtReallocArray (
buffer->data,
buffer->capacity,
buffer->size);
}
}
void *XmdBufferOffset (XmdBuffer *buffer, Cardinal index) {
return buffer->data + (index * buffer->size);
}
void XmdBufferPush (XmdBuffer *buffer, void *element) {
Cardinal index = buffer->length;
XmdBufferResize(buffer, buffer->length + 1);
XmdBufferPoke(buffer, index, element);
}
void XmdBufferPop (XmdBuffer *buffer, void *element) {
Cardinal index = buffer->length - 1;
XmdBufferPeek(buffer, index, element);
XmdBufferResize(buffer, index);
}
void XmdBufferPoke (XmdBuffer *buffer, Cardinal index, void *element) {
if (index > buffer->length) return;
memcpy (
XmdBufferOffset(buffer, index),
element,
buffer->size);
char test;
XmdBufferPeek(buffer, index, &test);
}
void XmdBufferPeek (XmdBuffer *buffer, Cardinal index, void *element) {
if (index > buffer->length) return;
memcpy (
element,
XmdBufferOffset(buffer, index),
buffer->size);
}
void *XmdBufferBreak (XmdBuffer *buffer) {
void *data = buffer->data;
XtFree((char *)(buffer));
return data;
}
void XmdBufferFree (XmdBuffer *buffer) {
if (buffer->data != NULL) {
XtFree(buffer->data);
}
XtFree((char *)(buffer));
}