esp8266ndn
NDN Arduino library for ESP8266 and more
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
decoder.hpp
Go to the documentation of this file.
1 #ifndef NDNPH_TLV_DECODER_HPP
2 #define NDNPH_TLV_DECODER_HPP
3 
4 #include "../core/operators.hpp"
5 #include "varnum.hpp"
6 
7 namespace ndnph {
8 
10 class Decoder {
11 public:
13  class Tlv {
14  public:
16  explicit operator bool() const {
17  return size != 0;
18  }
19 
27  template<typename T>
28  bool decode(T& target) const {
29  return *this && target.decodeFrom(*this);
30  }
31 
33  Decoder vd() const {
34  return Decoder(value, length);
35  }
36 
37  public:
38  uint32_t type = 0;
39  size_t length = 0;
40  const uint8_t* value = nullptr;
41 
42  const uint8_t* tlv = nullptr;
43  size_t size = 0;
44  };
45 
46  static bool readTlv(Tlv& d, const uint8_t* input, const uint8_t* end) {
47  if (input == end) {
48  d = Tlv{};
49  return true;
50  }
51  int sizeofT = tlv::readVarNum(input, end - input, d.type);
52  if (sizeofT == 0) {
53  return false;
54  }
55  const uint8_t* posL = input + sizeofT;
56  uint32_t length;
57  int sizeofL = tlv::readVarNum(posL, end - posL, length);
58  if (sizeofL == 0) {
59  return false;
60  }
61  d.length = length;
62  d.value = posL + sizeofL;
63  d.tlv = input;
64  d.size = sizeofT + sizeofL + length;
65  return end - d.value >= static_cast<ssize_t>(length);
66  }
67 
69  class Iterator {
70  public:
71  using iterator_category = std::forward_iterator_tag;
72  using value_type = const Tlv;
73  using difference_type = std::ptrdiff_t;
74  using pointer = value_type*;
76 
77  Iterator() = default;
78 
79  explicit Iterator(const uint8_t* pos, const uint8_t* end)
80  : m_pos(pos)
81  , m_end(end) {
82  tryRead();
83  }
84 
86  bool hasError() const {
87  return m_pos == nullptr;
88  }
89 
96  m_pos = m_tlv.value + m_tlv.length;
97  tryRead();
98  return *this;
99  }
100 
102  Iterator copy(*this);
103  ++*this;
104  return copy;
105  }
106 
113  return m_tlv;
114  }
115 
117  return &m_tlv;
118  }
119 
120  friend bool operator==(const Iterator& lhs, const Iterator& rhs) {
121  return (lhs.m_end - lhs.m_pos) == (rhs.m_end - rhs.m_pos);
122  }
123 
124  NDNPH_DECLARE_NE(Iterator, friend)
125 
126  private:
127  void tryRead() {
128  if (readTlv(m_tlv, m_pos, m_end)) {
129  return;
130  }
131  m_tlv = Tlv{};
132  m_pos = m_end = nullptr;
133  }
134 
135  private:
136  const uint8_t* m_pos = nullptr;
137  const uint8_t* m_end = nullptr;
138  Tlv m_tlv;
139  };
140 
141  explicit Decoder(const uint8_t* input, size_t count)
142  : m_begin(input)
143  , m_end(input + count) {}
144 
145  Iterator begin() const {
146  return Iterator(m_begin, m_end);
147  }
148 
149  Iterator end() const {
150  return Iterator(m_end, m_end);
151  }
152 
157  template<typename T>
158  bool decode(T& target) const {
159  return begin()->decode(target);
160  }
161 
162 private:
163  const uint8_t* m_begin;
164  const uint8_t* m_end;
165 };
166 
167 } // namespace ndnph
168 
169 #endif // NDNPH_TLV_DECODER_HPP
Iterator over TLV elements.
Definition: decoder.hpp:69
friend bool operator==(const Iterator &lhs, const Iterator &rhs)
Definition: decoder.hpp:120
std::ptrdiff_t difference_type
Definition: decoder.hpp:73
bool hasError() const
Whether a decoding error has occurred.
Definition: decoder.hpp:86
pointer operator->()
Definition: decoder.hpp:116
reference operator*()
Obtain Decoder::Tlv.
Definition: decoder.hpp:112
Iterator operator++(int)
Definition: decoder.hpp:101
Iterator & operator++()
Increment to next TLV element.
Definition: decoder.hpp:95
Iterator(const uint8_t *pos, const uint8_t *end)
Definition: decoder.hpp:79
std::forward_iterator_tag iterator_category
Definition: decoder.hpp:71
Decoded TLV.
Definition: decoder.hpp:13
const uint8_t * tlv
Definition: decoder.hpp:42
Decoder vd() const
Create Decoder over TLV-VALUE.
Definition: decoder.hpp:33
uint32_t type
Definition: decoder.hpp:38
size_t length
Definition: decoder.hpp:39
size_t size
Definition: decoder.hpp:43
bool decode(T &target) const
Decode into target object.
Definition: decoder.hpp:28
const uint8_t * value
Definition: decoder.hpp:40
TLV decoder.
Definition: decoder.hpp:10
Iterator begin() const
Definition: decoder.hpp:145
Decoder(const uint8_t *input, size_t count)
Definition: decoder.hpp:141
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
Iterator end() const
Definition: decoder.hpp:149
bool input(Region &region, T &target, std::istream &is=std::cin)
Read and decode from input stream.
Definition: io.hpp:15
int readVarNum(const uint8_t *input, size_t size, uint32_t &n)
Read VAR-NUMBER.
Definition: varnum.hpp:38
Definition: fs.hpp:33
#define NDNPH_DECLARE_NE(T, specifier)
Declare operator!= in terms of operator==.
Definition: operators.hpp:7