encoder.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "encoder.hpp"
23 
24 namespace ndn {
25 namespace encoding {
26 
27 Encoder::Encoder(size_t totalReserve/* = MAX_NDN_PACKET_SIZE*/, size_t reserveFromBack/* = 400*/)
28  : m_buffer(new Buffer(totalReserve))
29 {
30  m_begin = m_end = m_buffer->end() - (reserveFromBack < totalReserve ? reserveFromBack : 0);
31 }
32 
33 
35  : m_buffer(const_pointer_cast<Buffer>(block.getBuffer()))
36  , m_begin(m_buffer->begin() + (block.begin() - m_buffer->begin()))
37  , m_end(m_buffer->begin() + (block.end() - m_buffer->begin()))
38 {
39 }
40 
43 
44 void
46 {
47  if ((m_end + size) > m_buffer->end())
48  reserve(m_buffer->size() * 2 + size, false);
49 }
50 
51 void
53 {
54  if ((m_buffer->begin() + size) > m_begin)
55  reserve(m_buffer->size() * 2 + size, true);
56 }
57 
58 
59 Block
60 Encoder::block(bool verifyLength/* = true*/) const
61 {
62  return Block(m_buffer,
63  m_begin, m_end,
64  verifyLength);
65 }
66 
67 void
68 Encoder::reserve(size_t size, bool addInFront)
69 {
70  if (size < m_buffer->size()) {
71  size = m_buffer->size();
72  }
73 
74  if (addInFront) {
75  size_t diffEnd = m_buffer->end() - m_end;
76  size_t diffBegin = m_buffer->end() - m_begin;
77 
78  Buffer* buf = new Buffer(size);
79  std::copy_backward(m_buffer->begin(), m_buffer->end(), buf->end());
80 
81  m_buffer.reset(buf);
82 
83  m_end = m_buffer->end() - diffEnd;
84  m_begin = m_buffer->end() - diffBegin;
85  }
86  else {
87  size_t diffEnd = m_end - m_buffer->begin();
88  size_t diffBegin = m_begin - m_buffer->begin();
89 
90  Buffer* buf = new Buffer(size);
91  std::copy(m_buffer->begin(), m_buffer->end(), buf->begin());
92 
93  m_buffer.reset(buf);
94 
95  m_end = m_buffer->begin() + diffEnd;
96  m_begin = m_buffer->begin() + diffBegin;
97  }
98 }
99 
102 
103 size_t
104 Encoder::prependByte(uint8_t value)
105 {
106  reserveFront(1);
107 
108  m_begin--;
109  *m_begin = value;
110  return 1;
111 }
112 
113 size_t
114 Encoder::appendByte(uint8_t value)
115 {
116  reserveBack(1);
117 
118  *m_end = value;
119  m_end++;
120  return 1;
121 }
122 
123 
124 size_t
125 Encoder::prependByteArray(const uint8_t* array, size_t length)
126 {
127  reserveFront(length);
128 
129  m_begin -= length;
130  std::copy(array, array + length, m_begin);
131  return length;
132 }
133 
134 size_t
135 Encoder::appendByteArray(const uint8_t* array, size_t length)
136 {
137  reserveBack(length);
138 
139  std::copy(array, array + length, m_end);
140  m_end += length;
141  return length;
142 }
143 
144 
145 size_t
146 Encoder::prependVarNumber(uint64_t varNumber)
147 {
148  if (varNumber < 253) {
149  prependByte(static_cast<uint8_t>(varNumber));
150  return 1;
151  }
152  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
153  uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
154  prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
155  prependByte(253);
156  return 3;
157  }
158  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
159  uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
160  prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
161  prependByte(254);
162  return 5;
163  }
164  else {
165  uint64_t value = htobe64(varNumber);
166  prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
167  prependByte(255);
168  return 9;
169  }
170 }
171 
172 size_t
173 Encoder::appendVarNumber(uint64_t varNumber)
174 {
175  if (varNumber < 253) {
176  appendByte(static_cast<uint8_t>(varNumber));
177  return 1;
178  }
179  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
180  appendByte(253);
181  uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
182  appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
183  return 3;
184  }
185  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
186  appendByte(254);
187  uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
188  appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
189  return 5;
190  }
191  else {
192  appendByte(255);
193  uint64_t value = htobe64(varNumber);
194  appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
195  return 9;
196  }
197 }
198 
199 
200 size_t
202 {
203  if (varNumber <= std::numeric_limits<uint8_t>::max()) {
204  return prependByte(static_cast<uint8_t>(varNumber));
205  }
206  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
207  uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
208  return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
209  }
210  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
211  uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
212  return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
213  }
214  else {
215  uint64_t value = htobe64(varNumber);
216  return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
217  }
218 }
219 
220 size_t
222 {
223  if (varNumber <= std::numeric_limits<uint8_t>::max()) {
224  return appendByte(static_cast<uint8_t>(varNumber));
225  }
226  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
227  uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
228  return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
229  }
230  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
231  uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
232  return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
233  }
234  else {
235  uint64_t value = htobe64(varNumber);
236  return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
237  }
238 }
239 
240 size_t
241 Encoder::prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize)
242 {
243  size_t totalLength = prependByteArray(array, arraySize);
244  totalLength += prependVarNumber(arraySize);
245  totalLength += prependVarNumber(type);
246 
247  return totalLength;
248 }
249 
250 size_t
251 Encoder::appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize)
252 {
253  size_t totalLength = appendVarNumber(type);
254  totalLength += appendVarNumber(arraySize);
255  totalLength += appendByteArray(array, arraySize);
256 
257  return totalLength;
258 }
259 
260 size_t
262 {
263  if (block.hasWire()) {
264  return prependByteArray(block.wire(), block.size());
265  }
266  else {
267  return prependByteArrayBlock(block.type(), block.value(), block.value_size());
268  }
269 }
270 
271 size_t
273 {
274  if (block.hasWire()) {
275  return appendByteArray(block.wire(), block.size());
276  }
277  else {
278  return appendByteArrayBlock(block.type(), block.value(), block.value_size());
279  }
280 }
281 
282 } // namespace encoding
283 } // namespace ndn
size_t prependByteArray(const uint8_t *array, size_t length)
Prepend a byte array array of length length.
Definition: encoder.cpp:125
void reserveFront(size_t size)
Reserve at least isze bytes at the beginning of the underlying buffer.
Definition: encoder.cpp:52
size_t appendVarNumber(uint64_t varNumber)
Prepend VarNumber varNumber of NDN TLV encoding.
Definition: encoder.cpp:173
iterator begin()
Get an iterator pointing to the first byte of the encoded buffer.
Definition: encoder.hpp:279
Copyright (c) 2013-2017 Regents of the University of California.
Definition: common.hpp:66
size_t size() const
Get size of the encoded buffer.
Definition: encoder.hpp:261
size_t prependByte(uint8_t value)
Prepend a byte.
Definition: encoder.cpp:104
iterator end()
Get an iterator pointing to the past-the-end byte of the encoded buffer.
Definition: encoder.hpp:285
Represents a TLV element of NDN packet format.
Definition: block.hpp:42
void reserve(size_t size, bool addInFront)
Reserve size bytes for the underlying buffer.
Definition: encoder.cpp:68
void reserveBack(size_t size)
Reserve at least size bytes at the back of the underlying buffer.
Definition: encoder.cpp:45
size_t size() const
Get size of encoded wire, including Type-Length-Value.
Definition: block.cpp:301
size_t prependVarNumber(uint64_t varNumber)
Prepend VarNumber varNumber of NDN TLV encoding.
Definition: encoder.cpp:146
size_t prependBlock(const Block &block)
Prepend TLV block block.
Definition: encoder.cpp:261
size_t appendBlock(const Block &block)
Append TLV block block.
Definition: encoder.cpp:272
shared_ptr< Buffer > getBuffer()
Get underlying buffer.
Definition: encoder.hpp:267
Block block(bool verifyLength=true) const
Create Block from the underlying buffer.
Definition: encoder.cpp:60
size_t appendByte(uint8_t value)
Append a byte.
Definition: encoder.cpp:114
size_t prependByteArrayBlock(uint32_t type, const uint8_t *array, size_t arraySize)
Prepend TLV block of type type and value from buffer array of size arraySize.
Definition: encoder.cpp:241
size_t value_size() const
Get size of TLV-VALUE aka TLV-LENGTH.
Definition: block.cpp:319
size_t appendByteArray(const uint8_t *array, size_t length)
Append a byte array array of length length.
Definition: encoder.cpp:135
uint32_t type() const
Get TLV-TYPE.
Definition: block.hpp:235
uint8_t * buf()
Get a pointer to the first byte of the encoded buffer.
Definition: encoder.hpp:303
const uint8_t * wire() const
Get pointer to encoded wire.
Definition: block.cpp:292
bool hasWire() const
Check if the Block has fully encoded wire.
Definition: block.cpp:252
const uint8_t * value() const
Get pointer to TLV-VALUE.
Definition: block.cpp:313
size_t prependNonNegativeInteger(uint64_t integer)
Prepend non-negative integer integer of NDN TLV encoding.
Definition: encoder.cpp:201
size_t appendByteArrayBlock(uint32_t type, const uint8_t *array, size_t arraySize)
Append TLV block of type type and value from buffer array of size arraySize.
Definition: encoder.cpp:251
size_t appendNonNegativeInteger(uint64_t integer)
Append non-negative integer integer of NDN TLV encoding.
Definition: encoder.cpp:221
General-purpose automatically managed/resized buffer.
Definition: buffer.hpp:40
Encoder(size_t totalReserve=MAX_NDN_PACKET_SIZE, size_t reserveFromBack=400)
Create instance of the encoder with the specified reserved sizes.
Definition: encoder.cpp:27