#ifndef UC_MBUF_H_ #define UC_MBUF_H_ #include #include #ifdef __GNUC__ # define UC_INLINE inline __attribute__((always_inline)) #else # define UC_INLINE inline #endif enum UC_MBUF_FLAGS { UC_MBUF_FL_MALLOC = 0x0001, //MBuf and MBuf->bufstart are seperatly malloc'd UC_MBUF_FL_MALLOC_BUF = 0x0001, //MBuf is not malloc'd. MBuf->bufstart is malloc'd UC_MBUF_FL_MALLOC_INLINE = 0x0002, //MBuf is one big malloc. Can't be resized UC_MBUF_FL_STATIC = 0x0004, //MBuf and MBuf->bustart is user controlled. Can't be resized }; struct MBuf { struct MBuf *next; uint8_t *p1; uint8_t *p2; uint8_t *p3; uint8_t *p4; void *cookie; uint32_t flags; uint32_t allocated; uint8_t *bufstart; uint8_t *head; uint8_t *tail; uint8_t inline_data[0]; }; /* Conventions: * push - prepend data to the buffer (in the head room part) * pull - remove data from the beginning of the message. * put - Add data to the buffer. */ struct MBuf *uc_mbuf_new_hr(uint32_t len, uint32_t headroom); #define uc_mbuf_new(len) uc_mbuf_new_hr((len), 0) struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom); #define uc_mbuf_new_inline(len) uc_mbuf_new_inline_hr((len), 0) void uc_mbuf_free(struct MBuf *mbuf); struct MBuf *uc_mbuf_copy_data(struct MBuf *mbuf); void uc_mbuf_init(struct MBuf *mbuf, uint8_t *buf, uint32_t len, uint32_t headroom, uint32_t flags); void uc_mbuf_zero(struct MBuf *mbuf); void uc_mbuf_reset(struct MBuf *mbuf); static UC_INLINE uint32_t uc_mbuf_len(struct MBuf *mbuf) { return (uint32_t)(mbuf->tail - mbuf->head); } static UC_INLINE uint32_t uc_mbuf_tailroom(struct MBuf *mbuf) { return mbuf->allocated - (uint32_t)(mbuf->tail - mbuf->bufstart); } static inline uint32_t uc_mbuf_headroom(struct MBuf *mbuf) { return (uint32_t)(mbuf->head - mbuf->bufstart); } uint8_t *uc_mbuf_put(struct MBuf *mbuf, uint32_t size); uint8_t *uc_mbuf_push(struct MBuf *mbuf, uint32_t size); uint8_t *uc_mbuf_pull(struct MBuf *mbuf, uint32_t size); #undef UC_INLINE #endif