#include #include #include #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)); }