The FreeRADIUS server
$Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
|
A generic data buffer structure for encoding and decoding. More...
#include <errno.h>
#include <freeradius-devel/missing.h>
#include <freeradius-devel/util/debug.h>
#include <freeradius-devel/util/nbo.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
Go to the source code of this file.
Data Structures | |
struct | fr_dbuff_thread_local_t |
Structure to encapsulate a thread local dbuff information. More... | |
Macros | |
#define | FR_DBUFF_ADV_PARENT_CURRENT 0x01 |
Advance current position of parent. More... | |
#define | FR_DBUFF_ADV_PARENT_END 0x02 |
Advance end pointer of parent. More... | |
#define | FR_DBUFF_RETURN(_func, ...) |
Generic wrapper macro to return if there's insufficient memory to satisfy the request on the dbuff. More... | |
Typedefs | |
typedef size_t(* | fr_dbuff_extend_t) (fr_dbuff_t *dbuff, size_t req_extension) |
dbuff extension callback More... | |
typedef struct fr_dbuff_marker_s | fr_dbuff_marker_t |
A position marker associated with a dbuff. More... | |
typedef struct fr_dbuff_s | fr_dbuff_t |
A dbuff. More... | |
Initialisers | |
static int | _dbuff_thread_local_free (void *dbtl) |
size_t | _fr_dbuff_extend_fd (fr_dbuff_t *dbuff, size_t extension) |
Refresh the buffer with more data from the file. More... | |
size_t | _fr_dbuff_extend_talloc (fr_dbuff_t *dbuff, size_t extension) |
Reallocate the current buffer. More... | |
#define | FR_DBUFF(_dbuff_or_marker) _FR_DBUFF(_dbuff_or_marker, fr_dbuff_current(_dbuff_or_marker), 0x00) |
Create a new dbuff pointing to the same underlying buffer. More... | |
#define | FR_DBUFF_ABS(_dbuff_or_marker) _FR_DBUFF(_dbuff_or_marker, fr_dbuff_start(_dbuff_or_marker), 0x00) |
Create a new dbuff pointing to the same underlying buffer. More... | |
#define | FR_DBUFF_BIND_CURRENT(_dbuff_or_marker) _FR_DBUFF(_dbuff_or_marker, fr_dbuff_current(_dbuff_or_marker), FR_DBUFF_ADV_PARENT_CURRENT) |
Create a new dbuff pointing to the same underlying buffer. More... | |
#define | FR_DBUFF_BIND_CURRENT_ABS(_dbuff_or_marker) FR_DBUFF_ABS(_dbuff_or_marker, fr_dbuff_start(_dbuff_or_marker), FR_DBUFF_ADV_PARENT_CURRENT) |
Create a new dbuff pointing to the same underlying buffer. More... | |
#define | FR_DBUFF_BIND_END_ABS(_dbuff_or_marker) _FR_DBUFF(_dbuff_or_marker, fr_dbuff_start(_dbuff_or_marker), FR_DBUFF_ADV_PARENT_END) |
Create a new dbuff pointing to the same underlying buffer. More... | |
static void | fr_dbuff_free_talloc (fr_dbuff_t *dbuff) |
Free the talloc buffer associated with a dbuff. More... | |
#define | fr_dbuff_init(_out, _start, _len_or_end) |
Initialise an dbuff for encoding or decoding. More... | |
#define | FR_DBUFF_INIT(_out, _start, _len_or_end) |
static fr_dbuff_t * | fr_dbuff_init_fd (fr_dbuff_t *dbuff, fr_dbuff_uctx_fd_t *fctx, uint8_t *buff, size_t len, int fd, size_t max) |
Initialise a special dbuff which automatically reads in more data as the buffer is exhausted. More... | |
static fr_dbuff_t * | fr_dbuff_init_talloc (TALLOC_CTX *ctx, fr_dbuff_t *dbuff, fr_dbuff_uctx_talloc_t *tctx, size_t init, size_t max) |
Initialise a special dbuff which automatically extends as additional data is written. More... | |
#define | FR_DBUFF_MAX(_dbuff_or_marker, _max) _FR_DBUFF_MAX(_dbuff_or_marker, _max, 0x00) |
Limit the maximum number of bytes available in the dbuff when passing it to another function. More... | |
#define | FR_DBUFF_MAX_BIND_CURRENT(_dbuff_or_marker, _max) _FR_DBUFF_MAX(_dbuff_or_marker, _max, FR_DBUFF_ADV_PARENT_CURRENT) |
Limit the maximum number of bytes available in the dbuff when passing it to another function. More... | |
int | fr_dbuff_reset_talloc (fr_dbuff_t *dbuff) |
Reset a talloced buffer to its initial length, clearing any data stored. More... | |
#define | FR_DBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max) |
Create a function local and thread local extensible dbuff. More... | |
#define | FR_DBUFF_TMP(_start, _len_or_end) |
Creates a compound literal to pass into functions which accept a dbuff. More... | |
int | fr_dbuff_trim_talloc (fr_dbuff_t *dbuff, size_t len) |
Trim a talloced dbuff to the minimum length required to represent the contained string. More... | |
Extension requests | |
These functions/macros may be used to request that the underlying buffer is either extended to accommodate more data, or that data is shifted out of the buffer, and that the buffer is refilled. | |
#define | fr_dbuff_extend(_dbuff) fr_dbuff_extend_lowat(NULL, _dbuff, 1) |
Extend if no space remains. More... | |
#define | fr_dbuff_extend_lowat(_status, _dbuff_or_marker, _lowat) |
Extend if we're below _lowat. More... | |
#define | FR_DBUFF_EXTEND_LOWAT_OR_RETURN(_dbuff_or_marker, _lowat) |
Extend if we're below _lowat and return if we can't extend above _lowat. More... | |
enum | fr_dbuff_extend_status_t { FR_DBUFF_NOT_EXTENDABLE = 0x00 , FR_DBUFF_EXTENDABLE = FR_DBUFF_FLAG_EXTENDABLE , FR_DBUFF_EXTENDABLE_EXTENDED = FR_DBUFF_FLAG_EXTENDABLE | FR_DBUFF_FLAG_EXTENDED , FR_DBUFF_EXTENDED = FR_DBUFF_FLAG_EXTENDED } |
Whether the buffer is currently extendable and whether it was extended. More... | |
#define | FR_DBUFF_FLAG_EXTENDABLE 0x01 |
Flag indicating a dbuff is extendable. More... | |
#define | FR_DBUFF_FLAG_EXTENDED 0x02 |
Flag indicating that during the last extend call the dbuff was extended. More... | |
#define | fr_dbuff_is_extendable(_status) ((_status) & FR_DBUFF_FLAG_EXTENDABLE) |
Check if a dbuff can be extended again. More... | |
#define | fr_dbuff_was_extended(_status) ((_status) & FR_DBUFF_FLAG_EXTENDED) |
Check if the dbuff was extended during the last extend call. More... | |
Length checks | |
These macros return the amount of data used/remaining relative to the dbuff or marker's 'start', 'current', and 'end' pointers. In the majority of cases these macros should not be used and the extension request functions should be used instead. The only exception to this is if the caller is certain the fr_dbuff_t is not extensible. | |
#define | fr_dbuff_ahead(_dbuff_or_marker) |
How many bytes the dbuff or marker is ahead of its parent. More... | |
#define | fr_dbuff_behind(_dbuff_or_marker) |
How many bytes the dbuff or marker is behind its parent. More... | |
#define | fr_dbuff_len(_dbuff_or_marker) ((size_t)(fr_dbuff_end(_dbuff_or_marker) - fr_dbuff_start(_dbuff_or_marker))) |
The length of the underlying buffer. More... | |
#define | fr_dbuff_remaining(_dbuff_or_marker) |
Return the number of bytes remaining between the dbuff or marker and the end of the buffer. More... | |
#define | FR_DBUFF_REMAINING_RETURN(_dbuff_or_marker, _len) if ((_len) > fr_dbuff_remaining(_dbuff_or_marker)) return -((_len) - fr_dbuff_remaining(_dbuff_or_marker)) |
Check if _len bytes are available in the dbuff and if not return the number of bytes we'd need. More... | |
#define | fr_dbuff_used(_dbuff_or_marker) |
Return the number of bytes remaining between the start of the dbuff or marker and the current position. More... | |
Accessors | |
Caching the pointers returned by the accessors is strongly discouraged. Cached pointers can become invalidated if the fr_dbuff_t is extended, as the extensions callback may use realloc or memmove on the underlying buffer. fr_dbuff_t dbuff;
fr_dbuff_uctx_talloc_t tctx;
uint8_t *p;
fr_dbuff_init_talloc(NULL, &dbuff, &tctx, 512, SIZE_MAX);
p = fr_dbuff_current(&dbuff); // Cache the start pointer
fr_dbuff_extend_lowat(&dbuff, 1024); // Extension call triggers realloc
printf("%s", p); // Should print an empty string but may
// SEGV as p may now be invalid.
#define fr_dbuff_current(_dbuff_or_marker) Return the 'current' position of a dbuff or marker. Definition: dbuff.h:911 #define fr_dbuff_extend_lowat(_status, _dbuff_or_marker, _lowat) Extend if we're below _lowat. Definition: dbuff.h:660 static fr_dbuff_t * fr_dbuff_init_talloc(TALLOC_CTX *ctx, fr_dbuff_t *dbuff, fr_dbuff_uctx_talloc_t *tctx, size_t init, size_t max) Initialise a special dbuff which automatically extends as additional data is written. Definition: dbuff.h:411 Definition: merged_model.c:41 If offsets of a fr_dbuff_t need to be accessed, markers should be used. If a dbuff is extended all markers associated with it will be updated so that the content they point to remains constant. fr_dbuff_t dbuff;
fr_dbuff_uctx_talloc_t tctx;
fr_dbuff_init_talloc(NULL, &dbuff, &tctx, 512, SIZE_MAX);
fr_dbuff_marker(&m, &dbuff);
fr_dbuff_extend_lowat(&dbuff, 1024); // Extension call triggers realloc
// was extended. All is well.
struct fr_dbuff_marker_s fr_dbuff_marker_t A position marker associated with a dbuff. Definition: dbuff.h:81 static uint8_t * fr_dbuff_marker(fr_dbuff_marker_t *m, fr_dbuff_t *dbuff) Initialises a new marker pointing to the 'current' position of the dbuff. Definition: dbuff.h:1192 Using offsets of the pointers returned by accessor functions is also strongly discouraged as it invalidates many of the protections dbuffs give. fr_dbuff_t dbuff;
fr_dbuff_current(&dbuff)[2] = 0x00; // Write to invalid memory
#define fr_dbuff_init(_out, _start, _len_or_end) Initialise an dbuff for encoding or decoding. Definition: dbuff.h:354 | |
#define | fr_dbuff_buff(_dbuff_or_marker) |
Return the underlying buffer in a dbuff or one of marker. More... | |
#define | fr_dbuff_current(_dbuff_or_marker) |
Return the 'current' position of a dbuff or marker. More... | |
#define | fr_dbuff_end(_dbuff_or_marker) |
Return the current 'end' position of a dbuff or marker. More... | |
#define | fr_dbuff_ptr(_dbuff_or_marker) |
Return a pointer to the dbuff. More... | |
#define | fr_dbuff_ptr_const(_dbuff_or_marker) |
Return a const pointer to the dbuff. More... | |
#define | fr_dbuff_start(_dbuff_or_marker) |
Return the 'start' position of a dbuff or marker. More... | |
Position modification (recursive) | |
#define | fr_dbuff_advance(_dbuff_or_marker, _len) |
Advance 'current' position in dbuff or marker by _len bytes. More... | |
#define | fr_dbuff_advance_extend(_dbuff_or_marker, _len) |
Advance current'position in dbuff or marker by _len bytes (extending if necessary) More... | |
#define | FR_DBUFF_ADVANCE_RETURN(_dbuff_or_marker, _len) FR_DBUFF_RETURN(fr_dbuff_advance, _dbuff_or_marker, _len) |
Advance the 'current' position in dbuff or marker by _len bytes returning if _len is out of range. More... | |
#define | FR_DBUFF_BIND_EXTEND_RETURN(_dbuff_or_marker, _len) FR_DBUFF_RETURN(fr_dbuff_advance_extend, _dbuff_or_marker, _len) |
#define | fr_dbuff_set(_dst, _src) |
Set the 'current' position in a dbuff or marker using another dbuff or marker, a char pointer, or a length value. More... | |
#define | fr_dbuff_set_end(_dst, _end) |
Set a new 'end' position in a dbuff or marker. More... | |
#define | FR_DBUFF_SET_RETURN(_dst, _src) FR_DBUFF_RETURN(fr_dbuff_set, _dst, _src) |
Set the 'current' position in a dbuff or marker returning if _src is out of range. More... | |
#define | fr_dbuff_set_to_end(_dbuff_or_marker) fr_dbuff_set(_dbuff_or_marker, fr_dbuff_end(_dbuff_or_marker)) |
Reset the 'current' position of the dbuff or marker to the 'end' of the buffer. More... | |
#define | fr_dbuff_set_to_start(_dbuff_or_marker) fr_dbuff_set(_dbuff_or_marker, fr_dbuff_start(_dbuff_or_marker)) |
Reset the 'current' position of the dbuff or marker to the 'start' of the buffer. More... | |
"in" functions (copy data into a dbuff) | |
#define | fr_dbuff_in(_dbuff_or_marker, _in) |
Copy data from a fixed sized C type into a dbuff or marker. More... | |
#define | fr_dbuff_in_bytes(_dbuff_or_marker, ...) fr_dbuff_in_memcpy(_dbuff_or_marker, ((uint8_t []){ __VA_ARGS__ }), sizeof((uint8_t []){ __VA_ARGS__ })) |
Copy a byte sequence into a dbuff or marker. More... | |
#define | fr_dbuff_in_bytes_partial(_dbuff, ...) fr_dbuff_in_memcpy_partial(_dbuff, ((uint8_t []){ __VA_ARGS__ }), sizeof((uint8_t []){ __VA_ARGS__ })) |
Copy a partial byte sequence into a dbuff. More... | |
#define | FR_DBUFF_IN_BYTES_RETURN(_dbuff_or_marker, ...) FR_DBUFF_IN_MEMCPY_RETURN(_dbuff_or_marker, ((uint8_t []){ __VA_ARGS__ }), sizeof((uint8_t []){ __VA_ARGS__ })) |
Copy a byte sequence into a dbuff or marker returning if there's insufficient space. More... | |
#define | fr_dbuff_in_memcpy(_dbuff_or_marker, _in, _inlen) |
Copy exactly _inlen bytes into a dbuff or marker. More... | |
#define | fr_dbuff_in_memcpy_partial(_out, _in, _inlen) |
Copy at most _inlen bytes into the dbuff. More... | |
#define | FR_DBUFF_IN_MEMCPY_RETURN(_dbuff_or_marker, _in, _inlen) FR_DBUFF_RETURN(fr_dbuff_in_memcpy, _dbuff_or_marker, _in, _inlen) |
Copy exactly _inlen bytes into dbuff or marker returning if there's insufficient space. More... | |
#define | FR_DBUFF_IN_RETURN(_dbuff_or_marker, _in) FR_DBUFF_RETURN(fr_dbuff_in, _dbuff_or_marker, _in) |
Copy data from a fixed sized C type into a dbuff returning if there is insufficient space. More... | |
#define | fr_dbuff_in_uint64v(_dbuff_or_marker, _num) _fr_dbuff_in_uint64v(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), _num) |
Copy an integer value into a dbuff or marker using our internal variable length encoding. More... | |
#define | FR_DBUFF_IN_UINT64V(_dbuff_or_marker, _num) FR_DBUFF_RETURN(fr_dbuff_in_uint64v, _dbuff_or_marker, _num) |
Copy an integer value into a dbuff or marker using our internal variable length encoding returning if there is insufficient space. More... | |
#define | fr_dbuff_memset(_dbuff_or_marker, _c, _inlen) _fr_dbuff_memset(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), _c, _inlen) |
Set _inlen bytes of a dbuff or marker to _c. More... | |
#define | FR_DBUFF_MEMSET_RETURN(_dbuff_or_marker, _c, _inlen) FR_DBUFF_RETURN(fr_dbuff_memset, _dbuff_or_marker, _c, _inlen) |
Set _inlen bytes of a dbuff or marker to _c returning if there is insufficient space. More... | |
"move" functions (copy data between dbuffs and markers) | |
#define | fr_dbuff_move(_out, _in, _len) |
Copy in as many bytes as possible from one dbuff or marker to another. More... | |
"out" functions (copy data out of a dbuff) | |
#define | fr_dbuff_out(_out, _dbuff_or_marker) |
Copy data from a dbuff or marker to a fixed sized C type. More... | |
#define | fr_dbuff_out_int64v(_num, _dbuff_or_marker, _len) _fr_dbuff_out_int64v(_num, _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), _len) |
Read bytes from a dbuff or marker and interpret them as a network order signed integer. More... | |
#define | FR_DBUFF_OUT_INT64V_RETURN(_num, _dbuff_or_marker, _len) FR_DBUFF_RETURN(fr_dbuff_out_int64v, _num, _dbuff_or_marker, _len) |
Read bytes from a dbuff or marker and interpret them as a network order unsigned integer. More... | |
#define | fr_dbuff_out_memcpy(_out, _dbuff_or_marker, _outlen) |
Copy exactly _outlen bytes from the dbuff. More... | |
#define | FR_DBUFF_OUT_MEMCPY_RETURN(_out, _dbuff_or_marker, _outlen) FR_DBUFF_RETURN(fr_dbuff_out_memcpy, _out, _dbuff_or_marker, _outlen) |
Copy outlen bytes from the dbuff returning if there's insufficient data in the dbuff. More... | |
#define | FR_DBUFF_OUT_RETURN(_out, _dbuff_or_marker) FR_DBUFF_RETURN(fr_dbuff_out, _out, _dbuff_or_marker) |
Copy data from a dbuff or marker to a fixed sized C type returning if there is insufficient data. More... | |
#define | fr_dbuff_out_uint64v(_num, _dbuff_or_marker, _len) _fr_dbuff_out_uint64v(_num, _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), _len) |
Read bytes from a dbuff or marker and interpret them as a network order unsigned integer. More... | |
#define | FR_DBUFF_OUT_UINT64V_RETURN(_num, _dbuff_or_marker, _len) FR_DBUFF_RETURN(fr_dbuff_out_uint64v, _num, _dbuff_or_marker, _len) |
Read bytes from a dbuff or marker and interpret them as a network order unsigned integer. More... | |
Extension callback helpers | |
These public functions are intended to be called by extension callbacks to fixup dbuffs after the underlying buffer or its contents has been altered. | |
size_t | fr_dbuff_shift (fr_dbuff_t *dbuff, size_t shift) |
Shift the contents of the dbuff, returning the number of bytes we managed to shift. More... | |
void | fr_dbuff_update (fr_dbuff_t *dbuff, uint8_t *new_buff, size_t new_len) |
Update all markers and pointers in the set of dbuffs to point to new_buff. More... | |
Marker management | |
Most operations that can be performed on an fr_dbuff_t can also be performed on a fr_dbuff_marker_t. It is recommended that markers be created against a stack-frame-local dbuff so that they are automatically released when the framed is popped.
| |
static uint8_t * | fr_dbuff_marker (fr_dbuff_marker_t *m, fr_dbuff_t *dbuff) |
Initialises a new marker pointing to the 'current' position of the dbuff. More... | |
static void | fr_dbuff_marker_release (fr_dbuff_marker_t *m) |
Releases the specified marker and any markers added before it. More... | |
static size_t | fr_dbuff_marker_release_ahead (fr_dbuff_marker_t *m) |
Trims the linked list back to the specified pointer and return how many bytes marker was ahead of p. More... | |
static size_t | fr_dbuff_marker_release_behind (fr_dbuff_marker_t *m) |
Trims the linked list back to the specified pointer and return how many bytes marker was behind p. More... | |
A generic data buffer structure for encoding and decoding.
Because doing manual length checks is error prone and a waste of everyone's time.
Definition in file dbuff.h.
struct fr_dbuff_thread_local_t |
Data Fields | ||
---|---|---|
fr_dbuff_t | dbuff | Thread local dbuff. |
fr_dbuff_uctx_talloc_t | tctx | Thread local tctx. |
#define FR_DBUFF | ( | _dbuff_or_marker | ) | _FR_DBUFF(_dbuff_or_marker, fr_dbuff_current(_dbuff_or_marker), 0x00) |
#define FR_DBUFF_ABS | ( | _dbuff_or_marker | ) | _FR_DBUFF(_dbuff_or_marker, fr_dbuff_start(_dbuff_or_marker), 0x00) |
#define FR_DBUFF_ADV_PARENT_CURRENT 0x01 |
#define FR_DBUFF_ADV_PARENT_END 0x02 |
#define fr_dbuff_advance | ( | _dbuff_or_marker, | |
_len | |||
) |
Advance 'current' position in dbuff or marker by _len bytes.
[in] | _dbuff_or_marker | to advance. |
[in] | _len | How much to advance dbuff by. Must be a positive integer. |
#define fr_dbuff_advance_extend | ( | _dbuff_or_marker, | |
_len | |||
) |
Advance current'position in dbuff or marker by _len bytes (extending if necessary)
[in] | _dbuff_or_marker | to advance. |
[in] | _len | How much to advance dbuff by. Must be a positive integer. |
#define FR_DBUFF_ADVANCE_RETURN | ( | _dbuff_or_marker, | |
_len | |||
) | FR_DBUFF_RETURN(fr_dbuff_advance, _dbuff_or_marker, _len) |
Advance the 'current' position in dbuff or marker by _len bytes returning if _len is out of range.
[in] | _dbuff_or_marker | to advance. |
[in] | _len | How much to advance dbuff by. Must be a positive integer. |
#define fr_dbuff_ahead | ( | _dbuff_or_marker | ) |
How many bytes the dbuff or marker is ahead of its parent.
#define fr_dbuff_behind | ( | _dbuff_or_marker | ) |
How many bytes the dbuff or marker is behind its parent.
[in] | _dbuff_or_marker |
#define FR_DBUFF_BIND_CURRENT | ( | _dbuff_or_marker | ) | _FR_DBUFF(_dbuff_or_marker, fr_dbuff_current(_dbuff_or_marker), FR_DBUFF_ADV_PARENT_CURRENT) |
#define FR_DBUFF_BIND_CURRENT_ABS | ( | _dbuff_or_marker | ) | FR_DBUFF_ABS(_dbuff_or_marker, fr_dbuff_start(_dbuff_or_marker), FR_DBUFF_ADV_PARENT_CURRENT) |
#define FR_DBUFF_BIND_END_ABS | ( | _dbuff_or_marker | ) | _FR_DBUFF(_dbuff_or_marker, fr_dbuff_start(_dbuff_or_marker), FR_DBUFF_ADV_PARENT_END) |
Create a new dbuff pointing to the same underlying buffer.
This is used to create the producer of a producer/consumer pairs of dbuffs.
end
pointer will be advanced with child's p
pointer.start
pointer set to the start
pointer of the parent.[in] | _dbuff_or_marker | to make an ephemeral copy of. |
#define FR_DBUFF_BIND_EXTEND_RETURN | ( | _dbuff_or_marker, | |
_len | |||
) | FR_DBUFF_RETURN(fr_dbuff_advance_extend, _dbuff_or_marker, _len) |
#define fr_dbuff_buff | ( | _dbuff_or_marker | ) |
Return the underlying buffer in a dbuff or one of marker.
[in] | _dbuff_or_marker | to return the buffer for. |
#define fr_dbuff_current | ( | _dbuff_or_marker | ) |
Return the 'current' position of a dbuff or marker.
[in] | _dbuff_or_marker | to return the current position of. |
#define fr_dbuff_end | ( | _dbuff_or_marker | ) |
Return the current 'end' position of a dbuff or marker.
[in] | _dbuff_or_marker | to return the end position of. |
#define fr_dbuff_extend | ( | _dbuff | ) | fr_dbuff_extend_lowat(NULL, _dbuff, 1) |
#define fr_dbuff_extend_lowat | ( | _status, | |
_dbuff_or_marker, | |||
_lowat | |||
) |
Extend if we're below _lowat.
[out] | _status | May be NULL. If fr_dbuff_extend_lowat is used in a copy loop, the caller should pass a pointer to a fr_dbuff_extend_status_t. The initial value of the fr_dbuff_extend_status_t variable should be FR_DBUFF_EXTENDABLE, and will be updated to indicate whether the dbuff is extensible, whether it was extended, and whether it may be extended again. This information is used the loop condition to prevent spurious extension calls. |
[in] | _dbuff_or_marker | to extend. |
[in] | _lowat | If bytes remaining are below the amount, extend. |
#define FR_DBUFF_EXTEND_LOWAT_OR_RETURN | ( | _dbuff_or_marker, | |
_lowat | |||
) |
Extend if we're below _lowat and return if we can't extend above _lowat.
[in] | _dbuff_or_marker | to extend. |
[in] | _lowat | If bytes remaining are below the amount, extend. |
#define FR_DBUFF_FLAG_EXTENDABLE 0x01 |
#define FR_DBUFF_FLAG_EXTENDED 0x02 |
#define fr_dbuff_in | ( | _dbuff_or_marker, | |
_in | |||
) |
Copy data from a fixed sized C type into a dbuff or marker.
[out] | _dbuff_or_marker | to write to. Integer types will be automatically converted to big endian byte order. |
[in] | _in | Value to copy. |
#define fr_dbuff_in_bytes | ( | _dbuff_or_marker, | |
... | |||
) | fr_dbuff_in_memcpy(_dbuff_or_marker, ((uint8_t []){ __VA_ARGS__ }), sizeof((uint8_t []){ __VA_ARGS__ })) |
#define fr_dbuff_in_bytes_partial | ( | _dbuff, | |
... | |||
) | fr_dbuff_in_memcpy_partial(_dbuff, ((uint8_t []){ __VA_ARGS__ }), sizeof((uint8_t []){ __VA_ARGS__ })) |
#define FR_DBUFF_IN_BYTES_RETURN | ( | _dbuff_or_marker, | |
... | |||
) | FR_DBUFF_IN_MEMCPY_RETURN(_dbuff_or_marker, ((uint8_t []){ __VA_ARGS__ }), sizeof((uint8_t []){ __VA_ARGS__ })) |
#define fr_dbuff_in_memcpy | ( | _dbuff_or_marker, | |
_in, | |||
_inlen | |||
) |
Copy exactly _inlen bytes into a dbuff or marker.
If _in is a dbuff and _inlen is greater than the number of bytes available in that dbuff, the copy operation will fail.
[in] | _dbuff_or_marker | to copy data to. |
[in] | _in | data to copy in to the dbuff or marker. |
[in] | _inlen | How much data we need to copy. If _in is a char * or dbuff * and SIZE_MAX is passed, then _inlen will be substituted for the length of the data in the dbuff. |
#define fr_dbuff_in_memcpy_partial | ( | _out, | |
_in, | |||
_inlen | |||
) |
Copy at most _inlen bytes into the dbuff.
Use this variant when writing data to a streaming buffer where partial writes will be tracked.
If _in is a fr_dbuff_t and _inlen is greater than the number of bytes available in that dbuff, the copy operation will truncated.
[in] | _out | to copy data to. |
[in] | _in | Data to copy to dbuff. |
[in] | _inlen | How much data we need to copy. If _in is a char * or dbuff * and SIZE_MAX is passed, then _inlen will be substituted for the length of the buffer. |
#define FR_DBUFF_IN_MEMCPY_RETURN | ( | _dbuff_or_marker, | |
_in, | |||
_inlen | |||
) | FR_DBUFF_RETURN(fr_dbuff_in_memcpy, _dbuff_or_marker, _in, _inlen) |
Copy exactly _inlen bytes into dbuff or marker returning if there's insufficient space.
If _in is a dbuff and _inlen is greater than the number of bytes available in that dbuff, the copy operation will fail.
[in] | _dbuff_or_marker | to copy data to. |
[in] | _in | data to copy in to the dbuff or marker. |
[in] | _inlen | How much data we need to copy. If _in is a char * or dbuff * and SIZE_MAX is passed, then _inlen will be substituted for the length of the data in the dbuff. |
#define FR_DBUFF_IN_RETURN | ( | _dbuff_or_marker, | |
_in | |||
) | FR_DBUFF_RETURN(fr_dbuff_in, _dbuff_or_marker, _in) |
Copy data from a fixed sized C type into a dbuff returning if there is insufficient space.
[out] | _dbuff_or_marker | to write to. Integer types will be automatically converted to big endian byte order. |
[in] | _in | Value to copy. |
#define fr_dbuff_in_uint64v | ( | _dbuff_or_marker, | |
_num | |||
) | _fr_dbuff_in_uint64v(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), _num) |
Copy an integer value into a dbuff or marker using our internal variable length encoding.
[out] | _dbuff_or_marker | to copy integer value to. |
[in] | _num | to copy. |
#define FR_DBUFF_IN_UINT64V | ( | _dbuff_or_marker, | |
_num | |||
) | FR_DBUFF_RETURN(fr_dbuff_in_uint64v, _dbuff_or_marker, _num) |
Copy an integer value into a dbuff or marker using our internal variable length encoding returning if there is insufficient space.
[out] | _dbuff_or_marker | to copy integer value to. |
[in] | _num | to copy. |
#define fr_dbuff_init | ( | _out, | |
_start, | |||
_len_or_end | |||
) |
Initialise an dbuff for encoding or decoding.
[out] | _out | Pointer to buffer to parse |
[in] | _start | Start of the buffer to parse. |
[in] | _len_or_end | Either an end pointer or the length of the buffer we're decoding. |
#define FR_DBUFF_INIT | ( | _out, | |
_start, | |||
_len_or_end | |||
) |
#define fr_dbuff_is_extendable | ( | _status | ) | ((_status) & FR_DBUFF_FLAG_EXTENDABLE) |
#define fr_dbuff_len | ( | _dbuff_or_marker | ) | ((size_t)(fr_dbuff_end(_dbuff_or_marker) - fr_dbuff_start(_dbuff_or_marker))) |
#define FR_DBUFF_MAX | ( | _dbuff_or_marker, | |
_max | |||
) | _FR_DBUFF_MAX(_dbuff_or_marker, _max, 0x00) |
Limit the maximum number of bytes available in the dbuff when passing it to another function.
[in] | _dbuff_or_marker | to reserve bytes in. |
[in] | _max | The maximum number of bytes the caller is allowed to write to. |
#define FR_DBUFF_MAX_BIND_CURRENT | ( | _dbuff_or_marker, | |
_max | |||
) | _FR_DBUFF_MAX(_dbuff_or_marker, _max, FR_DBUFF_ADV_PARENT_CURRENT) |
Limit the maximum number of bytes available in the dbuff when passing it to another function.
[in] | _dbuff_or_marker | to reserve bytes in. |
[in] | _max | The maximum number of bytes the caller is allowed to write to. |
#define fr_dbuff_memset | ( | _dbuff_or_marker, | |
_c, | |||
_inlen | |||
) | _fr_dbuff_memset(_fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), _c, _inlen) |
Set _inlen bytes of a dbuff or marker to _c.
[in] | _dbuff_or_marker | to copy data to. Will be advanced by _inlen bytes. |
[in] | _c | Value to set. |
[in] | _inlen | How much data we need to copy. |
#define FR_DBUFF_MEMSET_RETURN | ( | _dbuff_or_marker, | |
_c, | |||
_inlen | |||
) | FR_DBUFF_RETURN(fr_dbuff_memset, _dbuff_or_marker, _c, _inlen) |
Set _inlen bytes of a dbuff or marker to _c returning if there is insufficient space.
[in] | _dbuff_or_marker | to copy data to. Will be advanced by _inlen bytes. |
[in] | _c | Value to set. |
[in] | _inlen | How much data we need to copy. |
#define fr_dbuff_move | ( | _out, | |
_in, | |||
_len | |||
) |
Copy in as many bytes as possible from one dbuff or marker to another.
[in] | _out | to copy into. |
[in] | _in | to copy from. |
[in] | _len | The maximum length to copy. |
#define fr_dbuff_out | ( | _out, | |
_dbuff_or_marker | |||
) |
Copy data from a dbuff or marker to a fixed sized C type.
[out] | _out | Where to write the data. If out is an integer type a byteswap will be performed if native endianness is not big endian. |
[in] | _dbuff_or_marker | to copy data from. Will be advanced by the number of bytes consumed, i.e. if out is a uin16_t *, _dbuff_or_marker will be advanced by two bytes. |
#define fr_dbuff_out_int64v | ( | _num, | |
_dbuff_or_marker, | |||
_len | |||
) | _fr_dbuff_out_int64v(_num, _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), _len) |
Read bytes from a dbuff or marker and interpret them as a network order signed integer.
[in] | _num | points to an int64_t to store the integer in |
[in] | _dbuff_or_marker | data to copy bytes from |
[in] | _len | number of bytes to read (must be positive and less than eight) |
#define FR_DBUFF_OUT_INT64V_RETURN | ( | _num, | |
_dbuff_or_marker, | |||
_len | |||
) | FR_DBUFF_RETURN(fr_dbuff_out_int64v, _num, _dbuff_or_marker, _len) |
Read bytes from a dbuff or marker and interpret them as a network order unsigned integer.
[in] | _num | points to an int64_t to store the integer in |
[in] | _dbuff_or_marker | data to copy bytes from |
[in] | _len | number of bytes to read (must be positive and less than eight) |
#define fr_dbuff_out_memcpy | ( | _out, | |
_dbuff_or_marker, | |||
_outlen | |||
) |
Copy exactly _outlen bytes from the dbuff.
If _out is a dbuff and _outlen is greater than the number of bytes available in that dbuff, the copy operation will fail.
[in] | _out | either a buffer, or another dbuff/marker to copy data to. |
[in] | _dbuff_or_marker | to copy data from. |
[in] | _outlen | How much data we need to copy. If _out is fr_dbuff_t * and SIZE_MAX is passed, then _inlen will be substituted for the length of the buffer. |
#define FR_DBUFF_OUT_MEMCPY_RETURN | ( | _out, | |
_dbuff_or_marker, | |||
_outlen | |||
) | FR_DBUFF_RETURN(fr_dbuff_out_memcpy, _out, _dbuff_or_marker, _outlen) |
Copy outlen bytes from the dbuff returning if there's insufficient data in the dbuff.
If _out is a dbuff and _outlen is greater than the number of bytes available in that dbuff, the copy operation will fail.
[in] | _out | either a buffer, or another dbuff/marker to copy data to. |
[in] | _dbuff_or_marker | to copy data from. |
[in] | _outlen | How much data we need to copy. If _out is fr_dbuff_t * and SIZE_MAX is passed, then _inlen will be substituted for the length of the buffer. |
#define FR_DBUFF_OUT_RETURN | ( | _out, | |
_dbuff_or_marker | |||
) | FR_DBUFF_RETURN(fr_dbuff_out, _out, _dbuff_or_marker) |
Copy data from a dbuff or marker to a fixed sized C type returning if there is insufficient data.
[out] | _out | Where to write the data. If out is an integer type a byteswap will be performed if native endianness is not big endian. |
[in] | _dbuff_or_marker | to copy data from. Will be advanced by the number of bytes consumed, i.e. if out is a uin16_t *, _dbuff_or_marker will be advanced by two bytes. |
#define fr_dbuff_out_uint64v | ( | _num, | |
_dbuff_or_marker, | |||
_len | |||
) | _fr_dbuff_out_uint64v(_num, _fr_dbuff_current_ptr(_dbuff_or_marker), fr_dbuff_ptr(_dbuff_or_marker), _len) |
Read bytes from a dbuff or marker and interpret them as a network order unsigned integer.
[in] | _num | points to a uint64_t to store the integer in |
[in] | _dbuff_or_marker | data to copy bytes from |
[in] | _len | number of bytes to read (must be positive and less than eight) |
#define FR_DBUFF_OUT_UINT64V_RETURN | ( | _num, | |
_dbuff_or_marker, | |||
_len | |||
) | FR_DBUFF_RETURN(fr_dbuff_out_uint64v, _num, _dbuff_or_marker, _len) |
Read bytes from a dbuff or marker and interpret them as a network order unsigned integer.
[in] | _num | points to a uint64_t to store the integer in |
[in] | _dbuff_or_marker | data to copy bytes from |
[in] | _len | number of bytes to read (must be positive and less than eight) |
#define fr_dbuff_ptr | ( | _dbuff_or_marker | ) |
Return a pointer to the dbuff.
[in] | _dbuff_or_marker | to return a pointer to. |
#define fr_dbuff_ptr_const | ( | _dbuff_or_marker | ) |
Return a const pointer to the dbuff.
[in] | _dbuff_or_marker | to return a pointer to. |
#define fr_dbuff_remaining | ( | _dbuff_or_marker | ) |
Return the number of bytes remaining between the dbuff or marker and the end of the buffer.
[in] | _dbuff_or_marker | to return the number of bytes remaining for. |
#define FR_DBUFF_REMAINING_RETURN | ( | _dbuff_or_marker, | |
_len | |||
) | if ((_len) > fr_dbuff_remaining(_dbuff_or_marker)) return -((_len) - fr_dbuff_remaining(_dbuff_or_marker)) |
Check if _len bytes are available in the dbuff and if not return the number of bytes we'd need.
[in] | _dbuff_or_marker | to return the number of bytes remaining for. |
[in] | _len | Minimum remaining bytes. |
#define FR_DBUFF_RETURN | ( | _func, | |
... | |||
) |
#define fr_dbuff_set | ( | _dst, | |
_src | |||
) |
Set the 'current' position in a dbuff or marker using another dbuff or marker, a char pointer, or a length value.
[in] | _dst | dbuff or marker to set the position for. |
[in] | _src | Variable to glean new position from. Behaviour here depends on the type of the variable.
|
#define fr_dbuff_set_end | ( | _dst, | |
_end | |||
) |
Set a new 'end' position in a dbuff or marker.
[out] | _dst | dbuff to use for constraints checks. |
[in] | _end | Position to set. |
#define FR_DBUFF_SET_RETURN | ( | _dst, | |
_src | |||
) | FR_DBUFF_RETURN(fr_dbuff_set, _dst, _src) |
#define fr_dbuff_set_to_end | ( | _dbuff_or_marker | ) | fr_dbuff_set(_dbuff_or_marker, fr_dbuff_end(_dbuff_or_marker)) |
#define fr_dbuff_set_to_start | ( | _dbuff_or_marker | ) | fr_dbuff_set(_dbuff_or_marker, fr_dbuff_start(_dbuff_or_marker)) |
#define fr_dbuff_start | ( | _dbuff_or_marker | ) |
Return the 'start' position of a dbuff or marker.
The start position is not necessarily the start of the buffer, and is advanced every time a dbuff is copied.
[in] | _dbuff_or_marker | to return the start position of. |
#define FR_DBUFF_TALLOC_THREAD_LOCAL | ( | _out, | |
_init, | |||
_max | |||
) |
Create a function local and thread local extensible dbuff.
[out] | _out | Where to write a pointer to the thread local dbuff |
[in] | _init | Initial size for the dbuff buffer. |
[in] | _max | Maximum size of the dbuff buffer. |
#define FR_DBUFF_TMP | ( | _start, | |
_len_or_end | |||
) |
Creates a compound literal to pass into functions which accept a dbuff.
[in] | _start | of the buffer. |
[in] | _len_or_end | Length of the buffer or the end pointer. |
#define fr_dbuff_used | ( | _dbuff_or_marker | ) |
Return the number of bytes remaining between the start of the dbuff or marker and the current position.
#define fr_dbuff_was_extended | ( | _status | ) | ((_status) & FR_DBUFF_FLAG_EXTENDED) |
typedef size_t(* fr_dbuff_extend_t) (fr_dbuff_t *dbuff, size_t req_extension) |
dbuff extension callback
This callback is used to extend the underlying buffer.
After performing an operation on the underlying buffer, this callback should call fr_dbuff_update to fix position pointers in the current dbuff and its parents and markers.
Generally the caller will request the minimum amount the buffer should be extended by. This callback may choose to ignore the request and extend the buffer by more than the requested amount.
[in] | dbuff | to extend. |
[in] | req_extension | How much the caller wants to extend the buffer by. |
typedef struct fr_dbuff_marker_s fr_dbuff_marker_t |
A position marker associated with a dbuff.
Markers are used whenever the caller needs to access part of the underlying buffer other than the 'start', 'current' or 'end' positions described by a fr_dbuff_t.
Markers are needed because if a fr_dbuff_t is extended, pointers into the underlying buffer may be invalidated by a realloc or memmove.
Markers are intended to be allocated on the stack and associated with a stack-frame-local fr_dbuff_t
. Using a stack-frame-local dbuff ensures markers are automatically released when the stack frame is popped so that markers are not leaked.
typedef struct fr_dbuff_s fr_dbuff_t |
A dbuff.
dbuffs wrap an underlying buffer, maintaining 'start', 'current', and 'end' position pointers.
dbuffs also contain information on if and how the underlying buffer can be extended.
For encoding extending means reallocing the underlying buffer so that there's addition space to write data to.
For stream decoding extending means shifting out existing data and refilling the underlying buffer from a data source.
dbuffs are intended to be organised into hierarchies, with one dbuff per stack frame, initialised from a parent in a higher stack frame.
Each time a dbuff is copied (using one of the provided FR_DBUFF_BIND_CURRENT_* macros), the copy's 'start' position is updated to be the 'current' position of its parent. This ensures length macros report only spaced used/available in the new dbuff and not its parent. Other copy macros may move the 'end' position, to artificially limit the amount of data available.
Whether the buffer is currently extendable and whether it was extended.
|
inlinestatic |
size_t _fr_dbuff_extend_fd | ( | fr_dbuff_t * | dbuff, |
size_t | extension | ||
) |
size_t _fr_dbuff_extend_talloc | ( | fr_dbuff_t * | dbuff, |
size_t | extension | ||
) |
Reallocate the current buffer.
[in] | dbuff | to be extended. |
[in] | extension | How many additional bytes should be allocated in the buffer. |
Definition at line 235 of file dbuff.c.
|
inlinestatic |
|
inlinestatic |
Initialise a special dbuff which automatically reads in more data as the buffer is exhausted.
[out] | dbuff | to initialise. |
[out] | fctx | to initialise. Must have a lifetime >= to the dbuff. |
[in] | buff | Temporary buffer to use for storing file contents. |
[in] | len | Length of the temporary buffer. |
[in] | fd | descriptor of an open file to read from. |
[in] | max | The maximum length of data to read from the file. |
< Store the real end
< Starts with 0 bytes available
Definition at line 485 of file dbuff.h.
|
inlinestatic |
Initialise a special dbuff which automatically extends as additional data is written.
[in] | ctx | to allocate buffer in. |
[out] | dbuff | to initialise. |
[out] | tctx | to initialise. Must have a lifetime >= to the dbuff. |
[in] | init | The length of the initial buffer. |
[in] | max | The maximum length of the buffer. |
Definition at line 411 of file dbuff.h.
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |
Trims the linked list back to the specified pointer and return how many bytes marker was ahead of p.
Pointers should be released in the inverse order to allocation.
Alternatively the oldest pointer can be released, resulting in any newer pointer also being removed from the list.
[in] | m | to release. |
Definition at line 1250 of file dbuff.h.
|
inlinestatic |
Trims the linked list back to the specified pointer and return how many bytes marker was behind p.
Pointers should be released in the inverse order to allocation.
Alternatively the oldest pointer can be released, resulting in any newer pointer also being removed from the list.
[in] | m | to release. |
Definition at line 1231 of file dbuff.h.
int fr_dbuff_reset_talloc | ( | fr_dbuff_t * | dbuff | ) |
size_t fr_dbuff_shift | ( | fr_dbuff_t * | dbuff, |
size_t | shift | ||
) |
Shift the contents of the dbuff, returning the number of bytes we managed to shift.
[in] | dbuff | to shift. |
[in] | shift | the number of bytes to shift (not necessarily the amount actually shifted, because one can't move pointers outside the buffer) |
Definition at line 116 of file dbuff.c.
int fr_dbuff_trim_talloc | ( | fr_dbuff_t * | dbuff, |
size_t | len | ||
) |
Trim a talloced dbuff to the minimum length required to represent the contained string.
[in] | dbuff | to trim. |
[in] | len | Length to trim to. Passing SIZE_MAX will result in the buffer being trimmed to the length of the content. |
Definition at line 297 of file dbuff.c.
void fr_dbuff_update | ( | fr_dbuff_t * | dbuff, |
uint8_t * | new_buff, | ||
size_t | new_len | ||
) |
Update all markers and pointers in the set of dbuffs to point to new_buff.
This function should be used if the underlying buffer is realloced.
[in] | dbuff | to update. |
[in] | new_buff | to assign to to sbuff. |
[in] | new_len | Length of the new buffer. |
Definition at line 79 of file dbuff.c.