|
ucx
UAP Common Extensions
|
Advanced buffer implementation. More...
Go to the source code of this file.
Data Structures | |
| struct | cx_buffer_s |
| Structure for the UCX buffer data. More... | |
Macros | |
| #define | CX_BUFFER_DEFAULT 0x00 |
| No buffer features enabled (all flags cleared). | |
| #define | CX_BUFFER_FREE_CONTENTS 0x01 |
| If this flag is enabled, the buffer will automatically free its contents when destroyed. | |
| #define | CX_BUFFER_AUTO_EXTEND 0x02 |
| If this flag is enabled, the buffer will automatically extend its capacity. | |
| #define | CX_BUFFER_COPY_ON_WRITE 0x04 |
| If this flag is enabled, the buffer will allocate new memory when written to. | |
| #define | CX_BUFFER_COPY_ON_EXTEND 0x08 |
| If this flag is enabled, the buffer will copy its contents to a new memory area on reallocation. | |
| #define | CX_BUFFER_DO_NOT_FREE 0x10 |
| If this flag is enabled, the buffer will never free its contents regardless of CX_BUFFER_FREE_CONTENTS. | |
| #define | cxBufferWriteFunc ((cx_write_func) cxBufferWrite) |
| Function pointer for cxBufferWrite that is compatible with cx_write_func. | |
| #define | cxBufferReadFunc ((cx_read_func) cxBufferRead) |
| Function pointer for cxBufferRead that is compatible with cx_read_func. | |
| #define | cxBufferPutString(buffer, str) |
| Writes a string to a buffer with cxBufferWrite(). | |
| #define | cxBufferAppendString(buffer, str) |
| Appends a string to a buffer with cxBufferAppend(). | |
Typedefs | |
| typedef struct cx_buffer_s | CxBuffer |
| UCX buffer. | |
Functions | |
| int | cxBufferInit (CxBuffer *buffer, const CxAllocator *allocator, void *space, size_t capacity, int flags) |
| Initializes a fresh buffer. | |
| void | cxBufferDestroy (CxBuffer *buffer) |
| Destroys the buffer contents. | |
| void | cxBufferFree (CxBuffer *buffer) |
| Deallocates the buffer. | |
| CxBuffer * | cxBufferCreate (const CxAllocator *allocator, void *space, size_t capacity, int flags) |
| Allocates and initializes a fresh buffer. | |
| int | cxBufferShift (CxBuffer *buffer, off_t shift) |
| Shifts the contents of the buffer by the given offset. | |
| int | cxBufferShiftRight (CxBuffer *buffer, size_t shift) |
| Shifts the buffer to the right. | |
| int | cxBufferShiftLeft (CxBuffer *buffer, size_t shift) |
| Shifts the buffer to the left. | |
| int | cxBufferSeek (CxBuffer *buffer, off_t offset, int whence) |
| Moves the position of the buffer. | |
| size_t | cxBufferPop (CxBuffer *buffer, size_t size, size_t nitems) |
| Discards items from the end of the buffer. | |
| void | cxBufferClear (CxBuffer *buffer) |
| Clears the buffer by resetting the position and deleting the data. | |
| void | cxBufferReset (CxBuffer *buffer) |
| Resets the buffer by resetting the position and size to zero. | |
| bool | cxBufferEof (const CxBuffer *buffer) |
| Tests, if the buffer position has exceeded the buffer size. | |
| int | cxBufferReserve (CxBuffer *buffer, size_t capacity) |
| Ensures that the buffer has the required capacity. | |
| int | cxBufferMaximumCapacity (CxBuffer *buffer, size_t capacity) |
| Limits the buffer's capacity. | |
| int | cxBufferMinimumCapacity (CxBuffer *buffer, size_t capacity) |
| Ensures that the buffer has a minimum capacity. | |
| void | cxBufferShrink (CxBuffer *buffer, size_t reserve) |
| Shrinks the capacity of the buffer to fit its current size. | |
| size_t | cxBufferWrite (const void *ptr, size_t size, size_t nitems, CxBuffer *buffer) |
| Writes data to a CxBuffer. | |
| size_t | cxBufferAppend (const void *ptr, size_t size, size_t nitems, CxBuffer *buffer) |
| Appends data to a CxBuffer. | |
| size_t | cxBufferRead (void *ptr, size_t size, size_t nitems, CxBuffer *buffer) |
| Reads data from a CxBuffer. | |
| int | cxBufferPut (CxBuffer *buffer, int c) |
| Writes a character to a buffer. | |
| int | cxBufferTerminate (CxBuffer *buffer) |
| Writes a terminating zero to a buffer at the current position. | |
| size_t | cx_buffer_put_string (CxBuffer *buffer, cxstring str) |
| Internal function - do not use. | |
| size_t | cx_buffer_append_string (CxBuffer *buffer, cxstring str) |
| Internal function - do not use. | |
| int | cxBufferGet (CxBuffer *buffer) |
| Gets a character from a buffer. | |
| static cxstring | cx_bstr (CxBuffer *buffer) |
Gets the data in a buffer as a cxstring. | |
| static cxmutstr | cx_bstr_m (CxBuffer *buffer) |
Gets the data in a buffer as a cxmutstr. | |
Advanced buffer implementation.
Instances of CxBuffer can be used to read from or to write to like one would do with a stream.
Some features for convenient use of the buffer can be enabled. See the documentation of the macro constants for more information.
| #define CX_BUFFER_COPY_ON_EXTEND 0x08 |
If this flag is enabled, the buffer will copy its contents to a new memory area on reallocation.
After performing the copy, the flag is automatically cleared. This flag has no effect on buffers which do not have CX_BUFFER_AUTO_EXTEND set, which is why buffers automatically admit the auto-extend flag when initialized with copy-on-extend enabled.
| #define CX_BUFFER_COPY_ON_WRITE 0x04 |
If this flag is enabled, the buffer will allocate new memory when written to.
The current contents of the buffer will be copied to the new memory, and the flag will be cleared while the CX_BUFFER_FREE_CONTENTS flag will be set automatically.
| #define CX_BUFFER_DO_NOT_FREE 0x10 |
If this flag is enabled, the buffer will never free its contents regardless of CX_BUFFER_FREE_CONTENTS.
This is useful, for example, when you want to keep a pointer to the data after destroying the buffer.
| #define CX_BUFFER_FREE_CONTENTS 0x01 |
If this flag is enabled, the buffer will automatically free its contents when destroyed.
Do NOT set this flag together with CX_BUFFER_COPY_ON_WRITE. It will be automatically set when the copy-on-write operation is performed.
| #define cxBufferAppendString | ( | buffer, | |
| str ) |
Appends a string to a buffer with cxBufferAppend().
| buffer | (CxBuffer*) the buffer |
| str | (any string) the zero-terminated string |
size_t) the number of bytes written | #define cxBufferPutString | ( | buffer, | |
| str ) |
Writes a string to a buffer with cxBufferWrite().
| buffer | (CxBuffer*) the buffer |
| str | (any string) the zero-terminated string |
size_t) the number of bytes written | #define cxBufferReadFunc ((cx_read_func) cxBufferRead) |
Function pointer for cxBufferRead that is compatible with cx_read_func.
| #define cxBufferWriteFunc ((cx_write_func) cxBufferWrite) |
Function pointer for cxBufferWrite that is compatible with cx_write_func.
Gets the data in a buffer as a cxstring.
| buffer | the buffer |
cxstring Gets the data in a buffer as a cxmutstr.
| buffer | the buffer |
cxmutstr Internal function - do not use.
| buffer | the buffer |
| str | the string |
Internal function - do not use.
| buffer | the buffer |
| str | the string |
| size_t cxBufferAppend | ( | const void * | ptr, |
| size_t | size, | ||
| size_t | nitems, | ||
| CxBuffer * | buffer ) |
Appends data to a CxBuffer.
The data is always appended to current data within the buffer, regardless of the current position. This is especially useful when the buffer is primarily meant for reading while additional data is added to the buffer occasionally. Consequently, the position of the buffer is unchanged after this operation.
| ptr | a pointer to the memory area containing the bytes to be written |
| size | the length of one element |
| nitems | the element count |
| buffer | the CxBuffer to write to |
| void cxBufferClear | ( | CxBuffer * | buffer | ) |
Clears the buffer by resetting the position and deleting the data.
The data is deleted by zeroing it with a call to memset(). If you do not need that, you can use the faster cxBufferReset().
| buffer | the buffer to be cleared |
| CxBuffer * cxBufferCreate | ( | const CxAllocator * | allocator, |
| void * | space, | ||
| size_t | capacity, | ||
| int | flags ) |
Allocates and initializes a fresh buffer.
You may also provide a read-only space, in which case you will need to cast the pointer, and you should set the CX_BUFFER_COPY_ON_WRITE flag. When you specify stack memory as space and decide to use the auto-extension feature, you must use the CX_BUFFER_COPY_ON_EXTEND flag, instead of the CX_BUFFER_AUTO_EXTEND flag.
NULL as the argument for space. Then this function will allocate the space and enforce the CX_BUFFER_FREE_CONTENTS flag.| allocator | the allocator to use for allocating the structure and the automatic memory management within the buffer (if NULL, the cxDefaultAllocator will be used) |
| space | pointer to the memory area, or NULL to allocate new memory |
| capacity | the capacity of the buffer |
| flags | buffer features (see cx_buffer_s.flags) |
NULL if a required allocation failed | void cxBufferDestroy | ( | CxBuffer * | buffer | ) |
Destroys the buffer contents.
Has no effect if the CX_BUFFER_FREE_CONTENTS feature is not enabled. If you want to free the memory of the entire buffer, use cxBufferFree().
| buffer | the buffer which contents shall be destroyed |
| bool cxBufferEof | ( | const CxBuffer * | buffer | ) |
Tests, if the buffer position has exceeded the buffer size.
| buffer | the buffer to test |
| true | if the current buffer position has exceeded the last byte of the buffer's contents |
| false | otherwise |
| void cxBufferFree | ( | CxBuffer * | buffer | ) |
Deallocates the buffer.
If the CX_BUFFER_FREE_CONTENTS feature is enabled, this function also destroys the contents. If you only want to destroy the contents, use cxBufferDestroy().
| buffer | the buffer to deallocate |
| int cxBufferGet | ( | CxBuffer * | buffer | ) |
Gets a character from a buffer.
The current position of the buffer is increased after a successful read.
| buffer | the buffer to read from |
EOF, if the end of the buffer is reached | int cxBufferInit | ( | CxBuffer * | buffer, |
| const CxAllocator * | allocator, | ||
| void * | space, | ||
| size_t | capacity, | ||
| int | flags ) |
Initializes a fresh buffer.
You may also provide a read-only space, in which case you will need to cast the pointer, and you should set the CX_BUFFER_COPY_ON_WRITE flag.
You need to set the size manually after initialization if you provide space which already contains data.
When you specify stack memory as space and decide to use the auto-extension feature, you must use the CX_BUFFER_COPY_ON_EXTEND flag, instead of the CX_BUFFER_AUTO_EXTEND flag.
NULL as the argument for space. Then this function will allocate the space and enforce the CX_BUFFER_FREE_CONTENTS flag. In that case, specifying copy-on-write should be avoided, because the allocated space will be leaking after the copy-on-write operation.| buffer | the buffer to initialize |
| allocator | the allocator this buffer shall use for automatic memory management (if NULL, the cxDefaultAllocator will be used) |
| space | pointer to the memory area, or NULL to allocate new memory |
| capacity | the capacity of the buffer |
| flags | buffer features (see cx_buffer_s.flags) |
| int cxBufferMaximumCapacity | ( | CxBuffer * | buffer, |
| size_t | capacity ) |
Limits the buffer's capacity.
If the current capacity is already larger, this function fails and returns non-zero.
The capacity limit will affect auto-extension features, as well as future calls to cxBufferMinimumCapacity() and cxBufferReserve().
| buffer | the buffer |
| capacity | the maximum allowed capacity for this buffer |
| zero | the limit is applied |
| non-zero | the new limit is smaller than the current capacity |
| int cxBufferMinimumCapacity | ( | CxBuffer * | buffer, |
| size_t | capacity ) |
Ensures that the buffer has a minimum capacity.
If the current capacity is not sufficient, the buffer will be generously extended.
The new capacity will be a power of two until the system's page size is reached. Then, the new capacity will be a multiple of the page size.
| buffer | the buffer |
| capacity | the minimum required capacity for this buffer |
| zero | the capacity was already sufficient or successfully increased |
| non-zero | on allocation failure |
| size_t cxBufferPop | ( | CxBuffer * | buffer, |
| size_t | size, | ||
| size_t | nitems ) |
Discards items from the end of the buffer.
When the current position points to a byte that gets discarded, the position is set to the buffer size.
| buffer | the buffer |
| size | the size of one item |
| nitems | the number of items to discard |
| int cxBufferPut | ( | CxBuffer * | buffer, |
| int | c ) |
Writes a character to a buffer.
The least significant byte of the argument is written to the buffer. If the end of the buffer is reached and CX_BUFFER_AUTO_EXTEND feature is enabled, the buffer capacity is extended, unless a limit set by cxBufferMaximumCapacity() is reached. If the feature is disabled or the buffer extension fails, EOF is returned.
On successful writing, the position of the buffer is increased.
If you just want to write a null-terminator at the current position, you should use cxBufferTerminate() instead.
| buffer | the buffer to write to |
| c | the character to write |
EOF when the end of the stream is reached, and automatic extension is not enabled or not possible | size_t cxBufferRead | ( | void * | ptr, |
| size_t | size, | ||
| size_t | nitems, | ||
| CxBuffer * | buffer ) |
Reads data from a CxBuffer.
The position of the buffer is increased by the number of bytes read.
| ptr | a pointer to the memory area where to store the read data |
| size | the length of one element |
| nitems | the element count |
| buffer | the CxBuffer to read from |
| int cxBufferReserve | ( | CxBuffer * | buffer, |
| size_t | capacity ) |
Ensures that the buffer has the required capacity.
If the current capacity is not sufficient, the buffer will be extended. If the current capacity is larger, the buffer is shrunk and superfluous content is discarded.
This function will reserve no more bytes than requested, in contrast to cxBufferMinimumCapacity(), which may reserve more bytes to improve the number of future necessary reallocations.
| buffer | the buffer |
| capacity | the required capacity for this buffer |
| zero | on success |
| non-zero | on allocation failure |
| void cxBufferReset | ( | CxBuffer * | buffer | ) |
Resets the buffer by resetting the position and size to zero.
The data in the buffer is not deleted. If you need a safe reset of the buffer, use cxBufferClear().
| buffer | the buffer to be cleared |
| int cxBufferSeek | ( | CxBuffer * | buffer, |
| off_t | offset, | ||
| int | whence ) |
Moves the position of the buffer.
The new position is relative to the whence argument.
SEEK_SET marks the start of the buffer. SEEK_CUR marks the current position. SEEK_END marks the end of the buffer.With an offset of zero, this function sets the buffer position to zero (SEEK_SET), the buffer size (SEEK_END) or leaves the buffer position unchanged (SEEK_CUR).
| buffer | the buffer |
| offset | position offset relative to whence |
| whence | one of SEEK_SET, SEEK_CUR or SEEK_END |
| zero | success |
| non-zero | if the position is invalid |
| int cxBufferShift | ( | CxBuffer * | buffer, |
| off_t | shift ) |
Shifts the contents of the buffer by the given offset.
If the offset is positive, the contents are shifted to the right. If auto extension is enabled, the buffer grows, if necessary. In case the auto extension fails, this function returns a non-zero value and no contents are changed. When the auto extension is disabled, the contents that do not fit into the buffer are discarded.
If the offset is negative, the contents are shifted to the left where the first shift bytes are discarded. The new size of the buffer is the old size minus the absolute shift value. If this value is larger than the buffer size, the buffer is emptied (but not cleared, see the security note below).
The buffer position gets shifted alongside the content but is kept within the boundaries of the buffer.
off_t is not large enough, there are specialized cxBufferShiftLeft() and cxBufferShiftRight() functions using a size_t as the parameter type.memset(buffer->bytes, 0, shift) for a right shift or memset(buffer->bytes + buffer->size, 0, buffer->capacity - buffer->size) for a left shift.| buffer | the buffer |
| shift | the shift offset (negative means left shift) |
| zero | success |
| non-zero | if a required auto-extension or copy-on-write fails |
| int cxBufferShiftLeft | ( | CxBuffer * | buffer, |
| size_t | shift ) |
Shifts the buffer to the left.
See cxBufferShift() for details.
| buffer | the buffer |
| shift | the positive shift offset |
| zero | success |
| non-zero | if the buffer uses copy-on-write and the allocation fails |
| int cxBufferShiftRight | ( | CxBuffer * | buffer, |
| size_t | shift ) |
Shifts the buffer to the right.
See cxBufferShift() for details.
| buffer | the buffer |
| shift | the shift offset |
| zero | success |
| non-zero | if a required auto-extension or copy-on-write fails |
| void cxBufferShrink | ( | CxBuffer * | buffer, |
| size_t | reserve ) |
Shrinks the capacity of the buffer to fit its current size.
If reserve is larger than zero, the buffer is shrunk to its size plus the number of reserved bytes.
If the current capacity is not larger than the size plus the reserved bytes, nothing happens.
If the CX_BUFFER_COPY_ON_WRITE or CX_BUFFER_COPY_ON_EXTEND flag is set, this function does nothing.
| buffer | the buffer |
| reserve | the number of bytes that shall remain reserved |
| int cxBufferTerminate | ( | CxBuffer * | buffer | ) |
Writes a terminating zero to a buffer at the current position.
If successful, also sets the size to the current position and shrinks the buffer.
The purpose of this function is to have the written data ready to be used as a C string with the buffer's size being the length of that string.
| buffer | the buffer to write to |
| size_t cxBufferWrite | ( | const void * | ptr, |
| size_t | size, | ||
| size_t | nitems, | ||
| CxBuffer * | buffer ) |
Writes data to a CxBuffer.
If auto-extension is enabled, the buffer's capacity is automatically increased when it is not large enough to hold all data. By default, the capacity grows indefinitely, unless limited with cxBufferMaximumCapacity(). When auto-extension fails, this function writes no data and returns zero.
The position of the buffer is moved alongside the written data.
| ptr | a pointer to the memory area containing the bytes to be written |
| size | the length of one element |
| nitems | the element count |
| buffer | the CxBuffer to write to |