esp8266ndn
NDN Arduino library for ESP8266 and more
Loading...
Searching...
No Matches
encoder.hpp
Go to the documentation of this file.
1#ifndef NDNPH_TLV_ENCODER_HPP
2#define NDNPH_TLV_ENCODER_HPP
3
4#include "../core/region.hpp"
5#include "varnum.hpp"
6
7namespace ndnph {
8
10class Encoder {
11public:
13 explicit Encoder(uint8_t* buf, size_t capacity) {
14 init(buf, capacity);
15 }
16
22 explicit Encoder(Region& region)
23 : m_region(&region) {
24 size_t capacity = region.available();
25 init(region.alloc(capacity), capacity);
26 }
27
29 explicit operator bool() const {
30 return m_pos != nullptr;
31 }
32
34 const uint8_t* begin() const {
35 return m_pos;
36 }
37
39 const uint8_t* end() const {
40 return m_pos == nullptr ? nullptr : m_end;
41 }
42
44 size_t size() const {
45 return m_pos == nullptr ? 0 : m_end - m_pos;
46 }
47
49 size_t availableHeadroom() const {
50 return m_pos == nullptr ? 0 : m_pos - m_buf;
51 }
52
58 void trim() const {
59 if (m_region == nullptr) {
60 return;
61 }
62 m_region->free(m_buf, (m_pos == nullptr ? m_end : m_pos) - m_buf);
63 const_cast<Encoder*>(this)->m_buf = m_pos;
64 }
65
72 void discard() {
73 if (m_region == nullptr || m_buf == nullptr) {
74 return;
75 }
76 m_region->free(m_buf, m_end - m_buf);
77 m_buf = m_pos = m_end = nullptr;
78 }
79
81 void resetFront(uint8_t* pos) {
82 m_pos = pos;
83 }
84
90 uint8_t* prependRoom(size_t size) {
91 if (m_pos == nullptr || m_pos - m_buf < static_cast<ssize_t>(size)) {
92 m_pos = nullptr;
93 } else {
94 m_pos -= size;
95 }
96 return m_pos;
97 }
98
103 bool prependTypeLength(uint32_t type, size_t length) {
104 size_t sizeT = tlv::sizeofVarNum(type);
105 size_t sizeL = tlv::sizeofVarNum(length);
106 uint8_t* room = prependRoom(sizeT + sizeL);
107 if (room == nullptr) {
108 return false;
109 }
110 tlv::writeVarNum(room, type);
111 tlv::writeVarNum(room + sizeT, length);
112 return true;
113 }
114
122 template<typename First, typename... Arg>
123 bool prepend(const First& first, const Arg&... arg) {
124 prepend(arg...);
125 prependOne(first);
126 return !!*this;
127 }
128
133
142 template<typename... Arg>
143 bool prependTlv(uint32_t type, OmitEmptyTag omitEmpty, const Arg&... arg) {
144 uint8_t* after = m_pos;
145 bool ok = prepend(arg...);
146 size_t length = after - m_pos;
147 if (length == 0 && omitEmpty == OmitEmpty) {
148 return ok;
149 }
150 return ok && prependTypeLength(type, length);
151 }
152
154 template<typename First, typename... Arg>
155 typename std::enable_if<!std::is_same<First, OmitEmptyTag>::value, bool>::type prependTlv(
156 uint32_t type, const First& first, const Arg&... arg) {
157 return prependTlv(type, NoOmitEmpty, first, arg...);
158 }
159
161 bool prependTlv(uint32_t type) {
162 return prependTypeLength(type, 0);
163 }
164
166 void setError() {
167 m_pos = nullptr;
168 }
169
170private:
171 void init(uint8_t* buf, size_t capacity) {
172 m_buf = buf;
173 m_pos = m_end = buf + capacity;
174 }
175
176 bool prepend() {
177 return true;
178 }
179
180 template<typename T>
181 void prependOne(const T& encodeFunc, decltype(&T::operator()) = nullptr) {
182 encodeFunc(*this);
183 }
184
185 template<typename T>
186 void prependOne(const T& encodable, decltype(&T::encodeTo) = nullptr) {
187 encodable.encodeTo(*this);
188 }
189
190private:
191 Region* m_region = nullptr;
192 uint8_t* m_buf = nullptr;
193 uint8_t* m_pos = nullptr;
194 uint8_t* m_end = nullptr;
195};
196
198class ScopedEncoder : public Encoder {
199public:
200 using Encoder::Encoder;
201
203 discard();
204 }
205};
206
207} // namespace ndnph
208
209#endif // NDNPH_TLV_ENCODER_HPP
TLV encoder that accepts items in reverse order.
Definition encoder.hpp:10
bool prepend(const First &first, const Arg &... arg)
Prepend a sequence of values.
Definition encoder.hpp:123
std::enable_if<!std::is_same< First, OmitEmptyTag >::value, bool >::type prependTlv(uint32_t type, const First &first, const Arg &... arg)
Prepend TLV, measuring TLV-LENGTH automatically.
Definition encoder.hpp:155
void trim() const
Release unused space to the Region.
Definition encoder.hpp:58
bool prependTypeLength(uint32_t type, size_t length)
Prepend TLV-TYPE and TLV-LENGTH.
Definition encoder.hpp:103
size_t availableHeadroom() const
Get available headroom.
Definition encoder.hpp:49
Encoder(Region &region)
Create over remaining space in a Region.
Definition encoder.hpp:22
OmitEmptyTag
Definition encoder.hpp:129
@ NoOmitEmpty
Definition encoder.hpp:130
@ OmitEmpty
Definition encoder.hpp:131
uint8_t * prependRoom(size_t size)
Make room to prepend an object.
Definition encoder.hpp:90
bool prependTlv(uint32_t type)
Prepend TLV with zero TLV-LENGTH.
Definition encoder.hpp:161
void discard()
Release all space to the Region.
Definition encoder.hpp:72
Encoder(uint8_t *buf, size_t capacity)
Create over given buffer.
Definition encoder.hpp:13
const uint8_t * begin() const
Get output begin.
Definition encoder.hpp:34
bool prependTlv(uint32_t type, OmitEmptyTag omitEmpty, const Arg &... arg)
Prepend TLV, measuring TLV-LENGTH automatically.
Definition encoder.hpp:143
void setError()
Indicate an error has occurred.
Definition encoder.hpp:166
size_t size() const
Get output size.
Definition encoder.hpp:44
const uint8_t * end() const
Get output end.
Definition encoder.hpp:39
void resetFront(uint8_t *pos)
Reset front to given position.
Definition encoder.hpp:81
Region-based memory allocator thats owns memory of NDNph objects.
Definition region.hpp:9
size_t available() const
Compute remaining space for alloc().
Definition region.hpp:106
uint8_t * alloc(size_t size)
Allocate a buffer with no alignment requirement.
Definition region.hpp:27
bool free(const uint8_t *first, const uint8_t *last)
Deallocate (part of) last allocated buffer.
Definition region.hpp:51
Encoder that auto-discards upon destruction.
Definition encoder.hpp:198
~ScopedEncoder()
Definition encoder.hpp:202
void writeVarNum(uint8_t *room, uint32_t n)
Write VAR-NUMBER.
Definition varnum.hpp:17
constexpr size_t sizeofVarNum(uint32_t n)
Compute size of VAR-NUMBER.
Definition varnum.hpp:11
Definition fs.hpp:33