Implements a simple write buffer.
Used by every function which needs to return strings or other information of unknown size.
WriteBuffer | Implements a simple write buffer. |
Copyright | This program is free software. |
Files | |
C-kern/ | Header file WriteBuffer. |
C-kern/ | Implementation file WriteBuffer impl. |
Types | |
struct wbuffer_t | Export wbuffer_t. |
struct wbuffer_it | Export interface wbuffer_it. |
struct memstream_t | Export memstream_t. |
Variables | |
g_wbuffer_cstring | Adapt wbuffer_t to use cstring_t as buffer. |
g_wbuffer_memblock | Adapt wbuffer_t to use memblock_t as buffer. |
g_wbuffer_static | Adapt wbuffer_t to a static buffer. |
Functions | |
test | |
unittest_memory_wbuffer | Test object wbuffer_t. |
wbuffer_it | Defines implementation interface for wbuffer_t. |
Variables | |
alloc | Allocate a new memory block of new_size bytes and return it in memstr. |
shrink | Free all memory beyond the first new_size bytes. |
size | Returns number of used bytes. |
wbuffer_t | Supports construction of return values of unknown size. |
next | Pointer to next free memory location of the allocated memory. |
end | Points to memory address one after the end address of allocated memory. |
impl | Points to wrapped object or a static allocated buffer. |
iimpl | Pointer to interface implementing memory allocation strategy. |
lifetime | |
wbuffer_INIT_CSTRING | Static initializer which wraps a cstring_t object into a wbuffer_t. |
wbuffer_INIT_MEMBLOCK | Static initializer which wraps a memblock_t object into a wbuffer_t. |
wbuffer_INIT_STATIC | Static initializer which wraps static memory into a wbuffer_t. |
wbuffer_INIT_OTHER | Static initializer to adapt wbuffer_t to own memory implementation object. |
wbuffer_FREE | Static initializer for invalid wbuffer_t. |
query | |
sizereserved_wbuffer | Returns the number of allocated bytes which are not in use. |
size_wbuffer | Returns the number of appended bytes. |
change | |
clear_wbuffer | Removes all appended content from wbuffer. |
shrink_wbuffer | Removes the last size_wbuffer(wbuf)-newsize bytes from wbuf. |
appendbytes_wbuffer | Appends buffer_size bytes of unitilaized memory to wbuf. |
appendbyte_wbuffer | Appends 1 byte to the buffer. |
appendcopy_wbuffer | Appends the first buffer_size bytes from buffer to wbuf. |
inline implementation | |
wbuffer_t | |
appendbyte_wbuffer | Implements wbuffer_t.appendbyte_wbuffer. |
appendbytes_wbuffer | Implements wbuffer_t.appendbytes_wbuffer. |
clear_wbuffer | Implements wbuffer_t.clear_wbuffer. |
shrink_wbuffer | Implements wbuffer_t.shrink_wbuffer. |
sizereserved_wbuffer | Implements wbuffer_t.sizereserved_wbuffer. |
size_wbuffer | Implements wbuffer_t.size_wbuffer. |
This program is free software. You can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
© 2013 Jörg Seebohn
Header file WriteBuffer.
Implementation file WriteBuffer impl.
typedef struct wbuffer_t wbuffer_t
Export wbuffer_t.
typedef struct wbuffer_it wbuffer_it
Export interface wbuffer_it.
typedef struct memstream_t memstream_t
Export memstream_t.
extern wbuffer_it g_wbuffer_memblock
Adapt wbuffer_t to use memblock_t as buffer.
extern wbuffer_it g_wbuffer_static
Adapt wbuffer_t to a static buffer.
test | |
unittest_memory_wbuffer | Test object wbuffer_t. |
int unittest_memory_wbuffer( void )
Test object wbuffer_t.
int ( * alloc ) (void * impl, size_t new_size, /*inout*/struct memstream_t * memstr)
Allocate a new memory block of new_size bytes and return it in memstr. Before this function is called parameter memstr is set to the unused last part of the last allocated memory block: memstr->end is unchanged and (memstr->end - memstr->next) gives the number of unused bytes. This function serves two purposes. First it marks the last allocated block used and remembers that all bytes from [memstr->next...memstr->end-1] are not used. Second it allocates a new block of at least new_size bytes in returns it in memstr.
int ( * shrink ) (void * impl, size_t new_size, /*inout*/struct memstream_t * memstr)
Free all memory beyond the first new_size bytes. Return in memstr the start address of the free memory after the first used new_size bytes. Unused memory blocks could be freed or kept in cache. Parameter memstr is set to the unused part of the last allocated memory block before this function is called. The function should return EINVAL in case new_size is bigger than the return value of size.
struct wbuffer_t
Supports construction of return values of unknown size. The data is stored in an object of type cstring_t, memblock_t or static allocated memory.
Use wbuffer_INIT_CSTRING, wbuffer_INIT_MEMBLOCK or wbuffer_INIT_STATIC to initialize a wbuffer_t. After initialization of wbuffer_t you are not allowed to change the wrapped object until after the result is written into the buffer. wbuffer_t caches some values so if you change cstring_t or a memblock_t after having it wrapped into a wbuffer_t the behaviour is undefined.
The size of the contained value is only stored in wbuffer_t. The wrapped object is not truncated to fit the written data. You have to call <truncate_cstring>
wbuffer_t does not allocate memory for itself so you do not need to free an initialized object. But you have to free the wrapped object.
next | Pointer to next free memory location of the allocated memory. |
end | Points to memory address one after the end address of allocated memory. |
impl | Points to wrapped object or a static allocated buffer. |
iimpl | Pointer to interface implementing memory allocation strategy. |
lifetime | |
wbuffer_INIT_CSTRING | Static initializer which wraps a cstring_t object into a wbuffer_t. |
wbuffer_INIT_MEMBLOCK | Static initializer which wraps a memblock_t object into a wbuffer_t. |
wbuffer_INIT_STATIC | Static initializer which wraps static memory into a wbuffer_t. |
wbuffer_INIT_OTHER | Static initializer to adapt wbuffer_t to own memory implementation object. |
wbuffer_FREE | Static initializer for invalid wbuffer_t. |
query | |
sizereserved_wbuffer | Returns the number of allocated bytes which are not in use. |
size_wbuffer | Returns the number of appended bytes. |
change | |
clear_wbuffer | Removes all appended content from wbuffer. |
shrink_wbuffer | Removes the last size_wbuffer(wbuf)-newsize bytes from wbuf. |
appendbytes_wbuffer | Appends buffer_size bytes of unitilaized memory to wbuf. |
appendbyte_wbuffer | Appends 1 byte to the buffer. |
appendcopy_wbuffer | Appends the first buffer_size bytes from buffer to wbuf. |
#define wbuffer_INIT_MEMBLOCK( memblock ) wbuffer_INIT_OTHER(size_memblock(memblock), addr_memblock(memblock), memblock, &g_wbuffer_memblock)
Static initializer which wraps a memblock_t object into a wbuffer_t. If the memory is not big enough RESIZE_MM is called to resize it.
memblock | Pointer to initialized memblock_t. It is allowed to set it to <memblock_FREE>. |
#define wbuffer_INIT_STATIC( buffer_size, buffer ) wbuffer_INIT_OTHER(buffer_size, buffer, buffer, &g_wbuffer_static)
Static initializer which wraps static memory into a wbuffer_t. Reserving additional memory beyond buffer_size always results in ENOMEM.
buffer_size | Size in bytes of static buffer. |
buffer | Memory address of static buffer. |
#define wbuffer_INIT_OTHER( buffer_size, buffer, impl, iimpl_it ) { (buffer), (buffer) + (buffer_size), (impl), (iimpl_it) }
Static initializer to adapt wbuffer_t to own memory implementation object.
buffer_size | Size in bytes of already reserved memory. |
buffer | Start address of already reserved memory. |
impl | Pointer to implementation specific data. |
iimpl_it | Pointer to interface wbuffer_it which implements memory allocation strategy. |
#define wbuffer_FREE { 0, 0, 0, 0 }
Static initializer for invalid wbuffer_t.
size_t size_wbuffer( const wbuffer_t * wbuf )
Returns the number of appended bytes. A returned value of 0 means no data is returned. Always use this function to determine the number of appended bytes. The size of the wrapped object is not correct only the buffer of the wrapped object is used.
int shrink_wbuffer( wbuffer_t * wbuf, size_t newsize )
Removes the last size_wbuffer(wbuf)-newsize bytes from wbuf. The memory is not necessarily freed but it is marked as free. Use this function if an error has occurred but the return parameter of type wbuffer_t has been partially filled with content. The error EINVAL is returned and nothing is done in case newsize is bigger than size_wbuffer(wbuf).
int appendbytes_wbuffer( wbuffer_t * wbuf, size_t buffer_size, uint8_t ** buffer )
Appends buffer_size bytes of unitilaized memory to wbuf. A pointer to the uninitialized memory block is returned in buffer. The returned pointer in buffer is valid as long as no other function is called on wbuf.
wbuffer_t | |
appendbyte_wbuffer | Implements wbuffer_t.appendbyte_wbuffer. |
appendbytes_wbuffer | Implements wbuffer_t.appendbytes_wbuffer. |
clear_wbuffer | Implements wbuffer_t.clear_wbuffer. |
shrink_wbuffer | Implements wbuffer_t.shrink_wbuffer. |
sizereserved_wbuffer | Implements wbuffer_t.sizereserved_wbuffer. |
size_wbuffer | Implements wbuffer_t.size_wbuffer. |
#define appendbyte_wbuffer( wbuf, c ) ( __extension__ ({ int _err = 0 ; wbuffer_t * _wb = (wbuf) ; if ( 0 != sizereserved_wbuffer(_wb) || (0 == (_err = _wb->iimpl-> alloc(_wb->impl, 1, (struct memstream_t*)_wb)))) { *(_wb->next++) = c ; } _err ; }))
Implements wbuffer_t.appendbyte_wbuffer.
Implements wbuffer_t.appendbytes_wbuffer.
#define clear_wbuffer( wbuf ) do { wbuffer_t * _wb = (wbuf) ; _wb->iimpl->shrink(_wb->impl, 0, (struct memstream_t*)_wb); } while (0)
Implements wbuffer_t.clear_wbuffer.
#define shrink_wbuffer( wbuf, newsize ) ( __extension__ ({ wbuffer_t * _wb = (wbuf) ; _wb->iimpl->shrink(_wb->impl, (newsize), (struct memstream_t*)_wb); }))
Implements wbuffer_t.shrink_wbuffer.
#define sizereserved_wbuffer( wbuf ) ( __extension__ ({ const wbuffer_t * _wb2 = (wbuf) ; (size_t) (_wb2->end - _wb2->next) ; }))
Implements wbuffer_t.sizereserved_wbuffer.
#define size_wbuffer( wbuf ) ( __extension__ ({ const wbuffer_t * _wb = (wbuf) ; _wb->iimpl->size(_wb->impl, (const struct memstream_t*)_wb) ; }))
Implements wbuffer_t.size_wbuffer.
Export wbuffer_t.
typedef struct wbuffer_t wbuffer_t
Supports construction of return values of unknown size.
struct wbuffer_t
Export interface wbuffer_it.
typedef struct wbuffer_it wbuffer_it
Defines implementation interface for wbuffer_t.
struct wbuffer_it
Export memstream_t.
typedef struct memstream_t memstream_t
Wraps a memory block which points to start and end address.
struct memstream_t
Adapt wbuffer_t to use cstring_t as buffer.
extern wbuffer_it g_wbuffer_cstring
Dynamically growing C string with trailing ‘\0’ byte.
struct cstring_t
Adapt wbuffer_t to use memblock_t as buffer.
extern wbuffer_it g_wbuffer_memblock
Describes memory block.
struct memblock_t
Adapt wbuffer_t to a static buffer.
extern wbuffer_it g_wbuffer_static
Test object wbuffer_t.
int unittest_memory_wbuffer( void )
Allocate a new memory block of new_size bytes and return it in memstr.
int ( * alloc ) (void * impl, size_t new_size, /*inout*/struct memstream_t * memstr)
Free all memory beyond the first new_size bytes.
int ( * shrink ) (void * impl, size_t new_size, /*inout*/struct memstream_t * memstr)
Returns number of used bytes.
size_t ( * size ) (void * impl, const struct memstream_t * memstr)
Pointer to next free memory location of the allocated memory.
uint8_t * next
Points to memory address one after the end address of allocated memory.
uint8_t * end
Points to wrapped object or a static allocated buffer.
void * impl
Pointer to interface implementing memory allocation strategy.
const wbuffer_it * iimpl
Static initializer which wraps a cstring_t object into a wbuffer_t.
#define wbuffer_INIT_CSTRING( cstring ) wbuffer_INIT_OTHER(allocatedsize_cstring(cstring), (uint8_t*)str_cstring(cstring), cstring, &g_wbuffer_cstring)
Static initializer which wraps a memblock_t object into a wbuffer_t.
#define wbuffer_INIT_MEMBLOCK( memblock ) wbuffer_INIT_OTHER(size_memblock(memblock), addr_memblock(memblock), memblock, &g_wbuffer_memblock)
Static initializer which wraps static memory into a wbuffer_t.
#define wbuffer_INIT_STATIC( buffer_size, buffer ) wbuffer_INIT_OTHER(buffer_size, buffer, buffer, &g_wbuffer_static)
Static initializer to adapt wbuffer_t to own memory implementation object.
#define wbuffer_INIT_OTHER( buffer_size, buffer, impl, iimpl_it ) { (buffer), (buffer) + (buffer_size), (impl), (iimpl_it) }
Static initializer for invalid wbuffer_t.
#define wbuffer_FREE { 0, 0, 0, 0 }
Returns the number of allocated bytes which are not in use.
size_t sizereserved_wbuffer( const wbuffer_t * wbuf )
Returns the number of appended bytes.
size_t size_wbuffer( const wbuffer_t * wbuf )
Removes all appended content from wbuffer.
void clear_wbuffer( wbuffer_t * wbuf )
Removes the last size_wbuffer(wbuf)-newsize bytes from wbuf.
int shrink_wbuffer( wbuffer_t * wbuf, size_t newsize )
Appends buffer_size bytes of unitilaized memory to wbuf.
int appendbytes_wbuffer( wbuffer_t * wbuf, size_t buffer_size, uint8_t ** buffer )
Appends 1 byte to the buffer.
int appendbyte_wbuffer( wbuffer_t * wbuf, const uint8_t c )
Appends the first buffer_size bytes from buffer to wbuf.
int appendcopy_wbuffer( wbuffer_t * wbuf, size_t buffer_size, const uint8_t * buffer )
Implements wbuffer_t.appendbyte_wbuffer.
#define appendbyte_wbuffer( wbuf, c ) ( __extension__ ({ int _err = 0 ; wbuffer_t * _wb = (wbuf) ; if ( 0 != sizereserved_wbuffer(_wb) || (0 == (_err = _wb->iimpl-> alloc(_wb->impl, 1, (struct memstream_t*)_wb)))) { *(_wb->next++) = c ; } _err ; }))
Implements wbuffer_t.clear_wbuffer.
#define clear_wbuffer( wbuf ) do { wbuffer_t * _wb = (wbuf) ; _wb->iimpl->shrink(_wb->impl, 0, (struct memstream_t*)_wb); } while (0)
Implements wbuffer_t.shrink_wbuffer.
#define shrink_wbuffer( wbuf, newsize ) ( __extension__ ({ wbuffer_t * _wb = (wbuf) ; _wb->iimpl->shrink(_wb->impl, (newsize), (struct memstream_t*)_wb); }))
Implements wbuffer_t.sizereserved_wbuffer.
#define sizereserved_wbuffer( wbuf ) ( __extension__ ({ const wbuffer_t * _wb2 = (wbuf) ; (size_t) (_wb2->end - _wb2->next) ; }))
Implements wbuffer_t.size_wbuffer.
#define size_wbuffer( wbuf ) ( __extension__ ({ const wbuffer_t * _wb = (wbuf) ; _wb->iimpl->size(_wb->impl, (const struct memstream_t*)_wb) ; }))
Resizes memory block.
#define RESIZE_MM( newsize, mblock ) mresize_mm(mm_maincontext(), newsize, mblock)