blob: 28b2fa121c80b87d4af7d0050095f15454f4540a [file] [log] [blame]
Alexander Afanasyev74633892015-02-08 18:08:46 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi6617e492016-01-19 07:33:00 -07003 * Copyright (c) 2013-2016 Regents of the University of California.
Alexander Afanasyev74633892015-02-08 18:08:46 -08004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#ifndef NDN_ENCODING_ENCODER_HPP
23#define NDN_ENCODING_ENCODER_HPP
24
25#include "../common.hpp"
26#include "block.hpp"
27
28namespace ndn {
29namespace encoding {
30
31/**
32 * @brief Helper class to perform TLV encoding
33 * Interface of this class (mostly) matches interface of Estimator class
34 * @sa Estimator
35 */
36class Encoder
37{
38public: // common interface between Encoder and Estimator
39 /**
40 * @brief Create instance of the encoder with the specified reserved sizes
Davide Pesavento18cf81b2015-09-12 23:36:43 +020041 * @param totalReserve initial buffer size to reserve
42 * @param reserveFromBack number of bytes to reserve for append* operations
Alexander Afanasyev74633892015-02-08 18:08:46 -080043 */
44 explicit
susmit8b156552016-01-12 13:10:55 -070045 Encoder(size_t totalReserve = MAX_NDN_PACKET_SIZE, size_t reserveFromBack = 400);
Alexander Afanasyev74633892015-02-08 18:08:46 -080046
47 Encoder(const Encoder&) = delete;
48
49 Encoder&
50 operator=(const Encoder&) = delete;
51
52 /**
53 * @brief Prepend a byte
54 */
55 size_t
56 prependByte(uint8_t value);
57
58 /**
59 * @brief Append a byte
60 */
61 size_t
62 appendByte(uint8_t value);
63
64 /**
65 * @brief Prepend a byte array @p array of length @p length
66 */
67 size_t
68 prependByteArray(const uint8_t* array, size_t length);
69
70 /**
71 * @brief Append a byte array @p array of length @p length
72 */
73 size_t
74 appendByteArray(const uint8_t* array, size_t length);
75
76 /**
77 * @brief Prepend range of bytes from the range [@p first, @p last)
78 */
79 template<class Iterator>
80 size_t
81 prependRange(Iterator first, Iterator last);
82
83 /**
84 * @brief Append range of bytes from the range [@p first, @p last)
85 */
86 template<class Iterator>
87 size_t
88 appendRange(Iterator first, Iterator last);
89
90 /**
91 * @brief Prepend VarNumber @p varNumber of NDN TLV encoding
92 * @sa http://named-data.net/doc/ndn-tlv/
93 */
94 size_t
95 prependVarNumber(uint64_t varNumber);
96
97 /**
98 * @brief Prepend VarNumber @p varNumber of NDN TLV encoding
99 * @sa http://named-data.net/doc/ndn-tlv/
100 */
101 size_t
102 appendVarNumber(uint64_t varNumber);
103
104 /**
105 * @brief Prepend non-negative integer @p integer of NDN TLV encoding
106 * @sa http://named-data.net/doc/ndn-tlv/
107 */
108 size_t
109 prependNonNegativeInteger(uint64_t integer);
110
111 /**
112 * @brief Append non-negative integer @p integer of NDN TLV encoding
113 * @sa http://named-data.net/doc/ndn-tlv/
114 */
115 size_t
116 appendNonNegativeInteger(uint64_t integer);
117
118 /**
119 * @brief Prepend TLV block of type @p type and value from buffer @p array of size @p arraySize
120 */
121 size_t
122 prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize);
123
124 /**
125 * @brief Append TLV block of type @p type and value from buffer @p array of size @p arraySize
126 */
127 size_t
128 appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize);
129
130 /**
131 * @brief Prepend TLV block @p block
132 */
133 size_t
134 prependBlock(const Block& block);
135
136 /**
137 * @brief Append TLV block @p block
138 */
139 size_t
140 appendBlock(const Block& block);
141
142public: // unique interface to the Encoder
143 typedef Buffer::value_type value_type;
144 typedef Buffer::iterator iterator;
145 typedef Buffer::const_iterator const_iterator;
146
147 /**
148 * @brief Create EncodingBlock from existing block
149 *
150 * This is a dangerous constructor and should be used with caution.
151 * It will modify contents of the buffer that is used by block and may
152 * impact data in other blocks.
153 *
154 * The primary purpose for this method is to be used to extend Block
155 * after sign operation.
156 */
157 explicit
158 Encoder(const Block& block);
159
160 /**
161 * @brief Reserve @p size bytes for the underlying buffer
Alexander Afanasyevf2a46222015-09-17 18:01:30 -0700162 * @param size amount of bytes to reserve in the underlying buffer
Alexander Afanasyev74633892015-02-08 18:08:46 -0800163 * @param addInFront if true, then @p size bytes will be available in front (i.e., subsequent call
164 * to prepend* will not need to allocate memory). If false, then reservation will be done
165 * at the end of the buffer (i.d., for subsequent append* calls)
166 * @note Reserve size is exact, unlike reserveFront and reserveBack methods
167 * @sa reserveFront, reserveBack
168 */
169 void
170 reserve(size_t size, bool addInFront);
171
172 /**
173 * @brief Reserve at least @p size bytes at the back of the underlying buffer
174 * @note the actual reserve size can be (and in most cases is) larger than specified reservation
175 * length
176 */
177 void
178 reserveBack(size_t size);
179
180 /**
181 * @brief Reserve at least @p isze bytes at the beginning of the underlying buffer
182 * @note the actual reserve size can be (and in most cases is) larger than specified reservation
183 * length
184 */
185 void
186 reserveFront(size_t size);
187
188 /**
189 * @brief Get size of the underlying buffer
190 */
191 size_t
192 capacity() const;
193
194 /**
195 * @brief Get underlying buffer
196 */
197 shared_ptr<Buffer>
198 getBuffer();
199
200public: // accessors
201
202 /**
203 * @brief Get an iterator pointing to the first byte of the encoded buffer
204 */
205 iterator
206 begin();
207
208 /**
209 * @brief Get an iterator pointing to the past-the-end byte of the encoded buffer
210 */
211 iterator
212 end();
213
214 /**
215 * @brief Get an iterator pointing to the first byte of the encoded buffer
216 */
217 const_iterator
218 begin() const;
219
220 const_iterator
221 end() const;
222
223 /**
224 * @brief Get a pointer to the first byte of the encoded buffer
225 */
226 uint8_t*
227 buf();
228
229 /**
230 * @brief Get a pointer to the first byte of the encoded buffer
231 */
232 const uint8_t*
233 buf() const;
234
235 /**
236 * @brief Get size of the encoded buffer
237 */
238 size_t
239 size() const;
240
241 /**
242 * @brief Create Block from the underlying buffer
243 *
244 * @param verifyLength If this parameter set to true, Block's constructor
245 * will be requested to verify consistency of the encoded
246 * length in the Block, otherwise ignored
247 */
248 Block
249 block(bool verifyLength = true) const;
250
251private:
252 shared_ptr<Buffer> m_buffer;
253
254 // invariant: m_begin always points to the position of last-written byte (if prepending data)
255 iterator m_begin;
256 // invariant: m_end always points to the position of next unwritten byte (if appending data)
257 iterator m_end;
258};
259
260
261inline size_t
262Encoder::size() const
263{
264 return m_end - m_begin;
265}
266
267inline shared_ptr<Buffer>
268Encoder::getBuffer()
269{
270 return m_buffer;
271}
272
273inline size_t
274Encoder::capacity() const
275{
276 return m_buffer->size();
277}
278
279inline Buffer::iterator
280Encoder::begin()
281{
282 return m_begin;
283}
284
285inline Buffer::iterator
286Encoder::end()
287{
288 return m_end;
289}
290
291inline Buffer::const_iterator
292Encoder::begin() const
293{
294 return m_begin;
295}
296
297inline Buffer::const_iterator
298Encoder::end() const
299{
300 return m_end;
301}
302
303inline uint8_t*
304Encoder::buf()
305{
306 return &(*m_begin);
307}
308
309inline const uint8_t*
310Encoder::buf() const
311{
312 return &(*m_begin);
313}
314
315template<class Iterator>
316inline size_t
317Encoder::prependRange(Iterator first, Iterator last)
318{
319 size_t length = std::distance(first, last);
320 reserveFront(length);
321
322 m_begin -= length;
323 std::copy(first, last, m_begin);
324 return length;
325}
326
327
328template<class Iterator>
329inline size_t
330Encoder::appendRange(Iterator first, Iterator last)
331{
332 size_t length = std::distance(first, last);
333 reserveBack(length);
334
335 std::copy(first, last, m_end);
336 m_end += length;
337 return length;
338}
339
340
341} // namespace encoding
342} // namespace ndn
343
344#endif // NDN_ENCODING_ENCODER_HPP