WriteBuffer

Implements a simple write buffer.

Used by every function which needs to return strings or other information of unknown size.

Summary
WriteBufferImplements a simple write buffer.
CopyrightThis program is free software.
Files
C-kern/api/memory/wbuffer.hHeader file WriteBuffer.
C-kern/memory/wbuffer.cImplementation file WriteBuffer impl.
Types
struct wbuffer_tExport wbuffer_t.
struct wbuffer_itExport interface wbuffer_it.
struct memstream_tExport memstream_t.
Variables
g_wbuffer_cstringAdapt wbuffer_t to use cstring_t as buffer.
g_wbuffer_memblockAdapt wbuffer_t to use memblock_t as buffer.
g_wbuffer_staticAdapt wbuffer_t to a static buffer.
Functions
test
unittest_memory_wbufferTest object wbuffer_t.
wbuffer_itDefines implementation interface for wbuffer_t.
Variables
allocAllocate a new memory block of new_size bytes and return it in memstr.
shrinkFree all memory beyond the first new_size bytes.
sizeReturns number of used bytes.
wbuffer_tSupports construction of return values of unknown size.
nextPointer to next free memory location of the allocated memory.
endPoints to memory address one after the end address of allocated memory.
implPoints to wrapped object or a static allocated buffer.
iimplPointer to interface implementing memory allocation strategy.
lifetime
wbuffer_INIT_CSTRINGStatic initializer which wraps a cstring_t object into a wbuffer_t.
wbuffer_INIT_MEMBLOCKStatic initializer which wraps a memblock_t object into a wbuffer_t.
wbuffer_INIT_STATICStatic initializer which wraps static memory into a wbuffer_t.
wbuffer_INIT_OTHERStatic initializer to adapt wbuffer_t to own memory implementation object.
wbuffer_FREEStatic initializer for invalid wbuffer_t.
query
sizereserved_wbufferReturns the number of allocated bytes which are not in use.
size_wbufferReturns the number of appended bytes.
change
clear_wbufferRemoves all appended content from wbuffer.
shrink_wbufferRemoves the last size_wbuffer(wbuf)-newsize bytes from wbuf.
appendbytes_wbufferAppends buffer_size bytes of unitilaized memory to wbuf.
appendbyte_wbufferAppends 1 byte to the buffer.
appendcopy_wbufferAppends the first buffer_size bytes from buffer to wbuf.
inline implementation
wbuffer_t
appendbyte_wbufferImplements wbuffer_t.appendbyte_wbuffer.
appendbytes_wbufferImplements wbuffer_t.appendbytes_wbuffer.
clear_wbufferImplements wbuffer_t.clear_wbuffer.
shrink_wbufferImplements wbuffer_t.shrink_wbuffer.
sizereserved_wbufferImplements wbuffer_t.sizereserved_wbuffer.
size_wbufferImplements wbuffer_t.size_wbuffer.

Copyright

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.

Author

© 2013 Jörg Seebohn

Files

C-kern/api/memory/wbuffer.h

Header file WriteBuffer.

C-kern/memory/wbuffer.c

Implementation file WriteBuffer impl.

Types

struct wbuffer_t

typedef struct wbuffer_t wbuffer_t

Export wbuffer_t.

struct wbuffer_it

typedef struct wbuffer_it wbuffer_it

Export interface wbuffer_it.

struct memstream_t

typedef struct memstream_t memstream_t

Export memstream_t.

Variables

g_wbuffer_cstring

extern wbuffer_it g_wbuffer_cstring

Adapt wbuffer_t to use cstring_t as buffer.

g_wbuffer_memblock

extern wbuffer_it g_wbuffer_memblock

Adapt wbuffer_t to use memblock_t as buffer.

g_wbuffer_static

extern wbuffer_it g_wbuffer_static

Adapt wbuffer_t to a static buffer.

Functions

test

unittest_memory_wbuffer

int unittest_memory_wbuffer(void)

Test object wbuffer_t.

wbuffer_it

struct wbuffer_it

Defines implementation interface for wbuffer_t.  This allows wbuffer_t to adapt to different memory buffer objects.

Summary
Variables
allocAllocate a new memory block of new_size bytes and return it in memstr.
shrinkFree all memory beyond the first new_size bytes.
sizeReturns number of used bytes.

Variables

alloc

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.

shrink

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.

size

size_t (*size) (void * impl, const struct memstream_t * memstr)

Returns number of used bytes.  Parameter memstr contains the unused part of the last allocated memory block.

wbuffer_t

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.

Summary
nextPointer to next free memory location of the allocated memory.
endPoints to memory address one after the end address of allocated memory.
implPoints to wrapped object or a static allocated buffer.
iimplPointer to interface implementing memory allocation strategy.
lifetime
wbuffer_INIT_CSTRINGStatic initializer which wraps a cstring_t object into a wbuffer_t.
wbuffer_INIT_MEMBLOCKStatic initializer which wraps a memblock_t object into a wbuffer_t.
wbuffer_INIT_STATICStatic initializer which wraps static memory into a wbuffer_t.
wbuffer_INIT_OTHERStatic initializer to adapt wbuffer_t to own memory implementation object.
wbuffer_FREEStatic initializer for invalid wbuffer_t.
query
sizereserved_wbufferReturns the number of allocated bytes which are not in use.
size_wbufferReturns the number of appended bytes.
change
clear_wbufferRemoves all appended content from wbuffer.
shrink_wbufferRemoves the last size_wbuffer(wbuf)-newsize bytes from wbuf.
appendbytes_wbufferAppends buffer_size bytes of unitilaized memory to wbuf.
appendbyte_wbufferAppends 1 byte to the buffer.
appendcopy_wbufferAppends the first buffer_size bytes from buffer to wbuf.

