src.dualinventive.com/dinet/sec-multi-proxy/libdi/include/di/buffer.h

160 lines
3.9 KiB
C

#ifndef DI_BUFFER_H__
#define DI_BUFFER_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <di/types.h>
#include <di/semaphore.h>
#define DI_BUFFER_DECL_ARRAY(name, elements, size) \
static uint8_t name##_data[elements][size]; \
static struct di_buffer name[elements];
#define DI_BUFFER_INIT_ARRAY(name, elements, size) \
di_buffer_init_array(name, name##_data, elements, size)
#define DI_BUFFER_DECL(name, size) \
static uint8_t name##_data[size]; \
static struct di_buffer name = { name##_data, name##_data, size, 0, false };
/**
* Create buffers with list
* - data: NAME_data[LIST_SIZE][DATA_SIZE]
* - buffer: NAME_buffer
* - list: NAME
*/
#define DI_BUFFER_LIST_DECL(name, list_size, data_size, ...) \
static uint8_t name##_data[list_size][data_size]; \
static struct di_buffer name##_buffer[list_size]; \
static struct di_buffer_list name
#define DI_BUFFER_LIST_INIT(name, list_size, data_size) \
di_buffer_list_init(&name, list_size, name##_buffer, &name##_data, data_size)
/**
* Buffer
*/
struct di_buffer {
uint8_t *data;
uint8_t *cur;
size_t size;
size_t used;
bool in_use;
};
/**
* List of di_buffer with locking
*/
struct di_buffer_list {
struct di_buffer *buffer;
size_t size;
di_bsem_t lock;
};
/**
* Initialize buffer, it will not flush the buffer. Please use di_buffer_flush.
*/
void di_buffer_init(struct di_buffer *b, void *data, size_t size);
void di_buffer_init_array(struct di_buffer *a, void *data, size_t elements, size_t size);
void di_buffer_destroy(struct di_buffer *b);
bool di_buffer_is_full(struct di_buffer *b);
/**
* Reset buffer to begin
* * Set cur member
* * Reset used member
*/
void di_buffer_reset(struct di_buffer *b);
/**
* Flush buffer data to zero and reset
*/
void di_buffer_flush(struct di_buffer *b);
/**
* Append byte to buffer
*/
bool di_buffer_write_u8(struct di_buffer *b, uint8_t c);
/**
* Append buffer to buffer
*/
size_t di_buffer_write_data(struct di_buffer *b, const void *buf, size_t len);
/**
* Set cursor to next byte
*/
bool di_buffer_next(struct di_buffer *b);
/**
* Get size in used bytes
*/
size_t di_buffer_size_inuse(struct di_buffer *b);
/**
* Get amount of free bytes
*/
size_t di_buffer_size_free(struct di_buffer *b);
/**
* Memory copy buf with n size into b->data + offset, when
* it won't fit then no bytes are written because memcpy truncating
* bytes is not normal behavior
* @return Size of written bytes (0 if it exceeds b->data + b->size)
*/
size_t di_buffer_memcpy(struct di_buffer *b, size_t offset, const void *buf, size_t n);
/**
* Search for pattern in memory and return at occurrence
* @param l Memory block
* @param l_len Memory block length
* @param s Pattern to search for
* @param s_len Pattern length
*/
void *di_buffer_memmem(const void *l, size_t l_len, const void *s, size_t s_len);
/**
* Append buffer to another
* Deep copies src->used bytes starting from offset 0 into dst starting from current offset
* the data must fit else no copy will occur
* @param dst Destination buffer
* @param src Source buffer
*/
di_errno_t di_buffer_append(struct di_buffer *dst, struct di_buffer *src);
/**
* Initialize list of buffers<br>
* Example:
* - LIST_SIZE: 10
* - OBJ_SIZE: 256
* - l: di_buffer list[LIST_SIZE]
* - l_n: LIST_SIZE
* - data: uint8_t list_data[LIST_SIZE][OBJ_SIZE]
* - data_n: OBJ_SIZE
* @param list List of buffer objects
* @param list_n Amount of items in list
* @param buffer Buffer
* @param data Data block, MUST have a size of l_n * data_n
* @param data_n Data block object size
*/
void di_buffer_list_init(struct di_buffer_list *list, size_t list_n, struct di_buffer *buffer,
void *data, size_t data_n);
struct di_buffer *di_buffer_list_get(struct di_buffer_list *list);
void di_buffer_list_return(struct di_buffer_list *list, struct di_buffer **b);
#ifdef __cplusplus
}
#endif
#endif /** DI_BUFFER_H__ */