blob: a258d1e26484a3f880e592ce19e668755f6793a2 [file] [log] [blame]
Alexander Afanasyev74633892015-02-08 18:08:46 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2015 Regents of the University of California.
4 *
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
41 * @param totalReserve initial buffer size to reserve
42 * @param totalFromBack number of bytes to reserve for append* operations
43 */
44 explicit
45 Encoder(size_t totalReserve = 8800, size_t reserveFromBack = 400);
46
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
162 * @param addInFront if true, then @p size bytes will be available in front (i.e., subsequent call
163 * to prepend* will not need to allocate memory). If false, then reservation will be done
164 * at the end of the buffer (i.d., for subsequent append* calls)
165 * @note Reserve size is exact, unlike reserveFront and reserveBack methods
166 * @sa reserveFront, reserveBack
167 */
168 void
169 reserve(size_t size, bool addInFront);
170
171 /**
172 * @brief Reserve at least @p size bytes at the back of the underlying buffer
173 * @note the actual reserve size can be (and in most cases is) larger than specified reservation
174 * length
175 */
176 void
177 reserveBack(size_t size);
178
179 /**
180 * @brief Reserve at least @p isze bytes at the beginning of the underlying buffer
181 * @note the actual reserve size can be (and in most cases is) larger than specified reservation
182 * length
183 */
184 void
185 reserveFront(size_t size);
186
187 /**
188 * @brief Get size of the underlying buffer
189 */
190 size_t
191 capacity() const;
192
193 /**
194 * @brief Get underlying buffer
195 */
196 shared_ptr<Buffer>
197 getBuffer();
198
199public: // accessors
200
201 /**
202 * @brief Get an iterator pointing to the first byte of the encoded buffer
203 */
204 iterator
205 begin();
206
207 /**
208 * @brief Get an iterator pointing to the past-the-end byte of the encoded buffer
209 */
210 iterator
211 end();
212
213 /**
214 * @brief Get an iterator pointing to the first byte of the encoded buffer
215 */
216 const_iterator
217 begin() const;
218
219 const_iterator
220 end() const;
221
222 /**
223 * @brief Get a pointer to the first byte of the encoded buffer
224 */
225 uint8_t*
226 buf();
227
228 /**
229 * @brief Get a pointer to the first byte of the encoded buffer
230 */
231 const uint8_t*
232 buf() const;
233
234 /**
235 * @brief Get size of the encoded buffer
236 */
237 size_t
238 size() const;
239
240 /**
241 * @brief Create Block from the underlying buffer
242 *
243 * @param verifyLength If this parameter set to true, Block's constructor
244 * will be requested to verify consistency of the encoded
245 * length in the Block, otherwise ignored
246 */
247 Block
248 block(bool verifyLength = true) const;
249
250private:
251 shared_ptr<Buffer> m_buffer;
252
253 // invariant: m_begin always points to the position of last-written byte (if prepending data)
254 iterator m_begin;
255 // invariant: m_end always points to the position of next unwritten byte (if appending data)
256 iterator m_end;
257};
258
259
260inline size_t
261Encoder::size() const
262{
263 return m_end - m_begin;
264}
265
266inline shared_ptr<Buffer>
267Encoder::getBuffer()
268{
269 return m_buffer;
270}
271
272inline size_t
273Encoder::capacity() const
274{
275 return m_buffer->size();
276}
277
278inline Buffer::iterator
279Encoder::begin()
280{
281 return m_begin;
282}
283
284inline Buffer::iterator
285Encoder::end()
286{
287 return m_end;
288}
289
290inline Buffer::const_iterator
291Encoder::begin() const
292{
293 return m_begin;
294}
295
296inline Buffer::const_iterator
297Encoder::end() const
298{
299 return m_end;
300}
301
302inline uint8_t*
303Encoder::buf()
304{
305 return &(*m_begin);
306}
307
308inline const uint8_t*
309Encoder::buf() const
310{
311 return &(*m_begin);
312}
313
314template<class Iterator>
315inline size_t
316Encoder::prependRange(Iterator first, Iterator last)
317{
318 size_t length = std::distance(first, last);
319 reserveFront(length);
320
321 m_begin -= length;
322 std::copy(first, last, m_begin);
323 return length;
324}
325
326
327template<class Iterator>
328inline size_t
329Encoder::appendRange(Iterator first, Iterator last)
330{
331 size_t length = std::distance(first, last);
332 reserveBack(length);
333
334 std::copy(first, last, m_end);
335 m_end += length;
336 return length;
337}
338
339
340} // namespace encoding
341} // namespace ndn
342
343#endif // NDN_ENCODING_ENCODER_HPP