esp8266ndn
NDN Arduino library for ESP8266 and more
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
component.hpp
Go to the documentation of this file.
1#ifndef NDNPH_PACKET_COMPONENT_HPP
2#define NDNPH_PACKET_COMPONENT_HPP
3
4#include "../core/printing.hpp"
5#include "../core/region.hpp"
6#include "../tlv/value.hpp"
7#include "an.hpp"
8
9namespace ndnph {
10
16class Component : public Printable {
17public:
18 explicit Component() = default;
19
21 explicit Component(Region& region, uint16_t type, size_t length, const uint8_t* value)
22 : Component(region.alloc(computeSize(type, length)), computeSize(type, length), type, length,
23 value) {}
24
26 explicit Component(Region& region, size_t length, const uint8_t* value)
27 : Component(region, TT::GenericNameComponent, length, value) {}
28
38 explicit Component(uint8_t* buf, size_t bufLen, uint16_t type, size_t length,
39 const uint8_t* value, bool writeFromBack = false)
40 : m_type(type)
41 , m_length(length) {
42 size_t sizeofTlv = computeSize(type, length);
43 if (buf == nullptr || bufLen < sizeofTlv) {
44 m_type = 0;
45 return;
46 }
47 if (writeFromBack) {
48 buf = buf + bufLen - sizeofTlv;
49 }
50
51 size_t sizeofT = tlv::sizeofVarNum(type);
52 size_t sizeofL = tlv::sizeofVarNum(length);
53 uint8_t* valueBuf = &buf[sizeofT + sizeofL];
54 if (value != valueBuf) {
55 std::memmove(valueBuf, value, length);
56 }
58 tlv::writeVarNum(&buf[sizeofT], length);
59 m_tlv = buf;
60 m_value = valueBuf;
61 }
62
64 static Component constant(const uint8_t* tlv, size_t size) {
65 Component comp;
66 Decoder(tlv, size).decode(comp);
67 return comp;
68 }
69
74 template<typename... Arg>
75 static Component from(Region& region, uint16_t type, const Arg&... arg) {
76 Encoder encoder(region);
78 Component comp;
79 if (encoder.prependTlv(type, arg...) && Decoder::readTlv(d, encoder.begin(), encoder.end()) &&
80 comp.decodeFrom(d)) {
81 encoder.trim();
82 } else {
83 encoder.discard();
84 }
85 return comp;
86 }
87
97 static Component parse(Region& region, const char* uri) {
98 return parse(region, uri, std::strlen(uri));
99 }
100
101 static Component parse(Region& region, const char* uri, size_t uriLen) {
102 size_t bufLen = 8 + uriLen;
103 uint8_t* buf = region.alloc(bufLen);
104 if (buf == nullptr) {
105 return Component();
106 }
107 Component comp = parse(buf, bufLen, uri, uriLen, true);
108 region.free(buf, !comp ? bufLen : comp.m_tlv - buf);
109 return comp;
110 }
111
113 static Component parse(uint8_t* buf, size_t bufLen, const char* uri) {
114 return parse(buf, bufLen, uri, std::strlen(uri));
115 }
116
117 static Component parse(uint8_t* buf, size_t bufLen, const char* uri, size_t uriLen,
118 bool writeFromBack = false) {
119 const char* uriEnd = uri + uriLen;
120 const char* posEqual = std::find(uri, uriEnd, '=');
122 if (posEqual != uriEnd) {
123 type = std::strtoul(uri, nullptr, 10);
124 uri = posEqual + 1;
125 }
126
127 size_t valueOffset = std::min(bufLen, tlv::sizeofVarNum(type) + tlv::sizeofVarNum(uriLen));
128 uint8_t* valueBuf = buf + valueOffset; // write TLV-VALUE in place in most cases
129 ssize_t length = parseUriValue(valueBuf, bufLen - valueOffset, uri, uriEnd);
130 if (length < 0) {
131 return Component();
132 }
133 return Component(buf, bufLen, type, length, valueBuf, writeFromBack);
134 }
135
137 explicit operator bool() const {
138 return m_type != 0;
139 }
140
141 uint16_t type() const {
142 return m_type;
143 }
144
145 size_t length() const {
146 return m_length;
147 }
148
149 const uint8_t* value() const {
150 return m_value;
151 }
152
153 const uint8_t* tlv() const {
154 return m_tlv;
155 }
156
157 size_t size() const {
158 return m_value - m_tlv + m_length;
159 }
160
161 void encodeTo(Encoder& encoder) const {
162 if (m_type == 0) {
163 encoder.setError();
164 return;
165 }
166 encoder.prepend(tlv::Value(m_tlv, size()));
167 }
168
169 bool decodeFrom(const Decoder::Tlv& d) {
170 if (d.type == 0 || d.type > 0xFFFF) {
171 return false;
172 }
173 m_tlv = d.tlv;
174 m_type = d.type;
175 m_length = d.length;
176 m_value = d.value;
177 return true;
178 }
179
180#ifdef NDNPH_PRINT_ARDUINO
181 size_t printTo(::Print& p) const final {
182 size_t count = 0;
183 printImpl([&](const char* str) { count += p.print(str); });
184 return count;
185 }
186#endif
187
188 template<typename Convention>
189 bool is() const {
190 return Convention::match(*this);
191 }
192
193 template<typename Convention, typename... Arg>
194 auto as(Arg&&... arg) const -> decltype(Convention::parse(*this, std::forward<Arg>(arg)...)) {
195 return Convention::parse(*this, std::forward<Arg>(arg)...);
196 }
197
198private:
199 static constexpr size_t computeSize(uint16_t type, size_t length) {
201 }
202
203 static ssize_t parseUriValue(uint8_t* buf, size_t bufLen, const char* uri, const char* uriEnd) {
204 if (std::count(uri, uriEnd, '.') == uriEnd - uri && uriEnd - uri >= 3) {
205 uri += 3;
206 }
207
208 for (size_t j = 0; j < bufLen; ++j) {
209 if (uri == uriEnd) {
210 return j;
211 }
212
213 if (*uri == '%' && uri + 3 <= uriEnd) {
214 char hex[] = {uri[1], uri[2], 0};
215 buf[j] = std::strtoul(hex, nullptr, 16);
216 uri += 3;
217 } else {
218 buf[j] = *uri++;
219 }
220 }
221 return -1;
222 }
223
224 template<typename F>
225 void printImpl(const F& output) const {
226 char buf[7];
227 snprintf(buf, sizeof(buf), "%d=", static_cast<int>(m_type));
228 output(buf);
229 size_t nNonPeriods = 0;
230 std::for_each(m_value, m_value + m_length, [&](uint8_t ch) {
231 if (ch != 0x00 && strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~",
232 ch) != nullptr) {
233 buf[0] = ch;
234 buf[1] = 0;
235 } else {
236 snprintf(buf, sizeof(buf), "%%%02X", static_cast<int>(ch));
237 }
238 output(buf);
239 nNonPeriods += ch != '.';
240 });
241 if (nNonPeriods == 0) {
242 output("...");
243 }
244 }
245
246#ifdef NDNPH_PRINT_OSTREAM
247 friend std::ostream& operator<<(std::ostream& os, const Component& comp) {
248 comp.printImpl([&os](const char* str) { os << str; });
249 return os;
250 }
251#endif
252
253private:
254 uint16_t m_type = 0;
255 size_t m_length = 0;
256 const uint8_t* m_tlv = nullptr;
257 const uint8_t* m_value = nullptr;
258};
259
260inline bool
261operator==(const Component& lhs, const Component& rhs) {
262 return lhs.size() == rhs.size() && std::equal(lhs.tlv(), lhs.tlv() + lhs.size(), rhs.tlv());
263}
264
265NDNPH_DECLARE_NE(Component, inline)
266
267} // namespace ndnph
268
269#endif // NDNPH_PACKET_COMPONENT_HPP
Name component.
Definition component.hpp:16
size_t printTo(::Print &p) const final
Definition component.hpp:181
void encodeTo(Encoder &encoder) const
Definition component.hpp:161
Component()=default
size_t length() const
Definition component.hpp:145
Component(Region &region, size_t length, const uint8_t *value)
Construct GenericNameComponent from L-V.
Definition component.hpp:26
static Component constant(const uint8_t *tlv, size_t size)
Construct from const TLV buffer.
Definition component.hpp:64
static Component parse(Region &region, const char *uri, size_t uriLen)
Definition component.hpp:101
uint16_t type() const
Definition component.hpp:141
auto as(Arg &&... arg) const -> decltype(Convention::parse(*this, std::forward< Arg >(arg)...))
Definition component.hpp:194
size_t size() const
Definition component.hpp:157
static Component from(Region &region, uint16_t type, const Arg &... arg)
Construct from TLV-TYPE, and several arguments to be encoded to TLV-VALUE.
Definition component.hpp:75
const uint8_t * value() const
Definition component.hpp:149
static Component parse(Region &region, const char *uri)
Parse from URI.
Definition component.hpp:97
bool is() const
Definition component.hpp:189
static Component parse(uint8_t *buf, size_t bufLen, const char *uri, size_t uriLen, bool writeFromBack=false)
Definition component.hpp:117
const uint8_t * tlv() const
Definition component.hpp:153
Component(uint8_t *buf, size_t bufLen, uint16_t type, size_t length, const uint8_t *value, bool writeFromBack=false)
Construct from T-L-V into provided buffer.
Definition component.hpp:38
bool decodeFrom(const Decoder::Tlv &d)
Definition component.hpp:169
Component(Region &region, uint16_t type, size_t length, const uint8_t *value)
Construct from T-L-V.
Definition component.hpp:21
static Component parse(uint8_t *buf, size_t bufLen, const char *uri)
Parse from URI into provided buffer.
Definition component.hpp:113
Decoded TLV.
Definition decoder.hpp:13
const uint8_t * tlv
Definition decoder.hpp:42
uint32_t type
Definition decoder.hpp:38
size_t length
Definition decoder.hpp:39
const uint8_t * value
Definition decoder.hpp:40
TLV decoder.
Definition decoder.hpp:10
static bool readTlv(Tlv &d, const uint8_t *input, const uint8_t *end)
Definition decoder.hpp:46
bool decode(T &target) const
Decode first TLV into target object.
Definition decoder.hpp:158
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
void trim() const
Release unused space to the Region.
Definition encoder.hpp:58
void discard()
Release all space to the Region.
Definition encoder.hpp:72
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
const uint8_t * end() const
Get output end.
Definition encoder.hpp:39
Definition printing.hpp:22
Region-based memory allocator thats owns memory of NDNph objects.
Definition region.hpp:9
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
A sequence of bytes, usually TLV-VALUE.
Definition value.hpp:11
@ GenericNameComponent
Definition an.hpp:20
void output(const Encodable &packet, std::ostream &os=std::cout)
Write an Encodable to output stream.
Definition io.hpp:33
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
bool operator==(const ValidityPeriod &lhs, const ValidityPeriod &rhs)
Definition validity-period.hpp:156
#define NDNPH_DECLARE_NE(T, specifier)
Declare operator!= in terms of operator==.
Definition operators.hpp:7