TypeLenVal
Loading...
Searching...
No Matches
tlv.h
Go to the documentation of this file.
1
29
30#pragma once
31
32#include <stdbool.h>
33#include <stdint.h>
34#include <string.h>
35#include <assert.h>
36
37typedef uint8_t tlv_tag_t;
38typedef uint8_t tlv_len_t;
39
41#define TLV_TAGLEN_SIZE (sizeof(tlv_tag_t) + sizeof(tlv_len_t))
42
50
52struct tlv_buf {
53 uint8_t *_mem;
54 size_t _cap;
55
56 size_t _head_idx;
57 size_t _tail_idx;
58};
59
62static void tlv_buf_init(struct tlv_buf *self, uint8_t *mem, const size_t cap)
63{
64 assert(self && mem && (cap > 0u));
65
66 self->_mem = mem;
67 self->_cap = cap;
68
69 self->_head_idx = 0u;
70 self->_tail_idx = 0u;
71}
72
74static void tlv_entry_init(struct tlv_entry *self, const uint8_t tag,
75 const uint8_t len, void *val)
76{
77 assert(self && val);
78
79 self->tag = tag;
80 self->len = len;
81 self->val = val;
82}
83
86static bool tlv_buf_push(struct tlv_buf *self, struct tlv_entry *entry)
87{
88 bool result;
89 size_t header_size;
90 size_t entry_size;
91 size_t new_tail_idx;
92
93 assert(self && entry);
94 result = false;
95 header_size = sizeof(entry->tag) + sizeof(entry->len);
96 entry_size = header_size + entry->len;
97 new_tail_idx = self->_tail_idx + entry_size;
98
99 if (new_tail_idx < self->_cap) {
100 self->_mem[self->_tail_idx] = entry->tag;
101 self->_tail_idx += sizeof(entry->tag);
102
103 self->_mem[self->_tail_idx] = entry->len;
104 self->_tail_idx += sizeof(entry->len);
105
106 (void)memcpy(&self->_mem[self->_tail_idx], entry->val,
107 entry->len);
108 self->_tail_idx = new_tail_idx;
109
110 result = true;
111 }
112
113 return result;
114}
115
118static bool tlv_buf_pop(struct tlv_buf *self, struct tlv_entry *entry)
119{
120 bool result;
121 size_t header_size;
122
123 assert(self && entry);
124 result = false;
125 header_size = sizeof(entry->tag) + sizeof(entry->len);
126
127 /* There's no extra check for full length, which might be dangerous */
128 if ((self->_head_idx + header_size) <= self->_tail_idx) {
129 entry->tag = self->_mem[self->_head_idx];
130 self->_head_idx += sizeof(entry->tag);
131
132 entry->len = self->_mem[self->_head_idx];
133 self->_head_idx += sizeof(entry->len);
134
135 entry->val = &self->_mem[self->_head_idx];
136 self->_head_idx += entry->len;
137
138 result = true;
139 }
140
141 return result;
142}
143
145static void tlv_buf_reset_head(struct tlv_buf *self)
146{
147 assert(self);
148 self->_head_idx = 0u;
149}
150
152static void tlv_buf_reset(struct tlv_buf *self)
153{
154 assert(self);
155 self->_head_idx = 0u;
156 self->_tail_idx = 0u;
157}
158
160static size_t tlv_buf_get_occupied_mem_size(struct tlv_buf *self)
161{
162 assert(self);
163
164 return self->_tail_idx;
165}
166
168static size_t tlv_buf_get_free_mem_size(struct tlv_buf *self)
169{
170 assert(self);
171
172 return self->_cap - self->_tail_idx;
173}
Definition tlv.h:52
Definition tlv.h:45
tlv_tag_t tag
Definition tlv.h:46
tlv_len_t len
Definition tlv.h:47
void * val
Definition tlv.h:48
static size_t tlv_buf_get_free_mem_size(struct tlv_buf *self)
Definition tlv.h:168
static bool tlv_buf_push(struct tlv_buf *self, struct tlv_entry *entry)
Definition tlv.h:86
static void tlv_buf_init(struct tlv_buf *self, uint8_t *mem, const size_t cap)
Definition tlv.h:62
static void tlv_buf_reset(struct tlv_buf *self)
Definition tlv.h:152
static void tlv_buf_reset_head(struct tlv_buf *self)
Definition tlv.h:145
static bool tlv_buf_pop(struct tlv_buf *self, struct tlv_entry *entry)
Definition tlv.h:118
static void tlv_entry_init(struct tlv_entry *self, const uint8_t tag, const uint8_t len, void *val)
Definition tlv.h:74
static size_t tlv_buf_get_occupied_mem_size(struct tlv_buf *self)
Definition tlv.h:160
uint8_t tlv_len_t
Definition tlv.h:38
uint8_t tlv_tag_t
Definition tlv.h:37