Flexible buffer management, idea from openssh/buffer.c. More...
Functions | |
Buffer * | buffer_new (size_t blocksize, char *name) |
Create a new buffer. More... | |
Buffer * | buffer_new_str (char *name) |
Create a new string buffer. More... | |
Buffer * | buffer_new_buf (char *name, void *data, size_t datasize) |
Create a new buffer from existing data. More... | |
void | buffer_free (Buffer *b) |
Clears and frees the Buffer. More... | |
void | buffer_clear (Buffer *b) |
Clears the Buffer. More... | |
void | buffer_rewind (Buffer *b) |
Put read offset back to start. More... | |
void | buffer_add (Buffer *b, const void *data, size_t len) |
Add data to the buffer. More... | |
void | buffer_add_buf (Buffer *dst, Buffer *src) |
Add data to the buffer. More... | |
void | buffer_add_str (Buffer *b, const char *fmt,...) |
Add a formated string to the buffer. More... | |
void | buffer_add_hex (Buffer *b, void *data, size_t len) |
Add data as hex string to the buffer. More... | |
int | buffer_done (Buffer *b) |
Tell if there are no more bytes to read. More... | |
size_t | buffer_get_chunk (Buffer *b, void *buf, size_t len) |
Read some chunk of data from the Buffer. More... | |
size_t | buffer_get_chunk_tobuf (Buffer *b, Buffer *dst, size_t len) |
Read some chunk of data from the Buffer and add to another Buffer. More... | |
byte * | buffer_get (Buffer *b) |
Read the whole Buffer content. More... | |
char * | buffer_get_str (Buffer *b) |
Read the whole Buffer content as string. More... | |
byte * | buffer_get_remainder (Buffer *b) |
Read the remaining data after current read offset. More... | |
size_t | buffer_extract (Buffer *b, void *buf, size_t offset, size_t len) |
Read some data inside the Buffer. More... | |
size_t | buffer_fwd_offset (Buffer *b, size_t fwdby) |
Forward read offset of given buffer. More... | |
void | buffer_dump (const Buffer *b) |
Dump the Buffer contents to stderr in hex form. More... | |
void | buffer_info (const Buffer *b) |
Print Buffer counters to stderr. More... | |
size_t | buffer_size (const Buffer *b) |
Tell how much data there is in the buffer available. More... | |
size_t | buffer_left (const Buffer *b) |
Tell how much data is left to read in the Buffer. More... | |
uint8_t | buffer_get8 (Buffer *b) |
Read 1 byte (8 bit) number from a Buffer. More... | |
uint16_t | buffer_get16 (Buffer *b) |
Read 2 bytes (16 bit) number from a Buffer. More... | |
uint32_t | buffer_get32 (Buffer *b) |
Read 4 byte (32 bit) number from a Buffer. More... | |
uint64_t | buffer_get64 (Buffer *b) |
Read 8 byte (64 bit) from a Buffer. More... | |
uint16_t | buffer_get16na (Buffer *b) |
Read 2 bytes (16 bit) number from a Buffer, converted to host endian. More... | |
uint32_t | buffer_get32na (Buffer *b) |
Read 4 byte (32 bit) number from a Buffer, converted to host endian. More... | |
uint64_t | buffer_get64na (Buffer *b) |
Read 8 byte (64 bit) from a Buffer, converted to host endian. More... | |
uint8_t | buffer_last8 (Buffer *b) |
Read the last 1 byte (8 bit) number from a Buffer. More... | |
uint16_t | buffer_last16 (Buffer *b) |
Read the last 2 byte (16 bit) number from a Buffer. More... | |
uint32_t | buffer_last32 (Buffer *b) |
Read the last 4 byte (32 bit) number from a Buffer. More... | |
uint64_t | buffer_last64 (Buffer *b) |
Read the last 8 byte (64 bit) number from a Buffer. More... | |
size_t | buffer_fd_read (Buffer *b, FILE *in, size_t len) |
Read data from a file directly into a Buffer. More... | |
void | buffer_add8 (Buffer *b, uint8_t v) |
Write a 1 byte (8 bit) number in binary form into the buffer. More... | |
void | buffer_add16 (Buffer *b, uint16_t v) |
Write a 2 byte (16 bit) number in binary form into the buffer. More... | |
void | buffer_add32 (Buffer *b, uint32_t v) |
Write a 4 byte (32 bit) number in binary form into the buffer. More... | |
void | buffer_add64 (Buffer *b, uint64_t v) |
Write a 8 byte (64 bit) number in binary form into the buffer. More... | |
void | buffer_add16be (Buffer *b, uint16_t v) |
Write a 2 byte (16 bit) number in binary form into the buffer, converted to big endian. More... | |
void | buffer_add32be (Buffer *b, uint32_t v) |
Write a 4 byte (32 bit) number in binary form into the buffer, converted to big endian. More... | |
void | buffer_add64be (Buffer *b, uint64_t v) |
Write a 8 byte (64 bit) number in binary form into the buffer, converted to big endian. More... | |
Flexible buffer management, idea from openssh/buffer.c.
This class allows us to dissect buffers into parts at will whithout the hassle of boundary checking in each and every line. Therefore it is more secure, since this system wraps all this stuff from us, so in case we're attemt to overflow a buffer or the like, the buffer functions will catch this, warn us and die.
void buffer_add | ( | Buffer * | b, |
const void * | data, | ||
size_t | len | ||
) |
Add data to the buffer.
Adds data of the size len to the buffer and resizes the buffer, if neccessary. The write position ('end' field) will be updated accordingly.
Data will be copied, you can free() the given pointer after copying..
[in] | b | The Buffer object. |
[out] | data | Arbitrary data to add to the Buffer. |
[in] | len | The size of the data to add in Bytes. |
void buffer_add16 | ( | Buffer * | b, |
uint16_t | v | ||
) |
Write a 2 byte (16 bit) number in binary form into the buffer.
[out] | b | The Buffer object to write to. |
[in] | v | The uint16_t to write to the buffer. |
void buffer_add16be | ( | Buffer * | b, |
uint16_t | v | ||
) |
Write a 2 byte (16 bit) number in binary form into the buffer, converted to big endian.
[out] | b | The Buffer object to write to. |
[in] | v | The uint16_t to write to the buffer. |
void buffer_add32 | ( | Buffer * | b, |
uint32_t | v | ||
) |
Write a 4 byte (32 bit) number in binary form into the buffer.
[out] | b | The Buffer object to write to. |
[in] | v | The uint32_t to write to the buffer. |
void buffer_add32be | ( | Buffer * | b, |
uint32_t | v | ||
) |
Write a 4 byte (32 bit) number in binary form into the buffer, converted to big endian.
[out] | b | The Buffer object to write to. |
[in] | v | The uint32_t to write to the buffer. |
void buffer_add64 | ( | Buffer * | b, |
uint64_t | v | ||
) |
Write a 8 byte (64 bit) number in binary form into the buffer.
[out] | b | The Buffer object to write to. |
[in] | v | The uint64_t to write to the buffer. |
void buffer_add64be | ( | Buffer * | b, |
uint64_t | v | ||
) |
Write a 8 byte (64 bit) number in binary form into the buffer, converted to big endian.
[out] | b | The Buffer object to write to. |
[in] | v | The uint64_t to write to the buffer. |
void buffer_add8 | ( | Buffer * | b, |
uint8_t | v | ||
) |
Write a 1 byte (8 bit) number in binary form into the buffer.
[out] | b | The Buffer object to write to. |
[in] | v | The uint8_t to write to the buffer. |
Add data to the buffer.
Adds data from the given Buffer src to the buffer and resizes the buffer, if neccessary. The write position ('end' field) will be updated accordingly.
Data will be copied, you can buffer_free() the given src Buffer after the copying.
[out] | dst | The destination Buffer object to copy data into. |
[in] | src | The source Buffer object to copy data from. |
void buffer_add_hex | ( | Buffer * | b, |
void * | data, | ||
size_t | len | ||
) |
Add data as hex string to the buffer.
Adds data of the size len to the buffer and resizes the buffer, if neccessary. The write position ('end' field) will be updated accordingly. Each byte will be put in its HEX form into the buffer (%02x).
Data will be copied, you can free() the given pointer after copying..
[in] | b | The Buffer object. |
[in] | data | Arbitrary data to add as hex into the Buffer. |
[in] | len | The size of the data to add in Bytes. |
void buffer_add_str | ( | Buffer * | b, |
const char * | fmt, | ||
... | |||
) |
Add a formated string to the buffer.
Use printf() like syntax to add a formatted string to the buffer. Refer to the documentation of printf() for details.
Data will be copied, you can free() the given format string and params after copying.
Example:
[in] | b | The Buffer object. |
[in] | fmt | The printf() compatible format description. |
[in] | ... | A variable number of arguments for the format string. |
void buffer_clear | ( | Buffer * | b | ) |
Clears the Buffer.
This clears the buffer by filling it with zeroes and resetting all counters. Memory will not be free'd. Called from buffer_free() before free'ing memory.
[in] | b | The Buffer object. |
int buffer_done | ( | Buffer * | b | ) |
Tell if there are no more bytes to read.
This functions tells if the EOF of the buffer is reached during read operations (no more data to read left).
[in] | b | The Buffer object. |
void buffer_dump | ( | const Buffer * | b | ) |
Dump the Buffer contents to stderr in hex form.
[in] | b | The Buffer object to dump. |
size_t buffer_extract | ( | Buffer * | b, |
void * | buf, | ||
size_t | offset, | ||
size_t | len | ||
) |
Read some data inside the Buffer.
Same as buffer_get() but fetch some data chunk from somewhere in the middle of the buffer.
The returned pointer has to be allocated by the caller to at least a size of len bytes.
The read offset will be left untouched by this function.
Example: suppose you've got a buffer with the following content:
Then:
[in] | b | The Buffer object to read from. |
[out] | buf | The buffer to copy data to. |
[in] | offset | Where to start copying. |
[in] | len | How mush data to copy. |
size_t buffer_fd_read | ( | Buffer * | b, |
FILE * | in, | ||
size_t | len | ||
) |
Read data from a file directly into a Buffer.
This function reads in len bytes from the FILE stream 'in' into the Buffer. The file must already be opened by the caller.
[in,out] | b | The Buffer object to read from. |
[in] | in | The FILE stream to read from. |
[in] | len | The number of bytes to read. |
void buffer_free | ( | Buffer * | b | ) |
Clears and frees the Buffer.
This clears the buffer by filling it with zeroes and frees any allocated memory, including the Buffer object itself. Use this function instead of directly calling free(Buffer).
[in] | b | The Buffer object. |
size_t buffer_fwd_offset | ( | Buffer * | b, |
size_t | fwdby | ||
) |
Forward read offset of given buffer.
Use to ignore a couple of bytes.
[in] | b | The Buffer object to read from. |
[in] | fwdby | Bytes to forward read offset. |
byte* buffer_get | ( | Buffer * | b | ) |
Read the whole Buffer content.
This function returns the whole buffer contents as a pointer to the internal data member (Buffer->buf). The returned pointer is allocated and filled with data up to buffer_size(Buffer), however, the allocated memory might be more than size, in fact it will be a multitude of Buffer-blocksize.
Don't free() the pointer directly, use buffer_free() always.
[in] | b | The Buffer object to read from. |
uint16_t buffer_get16 | ( | Buffer * | b | ) |
Read 2 bytes (16 bit) number from a Buffer.
[in] | b | The Buffer object to read from. |
uint16_t buffer_get16na | ( | Buffer * | b | ) |
Read 2 bytes (16 bit) number from a Buffer, converted to host endian.
[in] | b | The Buffer object to read from. |
uint32_t buffer_get32 | ( | Buffer * | b | ) |
Read 4 byte (32 bit) number from a Buffer.
[in] | b | The Buffer object to read from. |
uint32_t buffer_get32na | ( | Buffer * | b | ) |
Read 4 byte (32 bit) number from a Buffer, converted to host endian.
[in] | b | The Buffer object to read from. |
uint64_t buffer_get64 | ( | Buffer * | b | ) |
Read 8 byte (64 bit) from a Buffer.
[in] | b | The Buffer object to read from. |
uint64_t buffer_get64na | ( | Buffer * | b | ) |
Read 8 byte (64 bit) from a Buffer, converted to host endian.
[in] | b | The Buffer object to read from. |
uint8_t buffer_get8 | ( | Buffer * | b | ) |
Read 1 byte (8 bit) number from a Buffer.
[in] | b | The Buffer object to read from. |
size_t buffer_get_chunk | ( | Buffer * | b, |
void * | buf, | ||
size_t | len | ||
) |
Read some chunk of data from the Buffer.
Read some chunk of data from the Buffer, starting from current read offset til len.
Example: suppose you've got a buffer with the following content:
Then the following code would:
In order to catch buffer overflow, check the return value, which will be 0 in case of errors. See also: fatals_ifany(), buffer_done() and buffer_left().
[in] | b | The Buffer object to read from. |
[out] | buf | The destination pointer where the data will be copied to. This pointer must be allocated by the caller properly and it must have at least a size of len. |
[in] | len | The number of bytes to read from the Buffer. |
Read some chunk of data from the Buffer and add to another Buffer.
Works identical to buffer_get_chunk() but copies the requested chunk directly into the Buffer dst, which will be resized properly if needed.
[in] | b | The Buffer object to read from. |
[out] | dst | The Buffer object to write to. |
[in] | len | The number of bytes to read from the Buffer. |
byte* buffer_get_remainder | ( | Buffer * | b | ) |
Read the remaining data after current read offset.
Fetch whatever is left in the buffer. This works like buffer_get() but instead doesn't return everything, but only the part of the buffer, which follows after the current read offset.
The returned pointer will be allocated by buffer_get_remainder() with a size of buffer_left(). It's up to the caller to free() the returned pointer later on.
Example: suppose you've got a buffer with the following content:
Then:
[in] | b | The Buffer object to read from. |
char* buffer_get_str | ( | Buffer * | b | ) |
Read the whole Buffer content as string.
Access the Buffer content as string (char *).
The returned pointer is allocated and filled with data up to buffer_size(Buffer), however, the allocated memory might be more than size, in fact it will be a multitude of Buffer-blocksize.
The byte after buffer_size(Buffer) will be a \0.
Don't free() the pointer directly, use buffer_free() always.
Sample usage:
[in] | b | The Buffer object to read from. |
void buffer_info | ( | const Buffer * | b | ) |
Print Buffer counters to stderr.
[in] | b | The Buffer object to print infos about. |
uint16_t buffer_last16 | ( | Buffer * | b | ) |
Read the last 2 byte (16 bit) number from a Buffer.
Doesn't increment offset.
[in] | b | The Buffer object to read from. |
uint32_t buffer_last32 | ( | Buffer * | b | ) |
Read the last 4 byte (32 bit) number from a Buffer.
Doesn't increment offset.
[in] | b | The Buffer object to read from. |
uint64_t buffer_last64 | ( | Buffer * | b | ) |
Read the last 8 byte (64 bit) number from a Buffer.
Doesn't increment offset.
[in] | b | The Buffer object to read from. |
uint8_t buffer_last8 | ( | Buffer * | b | ) |
Read the last 1 byte (8 bit) number from a Buffer.
Doesn't increment offset.
[in] | b | The Buffer object to read from. |
size_t buffer_left | ( | const Buffer * | b | ) |
Tell how much data is left to read in the Buffer.
Use this function to check if it's ok to read more bytes from to buffer to avoid buffer overflows.
Example: suppose you've got a buffer with the following content:
Then:
[in] | b | The Buffer object to get the size from. |
Buffer* buffer_new | ( | size_t | blocksize, |
char * | name | ||
) |
Create a new buffer.
Create a new buffer, initially alloc'd to blocksize and zero-filled.
[in] | blocksize | Initial blocksize. The smaller the more often the buffer will be resized. Choose with care. |
[in] | name | A name for the Buffer. Just used for debugging purposes or in error messages. |
Buffer* buffer_new_buf | ( | char * | name, |
void * | data, | ||
size_t | datasize | ||
) |
Create a new buffer from existing data.
Create a new buffer, but don't allocate memory nor copy data. Instead the provided data pointer will be used as internal storage directly.
This kind of buffer can be used to put the Buffer API into use with existing data from other sources. In most cases you'll use it for reading. However, please be aware, that it can be used for writing as well and in this case the data pointer maybe resized (by calling realloc()).
When calling buffer_free() on this Buffer, the memory pointed to by the given data pointer will not be free'd and remains accessible. It's the responsibility of the caller to do so.
Example using mmap(2):
[in] | name | A name for the Buffer. Just used for debugging purposes or in error messages. |
[in] | data | The data pointer to use by the buffer. |
[in] | datasize | The size of the data. |
Buffer* buffer_new_str | ( | char * | name | ) |
Create a new string buffer.
Create a new buffer, initially alloc'd to a blocksize of 32 bytes and zero-filled. The buffer will be a string buffer. See buffer_get_str().
[in] | name | A name for the Buffer. Just used for debugging purposes or in error messages. |
void buffer_rewind | ( | Buffer * | b | ) |
Put read offset back to start.
This function sets the read offset counter back to 0 (start of the buffer).
[in] | b | The Buffer object. |
size_t buffer_size | ( | const Buffer * | b | ) |
Tell how much data there is in the buffer available.
This function returns the number of bytes stored in the buffer so far. Please note, that the actual allocation might be bigger, because we always allocate memory blockwise.
[in] | b | The Buffer object to get the size from. |