next

uint8_t * next

Pointer to next free memory location of the allocated memory.

end

uint8_t * end

Points to memory address one after the end address of allocated memory.

impl

void * impl

Points to wrapped object or a static allocated buffer.

iimpl

const wbuffer_it * iimpl

Pointer to interface implementing memory allocation strategy.

lifetime

wbuffer_INIT_CSTRING

#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 cstring_t object into a wbuffer_t.

Parameter

cstringPointer to initialized cstring.

wbuffer_INIT_MEMBLOCK

#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.

Parameter

memblockPointer to initialized memblock_t.  It is allowed to set it to <memblock_FREE>.

wbuffer_INIT_STATIC

#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.

Parameter

buffer_sizeSize in bytes of static buffer.
bufferMemory address of static buffer.

wbuffer_INIT_OTHER

#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.

Parameter

buffer_sizeSize in bytes of already reserved memory.
bufferStart address of already reserved memory.
implPointer to implementation specific data.
iimpl_itPointer to interface wbuffer_it which implements memory allocation strategy.

wbuffer_FREE

#define wbuffer_FREE { 0, 0, 0, 0 }

Static initializer for invalid wbuffer_t.

query

sizereserved_wbuffer

size_t sizereserved_wbuffer(const wbuffer_t *wbuf)

Returns the number of allocated bytes which are not in use.

size_wbuffer

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.

change

clear_wbuffer

void clear_wbuffer(wbuffer_t *wbuf)

Removes all appended content from wbuffer.  The memory is not necessarily freed but it is marked as free.

shrink_wbuffer

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).

appendbytes_wbuffer

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.

appendbyte_wbuffer

int appendbyte_wbuffer(wbuffer_t *wbuf,
const uint8_t c)

Appends 1 byte to the buffer.

appendcopy_wbuffer

int appendcopy_wbuffer(wbuffer_t *wbuf,
size_t buffer_size,
const uint8_t *buffer)

Appends the first buffer_size bytes from buffer to wbuf. wbuf is grown if necessary.

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.appendbyte_wbuffer.

appendbytes_wbuffer

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.clear_wbuffer.

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.shrink_wbuffer.

sizereserved_wbuffer

#define sizereserved_wbuffer(
   wbuf
) ( __extension__ ({ const wbuffer_t * _wb2 = (wbuf) ; (size_t) (_wb2->end - _wb2->next) ; }))

Implements wbuffer_t.sizereserved_wbuffer.

size_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.

Implements a simple write buffer.
Implements WriteBuffer.
typedef struct wbuffer_t wbuffer_t
Export wbuffer_t.
struct wbuffer_t
Supports construction of return values of unknown size.
typedef struct wbuffer_it wbuffer_it
Export interface wbuffer_it.
struct wbuffer_it
Defines implementation interface for wbuffer_t.
typedef struct memstream_t memstream_t
Export memstream_t.
struct memstream_t
Wraps a memory block which points to start and end address.
extern wbuffer_it g_wbuffer_cstring
Adapt wbuffer_t to use cstring_t as buffer.
struct cstring_t
Dynamically growing C string with trailing ‘\0’ byte.
extern wbuffer_it g_wbuffer_memblock
Adapt wbuffer_t to use memblock_t as buffer.
struct memblock_t
Describes memory block.
extern wbuffer_it g_wbuffer_static
Adapt wbuffer_t to a static buffer.
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.
int (
   *shrink
) (void * impl, size_t new_size, /*inout*/struct memstream_t * memstr)
Free all memory beyond the first new_size bytes.
size_t (*size) (void * impl, const struct memstream_t * memstr)
Returns number of used bytes.
uint8_t * next
Pointer to next free memory location of the allocated memory.
uint8_t * end
Points to memory address one after the end address of allocated memory.
void * impl
Points to wrapped object or a static allocated buffer.
const wbuffer_it * iimpl
Pointer to interface implementing memory allocation strategy.
#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 cstring_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 a memblock_t object into a wbuffer_t.
#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.
#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.
#define wbuffer_FREE { 0, 0, 0, 0 }
Static initializer for invalid wbuffer_t.
size_t sizereserved_wbuffer(const wbuffer_t *wbuf)
Returns the number of allocated bytes which are not in use.
size_t size_wbuffer(const wbuffer_t *wbuf)
Returns the number of appended bytes.
void clear_wbuffer(wbuffer_t *wbuf)
Removes all appended content from wbuffer.
int shrink_wbuffer(wbuffer_t *wbuf,
size_t newsize)
Removes the last size_wbuffer(wbuf)-newsize bytes from wbuf.
int appendbytes_wbuffer(wbuffer_t *wbuf,
size_t buffer_size,
uint8_t **buffer)
Appends buffer_size bytes of unitilaized memory to wbuf.
int appendbyte_wbuffer(wbuffer_t *wbuf,
const uint8_t c)
Appends 1 byte to the buffer.
int appendcopy_wbuffer(wbuffer_t *wbuf,
size_t buffer_size,
const uint8_t *buffer)
Appends the first buffer_size bytes from buffer to wbuf.
#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.
#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.
#define RESIZE_MM(newsize,
mblock) mresize_mm(mm_maincontext(), newsize, mblock)
Resizes memory block.
Close