diff --git a/libXmd/include/Xmd/Buffer.h b/libXmd/include/Xmd/Buffer.h index 6752587..e36e622 100644 --- a/libXmd/include/Xmd/Buffer.h +++ b/libXmd/include/Xmd/Buffer.h @@ -9,14 +9,26 @@ variable length strings and files. */ typedef struct _XmdBuffer XmdBuffer; -/* XmdBufferNew creates a new buffer with the specified element size. */ -XmdBuffer *XmdBufferNew (Cardinal size); +/* XmdBufferNew creates a new buffer that contains the specified type. */ +#define XmdBufferNew(type) _XmdBufferNew(sizeof(type)); +XmdBuffer *_XmdBufferNew (Cardinal size); /* XmdBufferPush adds a new element to the buffer. */ void XmdBufferPush (XmdBuffer *buffer, void *element); +/* XmdBufferPop copies the last element into element, and removes it from the + buffer. */ +void XmdBufferPop (XmdBuffer *buffer, void *element); + +/* XmdBufferPoke sets a single element of the buffer. */ +void XmdBufferPoke (XmdBuffer *buffer, Cardinal index, void *element); + +/* XmdBufferPeek copies the value of a single element of the buffer into + element. */ +void XmdBufferPeek (XmdBuffer *buffer, Cardinal index, void *element); + /* XmdBufferBreak frees the buffer without freeing its data. Its data is - returned and must be freed manually at some point. */ + returned and must be freed manually using XtFree() at some point. */ void *XmdBufferBreak (XmdBuffer *buffer); /* XmdBufferFree frees the buffer and any data associated with it. */ diff --git a/libXmd/src/Buffer.c b/libXmd/src/Buffer.c index de0f5b4..6fcd54c 100644 --- a/libXmd/src/Buffer.c +++ b/libXmd/src/Buffer.c @@ -16,12 +16,19 @@ static void XmdBufferResize (XmdBuffer *buffer, Cardinal length); static void XmdBufferFit (XmdBuffer *buffer); static void *XmdBufferOffset (XmdBuffer *buffer, Cardinal index); -XmdBuffer *XmdBufferNew (Cardinal size) { +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; } @@ -46,11 +53,34 @@ void *XmdBufferOffset (XmdBuffer *buffer, Cardinal index) { } 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, buffer->length - 1), + 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) { @@ -60,6 +90,8 @@ void *XmdBufferBreak (XmdBuffer *buffer) { } void XmdBufferFree (XmdBuffer *buffer) { - XtFree(buffer->data); + if (buffer->data != NULL) { + XtFree(buffer->data); + } XtFree((char *)(buffer)); }