/** * \file * source code of buffers */ #include #include #include "buffer.h" #ifdef TEST # include "protointerface_test.h" #else # include "protointerface.h" #endif #define MALLOC(size) (protoInterface_alloc(THISP->protoInterfacep, size)) #define FREE(pointer) (protoInterface_free(THISP->protoInterfacep, pointer)) /*====================================================== ======== BUFFERVECTOR ================================== ======================================================*/ /** \addtogroup bufferVector */ /** \{ */ #undef THISP #define THISP (bufferp) #define BUFFERVECTOR_STATESTRING_MAX_LEN 20 /** String representation of enum \ref BufferVector_state. */ static const char bufferVector_stateStrings[][BUFFERVECTOR_STATESTRING_MAX_LEN] = { "ok", "disabled", "memory exhausted", }; int bufferVector_init(BufferVector *bufferp, size_t elementSize, size_t initSize, struct ProtoInterface *protoInterfacep) { bufferp->protoInterfacep = protoInterfacep; bufferp->bufferState = BUFFERVECTOR_OK; bufferp->bufferdatap = MALLOC(initSize * elementSize); if (bufferp->bufferdatap == NULL) { bufferp->bufferState = BUFFERVECTOR_MEMORYEXHAUSTED; return 0; } bufferp->actPos = 0; bufferp->actSize = 0; bufferp->capacity = initSize; bufferp->elementSize = elementSize; return TRUE; } void bufferVector_destroy(BufferVector *bufferp) { bufferp->protoInterfacep = NULL; bufferp->bufferState = BUFFERVECTOR_DISABLED; FREE(bufferp->bufferdatap); bufferp->bufferdatap = NULL; bufferp->actPos = 0; bufferp->actSize = 0; bufferp->capacity = 0; bufferp->elementSize = 0; } const char* bufferVector_getStateString(BufferVector *bufferp) { return bufferVector_stateStrings[bufferp->bufferState]; } int bufferVector_enlarge(BufferVector *bufferp, size_t neededCapacity) { void* tmpp = NULL; size_t newCapacity = bufferp->capacity; /*standard case*/ if (neededCapacity == 0) neededCapacity = newCapacity * 2; while (neededCapacity > newCapacity) newCapacity *= 2; tmpp = MALLOC(bufferp->elementSize * newCapacity); if (tmpp == NULL) { bufferp->bufferState = BUFFERVECTOR_MEMORYEXHAUSTED; return 0; } /*automatical reorder*/ memcpy(tmpp, bufferp->bufferdatap + bufferp->actPos, bufferp->actSize * bufferp->elementSize); bufferp->actPos = 0; bufferp->capacity = newCapacity; FREE(bufferp->bufferdatap); bufferp->bufferdatap = tmpp; return TRUE; } int bufferVector_reorder(BufferVector *bufferp) { if (bufferp->actPos != 0) { memmove(bufferp->bufferdatap, bufferp->bufferdatap + bufferp->actPos * bufferp->elementSize, bufferp->actSize * bufferp->elementSize); bufferp->actPos = 0; return TRUE; } return 0; } void* bufferVector_ensureSpaceForElemements(BufferVector *bufferp, size_t nElements) { void *ret = NULL; /*at the moment there are not enough space left in buffer*/ if (bufferp->actPos + bufferp->actSize + nElements > bufferp->capacity) { /*even after reorder there would be not enough space left*/ if (bufferp->actSize + nElements > bufferp->capacity) { if (bufferVector_enlarge(bufferp, bufferp->actSize + nElements) == 0) return NULL; } else bufferVector_reorder(bufferp); } ret = bufferp->bufferdatap + (bufferp->actPos + bufferp->actSize) * bufferp->elementSize; return ret; } void* bufferVector_appendEmptyElements(BufferVector *bufferp, size_t nElements) { void *ret = NULL; ret = bufferVector_ensureSpaceForElemements(bufferp, nElements); if (ret) bufferp->actSize += nElements; return ret; } int bufferVector_appendElements(BufferVector *bufferp, const void *elementsp, size_t nElements) { void* beginp = NULL; beginp = bufferVector_appendEmptyElements(bufferp, nElements); if (beginp == NULL) return 0; memcpy(beginp, elementsp, bufferp->elementSize * nElements); return TRUE; } void* bufferVector_getElementsRef(BufferVector *bufferp, size_t pos, size_t nElements) { void *beginp = NULL; if (pos + nElements > bufferp->actSize || nElements == 0) return NULL; beginp = bufferp->bufferdatap + (bufferp->actPos + pos) * bufferp->elementSize; return beginp; } int bufferVector_getElementsCopy(BufferVector *bufferp, void *dtsp, size_t pos, size_t nElements) { void* beginp = NULL; if (nElements + pos > bufferp->actSize) return 0; beginp = bufferp->bufferdatap + (bufferp->actPos + pos) * bufferp->elementSize; memcpy(dtsp, beginp, nElements * bufferp->elementSize); return TRUE; } /** \} */ /*====================================================== ======== STACKINT ====================================== ======================================================*/ /** \addtogroup stackInt */ /** \{ */ #undef THISP #define THISP (stackp) #define STACKINT_STATESTRING_MAX_LEN 20 /** String representation of enum \ref StackInt_state. */ static const char stackInt_stateStrings[][STACKINT_STATESTRING_MAX_LEN] = { "ok", "disabled", "memory exhausted", }; int stackInt_init(StackInt *stackp, size_t initCapacity, struct ProtoInterface *protoInterfacep) { stackp->protoInterfacep = protoInterfacep; stackp->stackState = STACKINT_OK; stackp->bufferdatap = MALLOC(initCapacity * sizeof(unsigned int)); if (stackp->bufferdatap == NULL) { stackp->stackState = STACKINT_MEMORYEXHAUSTED; return 0; } stackp->actSize = 0; stackp->capacity = initCapacity; return TRUE; } void stackInt_destroy(StackInt *stackp) { stackp->protoInterfacep = NULL; stackp->stackState = STACKINT_DISABLED; FREE(stackp->bufferdatap); stackp->bufferdatap = NULL; stackp->actSize = 0; stackp->capacity = 0; } const char* stackInt_getStateString(StackInt *stackp) { return stackInt_stateStrings[stackp->stackState]; } int stackInt_enlarge(StackInt *stackp) { unsigned int *tmpp = NULL; tmpp = MALLOC(stackp->capacity * 2); if (tmpp == NULL) { stackp->stackState = STACKINT_MEMORYEXHAUSTED; return 0; } FREE(stackp->bufferdatap); stackp->bufferdatap = tmpp; stackp->capacity *= 2; return TRUE; } int stackInt_push(StackInt *stackp, unsigned int value) { if (stackp->actSize + 1 > stackp->capacity) { if (stackInt_enlarge(stackp) == 0) return 0; } stackp->bufferdatap[stackp->actSize] = value; stackp->actSize++; return TRUE; } int stackInt_pop(StackInt *stackp, unsigned int *value) { if (stackp->actSize == 0) return 0; stackp->actSize--; *value = stackp->bufferdatap[stackp->actSize]; return TRUE; } int stackInt_skip(StackInt *stackp, size_t nr) { if (nr > stackp->actSize) { stackp->actSize = 0; return 0; } else { stackp->actSize -= nr; return TRUE; } } int stackInt_get(StackInt *stackp, unsigned int *value, size_t nPrev) { if (nPrev > stackp->actSize - 1) return 0; *value = stackp->bufferdatap[stackp->actSize - 1 - nPrev]; return TRUE; } /** \} */