160 lines
3.9 KiB
C
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__ */
|