/** * \file * header file of buffers */ #ifndef BUFFER_H #define BUFFER_H #include "generic.h" extern struct ProtoInterface; /** \defgroup buffers buffers */ /** \defgroup bufferVector BufferVector * \ingroup buffers */ /** \{ */ /** Variables for BufferVector. \see section \ref sectionBufferVector */ /** Different states of the buffer. For example error states. */ static enum BufferVector_state { BUFFERVECTOR_OK, BUFFERVECTOR_DISABLED, BUFFERVECTOR_MEMORYEXHAUSTED, }; typedef struct BufferVector { struct ProtoInterface *protoInterfacep; /**< Interface to print and malloc functions. */ enum BufferVector_state bufferState; /**< State of buffer. Holds for example errors. */ char *bufferdatap; /**< Pointer to memory of buffer which is dynamically allocated. */ size_t actPos; /**< Offset to first Element in Buffervector::bufferdatap. */ size_t actSize; /**< Number of current valid elements in buffer. */ size_t capacity; /**< Maximal number of elements buffer can hold without enlarging. */ size_t elementSize; /**< Size of one element in bytes. */ } BufferVector; typedef int (GetdataExternCB)(void *contextp, void *dstp, size_t *nElementsp); /**< Type of a callback function which will be called by bufferVector_fillExtern() to fill the buffer by an external function. This function has to ensure that only the maximum number of \a *nElementsp will be written in memory pointed by \a dstp \b and that \a *nElementsp will be updated to the actual number of written elements. \param contextp Pointer passed through bufferVector_fillExtern() which can be used to access vars of the caller of it. \param dstp Pointer to memory where data should be written. \param nElemntsp Pointer to the maximum number of elements which are allowed to write. The callback function has to update this value to the actual number of elements written. \returns false if failed, true otherwise. */ int bufferVector_init(BufferVector *bufferp, size_t elementSize, size_t initSize, struct ProtoInterface *protoInterfacep); void bufferVector_destroy(BufferVector *bufferp); const char* bufferVector_getStateString(BufferVector *bufferp); int bufferVector_enlarge(BufferVector *bufferp, size_t neededCapacity); /**< Enlarges the buffer to a capacity wich can hold at least \a neededCapacity elements. The resulting capacity is a multiply of the actual capacity. \param neededCapacity Specifies the wanted capacity. If it is zero, buffer will be doubled. \param bufferp actual BufferVector object. */ int bufferVector_reorder(BufferVector *bufferp); /**< Copies elements at the beginning of buffer and ensures therefore for maximal space without reordering. \returns true if buffer was reorderd. \returns false if buffer was already alligned at the beginning. */ void* bufferVector_ensureSpaceForElemements(BufferVector *bufferp, size_t nElements); void* bufferVector_appendEmptyElements(BufferVector *bufferp, size_t nElements); int bufferVector_appendElement(BufferVector *bufferp, const void *elementp); int bufferVector_appendElements(BufferVector *bufferp, const void *elementsp, size_t nElements); void* bufferVector_getElementsRef(BufferVector *bufferp, size_t pos, size_t nElements); int bufferVector_getElementsCopy(BufferVector *bufferp, void *dtsp, size_t pos, size_t nElements); INLINE size_t bufferVector_getCapacity(BufferVector *bufferp) { return bufferp->capacity; } INLINE size_t bufferVector_getActSize(BufferVector *bufferp) { return bufferp->actSize; } INLINE int bufferVector_isFull(BufferVector *bufferp) { return (bufferp->capacity == bufferp->actSize); } INLINE void bufferVector_clear(BufferVector *bufferp) { bufferp->actPos = 0; bufferp->actSize = 0; } INLINE void* bufferVector_getElementRef(BufferVector *bufferp, size_t pos) { return bufferVector_getElementsRef(bufferp, pos, 1); } INLINE const void* bufferVector_getElementRefConst(BufferVector *bufferp, size_t pos) { return (const void*) bufferVector_getElementsRef(bufferp, pos, 1); } INLINE const void* bufferVector_getElementsRefConst(BufferVector *bufferp, size_t pos, size_t nElements) { return (const void*) bufferVector_getElementsRef(bufferp, pos, nElements); } INLINE size_t bufferVector_skip(BufferVector *bufferp, size_t nSkip) { if (nSkip >= bufferp->actSize) { nSkip = bufferp->actSize; bufferp->actPos = 0; bufferp->actSize = 0; } else { bufferp->actPos += nSkip; bufferp->actSize -= nSkip; } return nSkip; } /** This function calls the callback function pointed to by \a getdataExternCB which should fill the buffer. The pointer \a contextp whill be forwarded to this callback function. See \ref GetdataExternCB.*/ INLINE int bufferVector_fillExtern(BufferVector *bufferp, void* contextp, GetdataExternCB *getdataExternCB) { int ret; size_t nFree = bufferp->capacity - bufferp->actPos - bufferp->actSize; void *dstp = bufferp->bufferdatap + (bufferp->actPos + bufferp->actSize) * bufferp->elementSize; ret = getdataExternCB(contextp, dstp, &nFree); if (ret) bufferp->actSize += nFree; return ret; } INLINE int bufferVector_getRemoveElementsCopy(BufferVector *bufferp, void *dtsp, size_t nElements) { int ret; ret = bufferVector_getElementsCopy(bufferp, dtsp, 0, nElements); if (ret) bufferVector_skip(bufferp, nElements); return ret; } /** \} */ /** \defgroup stackInt StackInt * \ingroup buffers */ /** \{ */ /** Variables for StackInt. \see section \ref sectionStackInt */ /** Different states of the stack. For example error states. */ enum StackInt_state { STACKINT_OK, STACKINT_DISABLED, STACKINT_MEMORYEXHAUSTED, }; typedef struct StackInt { struct ProtoInterface *protoInterfacep; /**< Interface to print and malloc functions. */ enum StackInt_state stackState; /**< State of stack. Holds for example errors. */ unsigned int *bufferdatap; /**< Pointer to the reference data. */ size_t actSize; /**< Current number of stored elements. */ size_t capacity; /**< Maximal number of elements which could be stored. */ } StackInt; int stackInt_init(StackInt *stackp, size_t initCapacity, struct ProtoInterface *protoInterfacep); void stackInt_destroy(StackInt *stackp); const char* stackInt_getStateString(StackInt *stackp); int stackInt_enlarge(StackInt *stackp); /**< Enlarges the stack buffer. */ int stackInt_push(StackInt *stackp, unsigned int value); /**< Pushes one element to stack. */ int stackInt_pop(StackInt *stackp, unsigned int *value); /**< Pops one element from stack. This element will be deleted from stack. */ int stackInt_skip(StackInt *stackp, size_t nr); /**< Deletes the last \a nr elements from stack. */ int stackInt_get(StackInt *stackp, unsigned int *value, size_t nPrev); /**< Get one element from stack without deleting it. The element is choosed by \a nPrev. \a nPrev == 0 means the last element. */ /** Clears the stack. */ INLINE void stackInt_clear(StackInt *stackp) { stackp->actSize = 0; } /** Returns current number of stored elements. */ INLINE size_t stackInt_getSize(StackInt *stackp) { return stackp->actSize; } /** \} */ #endif