blob: b3f891617081f5ebcbdb5e98219df2f9aa4a15a1 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Wentao Shang77949212014-02-01 23:42:24 -08004 *
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07005 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Wentao Shang77949212014-02-01 23:42:24 -08006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * 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.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Wentao Shang <http://irl.cs.ucla.edu/~wentao/>
22 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
Wentao Shang77949212014-02-01 23:42:24 -080023 */
24
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070025#ifndef NDN_ENCODING_ENCODING_BUFFER_HPP
26#define NDN_ENCODING_ENCODING_BUFFER_HPP
Wentao Shang77949212014-02-01 23:42:24 -080027
28#include "../common.hpp"
29
Wentao Shang77949212014-02-01 23:42:24 -080030#include "buffer.hpp"
Alexander Afanasyev233750e2014-02-16 00:50:07 -080031#include "block.hpp"
Wentao Shang77949212014-02-01 23:42:24 -080032
Wentao Shang77949212014-02-01 23:42:24 -080033namespace ndn {
34
Alexander Afanasyev217325b2014-02-06 15:03:28 -080035namespace encoding {
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080036static const bool Buffer = true;
37static const bool Estimator = false;
Alexander Afanasyev217325b2014-02-06 15:03:28 -080038} // encoding
39
40template<bool isRealEncoderNotEstimator>
41class EncodingImpl;
42
43typedef EncodingImpl<encoding::Buffer> EncodingBuffer;
44typedef EncodingImpl<encoding::Estimator> EncodingEstimator;
45
Wentao Shang77949212014-02-01 23:42:24 -080046/**
47 * @brief Class representing wire element of the NDN packet
48 */
Alexander Afanasyev217325b2014-02-06 15:03:28 -080049template<>
50class EncodingImpl<encoding::Buffer>
Wentao Shang77949212014-02-01 23:42:24 -080051{
52public:
Wentao Shang77949212014-02-01 23:42:24 -080053 /**
Alexander Afanasyev217325b2014-02-06 15:03:28 -080054 * @brief Constructor to create a EncodingImpl with specified reserved sizes
55 *
56 * The caller should make sure that that reserveFromBack does not exceed totalReserve,
57 * otherwise behavior is undefined.
Wentao Shang77949212014-02-01 23:42:24 -080058 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070059 EncodingImpl(size_t totalReserve = 8800,
60 size_t reserveFromBack = 400)
61 : m_buffer(new Buffer(totalReserve))
Wentao Shang77949212014-02-01 23:42:24 -080062 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070063 m_begin = m_end = m_buffer->end() - (reserveFromBack < totalReserve ? reserveFromBack : 0);
Wentao Shang77949212014-02-01 23:42:24 -080064 }
65
Alexander Afanasyev15151312014-02-16 00:53:51 -080066 /**
67 * @brief Create EncodingBlock from existing block
68 *
69 * This is a dangerous constructor and should be used with caution.
70 * It will modify contents of the buffer that is used by block and may
71 * impact data in other blocks.
72 *
73 * The primary purpose for this method is to be used to extend Block
74 * after sign operation.
75 */
76 explicit
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070077 EncodingImpl(const Block& block)
Alexander Afanasyev15151312014-02-16 00:53:51 -080078 : m_buffer(const_pointer_cast<Buffer>(block.m_buffer))
79 , m_begin(m_buffer->begin() + (block.begin() - m_buffer->begin()))
80 , m_end(m_buffer->begin() + (block.end() - m_buffer->begin()))
81 {
82 }
Wentao Shang77949212014-02-01 23:42:24 -080083
84 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070085 size() const;
86
87 inline size_t
88 capacity() const;
Wentao Shang77949212014-02-01 23:42:24 -080089
90 inline uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070091 buf();
Wentao Shang77949212014-02-01 23:42:24 -080092
93 inline const uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070094 buf() const;
Wentao Shang77949212014-02-01 23:42:24 -080095
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080096 /**
97 * @brief Create Block from the underlying EncodingBuffer
98 *
99 * @param verifyLength If this parameter set to true, Block's constructor
100 * will be requested to verify consistency of the encoded
101 * length in the Block, otherwise ignored
102 */
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800103 inline Block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700104 block(bool verifyLength = true) const;
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800105
Wentao Shang77949212014-02-01 23:42:24 -0800106 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700107 resize(size_t size, bool addInFront);
Wentao Shang77949212014-02-01 23:42:24 -0800108
109 inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700110 begin();
Wentao Shang77949212014-02-01 23:42:24 -0800111
112 inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700113 end();
Wentao Shang77949212014-02-01 23:42:24 -0800114
115 inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700116 begin() const;
Wentao Shang77949212014-02-01 23:42:24 -0800117
118 inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700119 end() const;
Wentao Shang77949212014-02-01 23:42:24 -0800120
121 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700122 prependByte(uint8_t value);
Wentao Shang77949212014-02-01 23:42:24 -0800123
124 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700125 prependByteArray(const uint8_t* array, size_t length);
Wentao Shang77949212014-02-01 23:42:24 -0800126
127 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700128 prependNonNegativeInteger(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800129
130 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700131 prependVarNumber(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800132
133 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700134 appendByte(uint8_t value);
Wentao Shang77949212014-02-01 23:42:24 -0800135
136 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700137 appendByteArray(const uint8_t* array, size_t length);
Wentao Shang77949212014-02-01 23:42:24 -0800138
139 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700140 appendNonNegativeInteger(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800141
142 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700143 appendVarNumber(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800144
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800145 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700146 // removeByteFromFront();
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800147
148 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700149 // removeByteFromEnd();
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800150
151 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700152 // removeVarNumberFromFront(uint64_t varNumber);
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800153
154 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700155 // removeVarNumberFromBack(uint64_t varNumber);
156
Wentao Shang77949212014-02-01 23:42:24 -0800157private:
158 BufferPtr m_buffer;
159
160 // invariant: m_begin always points to the position of last-written byte (if prepending data)
161 Buffer::iterator m_begin;
162 // invariant: m_end always points to the position of next unwritten byte (if appending data)
163 Buffer::iterator m_end;
Alexander Afanasyev15151312014-02-16 00:53:51 -0800164
165 friend class Block;
Wentao Shang77949212014-02-01 23:42:24 -0800166};
167
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800168
169/**
170 * @brief Class representing wire element of the NDN packet
171 */
172template<>
173class EncodingImpl<encoding::Estimator>
174{
175public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700176 EncodingImpl(size_t totalReserve = 8800,
177 size_t reserveFromBack = 400)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800178 {
179 }
180
181 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700182 prependByte(uint8_t value);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800183
184 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700185 prependByteArray(const uint8_t* array, size_t length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800186
187 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700188 prependNonNegativeInteger(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800189
190 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700191 prependVarNumber(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800192
193 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700194 appendByte(uint8_t value);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800195
196 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700197 appendByteArray(const uint8_t* array, size_t length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800198
199 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700200 appendNonNegativeInteger(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800201
202 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700203 appendVarNumber(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800204};
205
206
Wentao Shang77949212014-02-01 23:42:24 -0800207////////////////////////////////////////////////////////////////////////////////
208////////////////////////////////////////////////////////////////////////////////
209////////////////////////////////////////////////////////////////////////////////
210
211inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700212EncodingImpl<encoding::Buffer>::size() const
Wentao Shang77949212014-02-01 23:42:24 -0800213{
214 return m_end - m_begin;
215}
216
217inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700218EncodingImpl<encoding::Buffer>::capacity() const
Wentao Shang77949212014-02-01 23:42:24 -0800219{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700220 return m_buffer->size();
Wentao Shang77949212014-02-01 23:42:24 -0800221}
222
223inline uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700224EncodingImpl<encoding::Buffer>::buf()
Wentao Shang77949212014-02-01 23:42:24 -0800225{
226 return &(*m_begin);
227}
228
229inline const uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700230EncodingImpl<encoding::Buffer>::buf() const
Wentao Shang77949212014-02-01 23:42:24 -0800231{
232 return &(*m_begin);
233}
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800234
235inline Block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700236EncodingImpl<encoding::Buffer>::block(bool verifyLength/* = true*/) const
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800237{
238 return Block(m_buffer,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800239 m_begin, m_end,
240 verifyLength);
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800241}
242
Wentao Shang77949212014-02-01 23:42:24 -0800243inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700244EncodingImpl<encoding::Buffer>::resize(size_t size, bool addInFront)
Wentao Shang77949212014-02-01 23:42:24 -0800245{
246 if (addInFront)
247 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700248 size_t diff_end = m_buffer->end() - m_end;
249 size_t diff_begin = m_buffer->end() - m_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800250
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700251 Buffer* buf = new Buffer(size);
252 std::copy_backward(m_buffer->begin(), m_buffer->end(), buf->end());
Wentao Shang77949212014-02-01 23:42:24 -0800253
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700254 m_buffer.reset(buf);
Wentao Shang77949212014-02-01 23:42:24 -0800255
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700256 m_end = m_buffer->end() - diff_end;
257 m_begin = m_buffer->end() - diff_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800258 }
259 else
260 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700261 size_t diff_end = m_end - m_buffer->begin();
262 size_t diff_begin = m_begin - m_buffer->begin();
Wentao Shang77949212014-02-01 23:42:24 -0800263
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700264 Buffer* buf = new Buffer(size);
265 std::copy(m_buffer->begin(), m_buffer->end(), buf->begin());
Wentao Shang77949212014-02-01 23:42:24 -0800266
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700267 m_buffer.reset(buf);
Wentao Shang77949212014-02-01 23:42:24 -0800268
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700269 m_end = m_buffer->begin() + diff_end;
270 m_begin = m_buffer->begin() + diff_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800271 }
272}
273
274inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700275EncodingImpl<encoding::Buffer>::begin()
Wentao Shang77949212014-02-01 23:42:24 -0800276{
277 return m_begin;
278}
279
280inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700281EncodingImpl<encoding::Buffer>::end()
Wentao Shang77949212014-02-01 23:42:24 -0800282{
283 return m_end;
284}
285
286inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700287EncodingImpl<encoding::Buffer>::begin() const
Wentao Shang77949212014-02-01 23:42:24 -0800288{
289 return m_begin;
290}
291
292inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700293EncodingImpl<encoding::Buffer>::end() const
Wentao Shang77949212014-02-01 23:42:24 -0800294{
295 return m_end;
296}
297
298
299//////////////////////////////////////////////////////////
300// Prepend to the back of the buffer. Resize if needed. //
301//////////////////////////////////////////////////////////
302
303inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700304EncodingImpl<encoding::Buffer>::prependByte(uint8_t value)
Wentao Shang77949212014-02-01 23:42:24 -0800305{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700306 if (m_begin == m_buffer->begin())
307 resize(m_buffer->size() * 2, true);
Wentao Shang77949212014-02-01 23:42:24 -0800308
309 m_begin--;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700310 *m_begin = value;
Wentao Shang77949212014-02-01 23:42:24 -0800311 return 1;
312}
313
314inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700315EncodingImpl<encoding::Estimator>::prependByte(uint8_t value)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800316{
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800317 return 1;
318}
319
320inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700321EncodingImpl<encoding::Buffer>::prependByteArray(const uint8_t* array, size_t length)
Wentao Shang77949212014-02-01 23:42:24 -0800322{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700323 if ((m_buffer->begin() + length) > m_begin)
324 resize(m_buffer->size() * 2 + length, true);
Wentao Shang77949212014-02-01 23:42:24 -0800325
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700326 m_begin -= length;
327 std::copy(array, array + length, m_begin);
328 return length;
Wentao Shang77949212014-02-01 23:42:24 -0800329}
330
331inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700332EncodingImpl<encoding::Estimator>::prependByteArray(const uint8_t* array, size_t length)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800333{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700334 return length;
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800335}
336
337inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700338EncodingImpl<encoding::Buffer>::prependNonNegativeInteger(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800339{
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -0800340 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700341 return prependByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800342 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700343 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
344 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
345 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800346 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700347 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
348 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
349 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800350 }
351 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700352 uint64_t value = htobe64(varNumber);
353 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800354 }
355}
356
357inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700358EncodingImpl<encoding::Estimator>::prependNonNegativeInteger(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800359{
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -0800360 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800361 return 1;
362 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700363 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800364 return 2;
365 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700366 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800367 return 4;
368 }
369 else {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800370 return 8;
371 }
372}
373
374inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700375EncodingImpl<encoding::Buffer>::prependVarNumber(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800376{
377 if (varNumber < 253) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700378 prependByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800379 return 1;
380 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700381 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
382 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
383 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
384 prependByte(253);
Wentao Shang77949212014-02-01 23:42:24 -0800385 return 3;
386 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700387 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
388 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
389 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
390 prependByte(254);
Wentao Shang77949212014-02-01 23:42:24 -0800391 return 5;
392 }
393 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700394 uint64_t value = htobe64(varNumber);
395 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
396 prependByte(255);
Wentao Shang77949212014-02-01 23:42:24 -0800397 return 9;
398 }
399}
400
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800401inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700402EncodingImpl<encoding::Estimator>::prependVarNumber(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800403{
404 if (varNumber < 253) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800405 return 1;
406 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700407 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800408 return 3;
409 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700410 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800411 return 5;
412 }
413 else {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800414 return 9;
415 }
416}
417
Wentao Shang77949212014-02-01 23:42:24 -0800418/////////////////////////////////////////////////////////
419// Append to the back of the buffer. Resize if needed. //
420/////////////////////////////////////////////////////////
421
422inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700423EncodingImpl<encoding::Buffer>::appendByte(uint8_t value)
Wentao Shang77949212014-02-01 23:42:24 -0800424{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700425 if (m_end == m_buffer->end())
426 resize(m_buffer->size() * 2, false);
Wentao Shang77949212014-02-01 23:42:24 -0800427
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700428 *m_end = value;
Wentao Shang77949212014-02-01 23:42:24 -0800429 m_end++;
430 return 1;
431}
432
433inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700434EncodingImpl<encoding::Estimator>::appendByte(uint8_t value)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800435{
436 return 1;
437}
438
439inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700440EncodingImpl<encoding::Buffer>::appendByteArray(const uint8_t* array, size_t length)
Wentao Shang77949212014-02-01 23:42:24 -0800441{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700442 if ((m_end + length) > m_buffer->end())
443 resize(m_buffer->size() * 2 + length, false);
Wentao Shang77949212014-02-01 23:42:24 -0800444
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700445 std::copy(array, array + length, m_end);
446 m_end += length;
447 return length;
Wentao Shang77949212014-02-01 23:42:24 -0800448}
449
450inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700451EncodingImpl<encoding::Estimator>::appendByteArray(const uint8_t* array, size_t length)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800452{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700453 return prependByteArray(array, length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800454}
455
456inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700457EncodingImpl<encoding::Buffer>::appendNonNegativeInteger(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800458{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700459 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
460 return appendByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800461 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700462 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
463 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
464 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800465 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700466 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
467 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
468 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800469 }
470 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700471 uint64_t value = htobe64(varNumber);
472 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800473 }
474}
475
476inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700477EncodingImpl<encoding::Estimator>::appendNonNegativeInteger(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800478{
479 return prependNonNegativeInteger(varNumber);
480}
481
482inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700483EncodingImpl<encoding::Buffer>::appendVarNumber(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800484{
485 if (varNumber < 253) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700486 appendByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800487 return 1;
488 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700489 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
490 appendByte(253);
491 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
492 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800493 return 3;
494 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700495 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
496 appendByte(254);
497 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
498 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800499 return 5;
500 }
501 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700502 appendByte(255);
503 uint64_t value = htobe64(varNumber);
504 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800505 return 9;
506 }
507}
508
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800509inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700510EncodingImpl<encoding::Estimator>::appendVarNumber(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800511{
512 return prependVarNumber(varNumber);
513}
514
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800515/// helper methods
516
517template<bool P>
518inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700519prependNonNegativeIntegerBlock(EncodingImpl<P>& encoder, uint32_t type, uint64_t number)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800520{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700521 size_t valueLength = encoder.prependNonNegativeInteger(number);
522 size_t totalLength = valueLength;
523 totalLength += encoder.prependVarNumber(valueLength);
524 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800525
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700526 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800527}
528
529template<bool P>
530inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700531prependByteArrayBlock(EncodingImpl<P>& encoder, uint32_t type,
532 const uint8_t* array, size_t arraySize)
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800533{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700534 size_t valueLength = encoder.prependByteArray(array, arraySize);
535 size_t totalLength = valueLength;
536 totalLength += encoder.prependVarNumber(valueLength);
537 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800538
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700539 return totalLength;
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800540}
541
542template<bool P>
543inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700544prependBooleanBlock(EncodingImpl<P>& encoder, uint32_t type)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800545{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700546 size_t totalLength = encoder.prependVarNumber(0);
547 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800548
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700549 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800550}
551
552
553template<bool P, class U>
554inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700555prependNestedBlock(EncodingImpl<P>& encoder, uint32_t type, const U& nestedBlock)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800556{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700557 size_t valueLength = nestedBlock.wireEncode(encoder);
558 size_t totalLength = valueLength;
559 totalLength += encoder.prependVarNumber(valueLength);
560 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800561
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700562 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800563}
564
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800565template<bool P>
566inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700567prependBlock(EncodingImpl<P>& encoder, const Block& block)
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800568{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700569 return encoder.prependByteArray(block.wire(), block.size());
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800570}
571
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800572
Wentao Shang77949212014-02-01 23:42:24 -0800573} // ndn
574
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700575#endif // NDN_ENCODING_ENCODING_BUFFER_HPP