blob: d3fa3ac5d24b9b58e9f35ae5e16f2d259f0886dd [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 Afanasyeve881e932014-06-08 14:47:03 +0300134 prependBlock(const Block& block);
135
136 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700137 appendByte(uint8_t value);
Wentao Shang77949212014-02-01 23:42:24 -0800138
139 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700140 appendByteArray(const uint8_t* array, size_t length);
Wentao Shang77949212014-02-01 23:42:24 -0800141
142 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700143 appendNonNegativeInteger(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800144
145 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700146 appendVarNumber(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800147
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800148 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700149 // removeByteFromFront();
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800150
151 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700152 // removeByteFromEnd();
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800153
154 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700155 // removeVarNumberFromFront(uint64_t varNumber);
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800156
157 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700158 // removeVarNumberFromBack(uint64_t varNumber);
159
Wentao Shang77949212014-02-01 23:42:24 -0800160private:
161 BufferPtr m_buffer;
162
163 // invariant: m_begin always points to the position of last-written byte (if prepending data)
164 Buffer::iterator m_begin;
165 // invariant: m_end always points to the position of next unwritten byte (if appending data)
166 Buffer::iterator m_end;
Alexander Afanasyev15151312014-02-16 00:53:51 -0800167
168 friend class Block;
Wentao Shang77949212014-02-01 23:42:24 -0800169};
170
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800171
172/**
173 * @brief Class representing wire element of the NDN packet
174 */
175template<>
176class EncodingImpl<encoding::Estimator>
177{
178public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700179 EncodingImpl(size_t totalReserve = 8800,
180 size_t reserveFromBack = 400)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800181 {
182 }
183
184 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700185 prependByte(uint8_t value);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800186
187 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700188 prependByteArray(const uint8_t* array, size_t length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800189
190 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700191 prependNonNegativeInteger(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800192
193 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700194 prependVarNumber(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800195
196 inline size_t
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300197 prependBlock(const Block& block);
198
199 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700200 appendByte(uint8_t value);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800201
202 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700203 appendByteArray(const uint8_t* array, size_t length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800204
205 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700206 appendNonNegativeInteger(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800207
208 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700209 appendVarNumber(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800210};
211
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300212////////////////////////////////////////////////////////////////////////////////
213////////////////////////////////////////////////////////////////////////////////
214////////////////////////////////////////////////////////////////////////////////
215
216/// helper methods
217
218template<bool P>
219inline size_t
220prependNonNegativeIntegerBlock(EncodingImpl<P>& encoder, uint32_t type, uint64_t number)
221{
222 size_t valueLength = encoder.prependNonNegativeInteger(number);
223 size_t totalLength = valueLength;
224 totalLength += encoder.prependVarNumber(valueLength);
225 totalLength += encoder.prependVarNumber(type);
226
227 return totalLength;
228}
229
230template<bool P>
231inline size_t
232prependByteArrayBlock(EncodingImpl<P>& encoder, uint32_t type,
233 const uint8_t* array, size_t arraySize)
234{
235 size_t valueLength = encoder.prependByteArray(array, arraySize);
236 size_t totalLength = valueLength;
237 totalLength += encoder.prependVarNumber(valueLength);
238 totalLength += encoder.prependVarNumber(type);
239
240 return totalLength;
241}
242
243template<bool P>
244inline size_t
245prependBooleanBlock(EncodingImpl<P>& encoder, uint32_t type)
246{
247 size_t totalLength = encoder.prependVarNumber(0);
248 totalLength += encoder.prependVarNumber(type);
249
250 return totalLength;
251}
252
253
254template<bool P, class U>
255inline size_t
256prependNestedBlock(EncodingImpl<P>& encoder, uint32_t type, const U& nestedBlock)
257{
258 size_t valueLength = nestedBlock.wireEncode(encoder);
259 size_t totalLength = valueLength;
260 totalLength += encoder.prependVarNumber(valueLength);
261 totalLength += encoder.prependVarNumber(type);
262
263 return totalLength;
264}
265
266template<bool P>
267inline size_t
268prependBlock(EncodingImpl<P>& encoder, const Block& block)
269{
270 return encoder.prependByteArray(block.wire(), block.size());
271}
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800272
Wentao Shang77949212014-02-01 23:42:24 -0800273////////////////////////////////////////////////////////////////////////////////
274////////////////////////////////////////////////////////////////////////////////
275////////////////////////////////////////////////////////////////////////////////
276
277inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700278EncodingImpl<encoding::Buffer>::size() const
Wentao Shang77949212014-02-01 23:42:24 -0800279{
280 return m_end - m_begin;
281}
282
283inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700284EncodingImpl<encoding::Buffer>::capacity() const
Wentao Shang77949212014-02-01 23:42:24 -0800285{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700286 return m_buffer->size();
Wentao Shang77949212014-02-01 23:42:24 -0800287}
288
289inline uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700290EncodingImpl<encoding::Buffer>::buf()
Wentao Shang77949212014-02-01 23:42:24 -0800291{
292 return &(*m_begin);
293}
294
295inline const uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700296EncodingImpl<encoding::Buffer>::buf() const
Wentao Shang77949212014-02-01 23:42:24 -0800297{
298 return &(*m_begin);
299}
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800300
301inline Block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700302EncodingImpl<encoding::Buffer>::block(bool verifyLength/* = true*/) const
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800303{
304 return Block(m_buffer,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800305 m_begin, m_end,
306 verifyLength);
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800307}
308
Wentao Shang77949212014-02-01 23:42:24 -0800309inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700310EncodingImpl<encoding::Buffer>::resize(size_t size, bool addInFront)
Wentao Shang77949212014-02-01 23:42:24 -0800311{
312 if (addInFront)
313 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700314 size_t diff_end = m_buffer->end() - m_end;
315 size_t diff_begin = m_buffer->end() - m_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800316
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700317 Buffer* buf = new Buffer(size);
318 std::copy_backward(m_buffer->begin(), m_buffer->end(), buf->end());
Wentao Shang77949212014-02-01 23:42:24 -0800319
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700320 m_buffer.reset(buf);
Wentao Shang77949212014-02-01 23:42:24 -0800321
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700322 m_end = m_buffer->end() - diff_end;
323 m_begin = m_buffer->end() - diff_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800324 }
325 else
326 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700327 size_t diff_end = m_end - m_buffer->begin();
328 size_t diff_begin = m_begin - m_buffer->begin();
Wentao Shang77949212014-02-01 23:42:24 -0800329
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700330 Buffer* buf = new Buffer(size);
331 std::copy(m_buffer->begin(), m_buffer->end(), buf->begin());
Wentao Shang77949212014-02-01 23:42:24 -0800332
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700333 m_buffer.reset(buf);
Wentao Shang77949212014-02-01 23:42:24 -0800334
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700335 m_end = m_buffer->begin() + diff_end;
336 m_begin = m_buffer->begin() + diff_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800337 }
338}
339
340inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700341EncodingImpl<encoding::Buffer>::begin()
Wentao Shang77949212014-02-01 23:42:24 -0800342{
343 return m_begin;
344}
345
346inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700347EncodingImpl<encoding::Buffer>::end()
Wentao Shang77949212014-02-01 23:42:24 -0800348{
349 return m_end;
350}
351
352inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700353EncodingImpl<encoding::Buffer>::begin() const
Wentao Shang77949212014-02-01 23:42:24 -0800354{
355 return m_begin;
356}
357
358inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700359EncodingImpl<encoding::Buffer>::end() const
Wentao Shang77949212014-02-01 23:42:24 -0800360{
361 return m_end;
362}
363
364
365//////////////////////////////////////////////////////////
366// Prepend to the back of the buffer. Resize if needed. //
367//////////////////////////////////////////////////////////
368
369inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700370EncodingImpl<encoding::Buffer>::prependByte(uint8_t value)
Wentao Shang77949212014-02-01 23:42:24 -0800371{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700372 if (m_begin == m_buffer->begin())
373 resize(m_buffer->size() * 2, true);
Wentao Shang77949212014-02-01 23:42:24 -0800374
375 m_begin--;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700376 *m_begin = value;
Wentao Shang77949212014-02-01 23:42:24 -0800377 return 1;
378}
379
380inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700381EncodingImpl<encoding::Estimator>::prependByte(uint8_t value)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800382{
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800383 return 1;
384}
385
386inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700387EncodingImpl<encoding::Buffer>::prependByteArray(const uint8_t* array, size_t length)
Wentao Shang77949212014-02-01 23:42:24 -0800388{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700389 if ((m_buffer->begin() + length) > m_begin)
390 resize(m_buffer->size() * 2 + length, true);
Wentao Shang77949212014-02-01 23:42:24 -0800391
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700392 m_begin -= length;
393 std::copy(array, array + length, m_begin);
394 return length;
Wentao Shang77949212014-02-01 23:42:24 -0800395}
396
397inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700398EncodingImpl<encoding::Estimator>::prependByteArray(const uint8_t* array, size_t length)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800399{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700400 return length;
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800401}
402
403inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700404EncodingImpl<encoding::Buffer>::prependNonNegativeInteger(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800405{
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -0800406 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700407 return prependByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800408 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700409 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
410 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
411 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800412 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700413 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
414 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
415 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800416 }
417 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700418 uint64_t value = htobe64(varNumber);
419 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800420 }
421}
422
423inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700424EncodingImpl<encoding::Estimator>::prependNonNegativeInteger(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800425{
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -0800426 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800427 return 1;
428 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700429 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800430 return 2;
431 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700432 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800433 return 4;
434 }
435 else {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800436 return 8;
437 }
438}
439
440inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700441EncodingImpl<encoding::Buffer>::prependVarNumber(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800442{
443 if (varNumber < 253) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700444 prependByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800445 return 1;
446 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700447 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
448 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
449 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
450 prependByte(253);
Wentao Shang77949212014-02-01 23:42:24 -0800451 return 3;
452 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700453 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
454 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
455 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
456 prependByte(254);
Wentao Shang77949212014-02-01 23:42:24 -0800457 return 5;
458 }
459 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700460 uint64_t value = htobe64(varNumber);
461 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
462 prependByte(255);
Wentao Shang77949212014-02-01 23:42:24 -0800463 return 9;
464 }
465}
466
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800467inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700468EncodingImpl<encoding::Estimator>::prependVarNumber(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800469{
470 if (varNumber < 253) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800471 return 1;
472 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700473 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800474 return 3;
475 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700476 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800477 return 5;
478 }
479 else {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800480 return 9;
481 }
482}
483
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300484inline size_t
485EncodingImpl<encoding::Buffer>::prependBlock(const Block& block)
486{
487 if (block.hasWire()) {
488 return prependByteArray(block.wire(), block.size());
489 }
490 else {
491 return prependByteArrayBlock(*this, block.type(), block.value(), block.value_size());
492 }
493}
494
495inline size_t
496EncodingImpl<encoding::Estimator>::prependBlock(const Block& block)
497{
498 if (block.hasWire()) {
499 return block.size();
500 }
501 else {
502 return prependByteArrayBlock(*this, block.type(), block.value(), block.value_size());
503 }
504}
505
Wentao Shang77949212014-02-01 23:42:24 -0800506/////////////////////////////////////////////////////////
507// Append to the back of the buffer. Resize if needed. //
508/////////////////////////////////////////////////////////
509
510inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700511EncodingImpl<encoding::Buffer>::appendByte(uint8_t value)
Wentao Shang77949212014-02-01 23:42:24 -0800512{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700513 if (m_end == m_buffer->end())
514 resize(m_buffer->size() * 2, false);
Wentao Shang77949212014-02-01 23:42:24 -0800515
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700516 *m_end = value;
Wentao Shang77949212014-02-01 23:42:24 -0800517 m_end++;
518 return 1;
519}
520
521inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700522EncodingImpl<encoding::Estimator>::appendByte(uint8_t value)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800523{
524 return 1;
525}
526
527inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700528EncodingImpl<encoding::Buffer>::appendByteArray(const uint8_t* array, size_t length)
Wentao Shang77949212014-02-01 23:42:24 -0800529{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700530 if ((m_end + length) > m_buffer->end())
531 resize(m_buffer->size() * 2 + length, false);
Wentao Shang77949212014-02-01 23:42:24 -0800532
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700533 std::copy(array, array + length, m_end);
534 m_end += length;
535 return length;
Wentao Shang77949212014-02-01 23:42:24 -0800536}
537
538inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700539EncodingImpl<encoding::Estimator>::appendByteArray(const uint8_t* array, size_t length)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800540{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700541 return prependByteArray(array, length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800542}
543
544inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700545EncodingImpl<encoding::Buffer>::appendNonNegativeInteger(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800546{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700547 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
548 return appendByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800549 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700550 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
551 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
552 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800553 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700554 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
555 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
556 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800557 }
558 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700559 uint64_t value = htobe64(varNumber);
560 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800561 }
562}
563
564inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700565EncodingImpl<encoding::Estimator>::appendNonNegativeInteger(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800566{
567 return prependNonNegativeInteger(varNumber);
568}
569
570inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700571EncodingImpl<encoding::Buffer>::appendVarNumber(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800572{
573 if (varNumber < 253) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700574 appendByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800575 return 1;
576 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700577 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
578 appendByte(253);
579 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
580 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800581 return 3;
582 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700583 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
584 appendByte(254);
585 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
586 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800587 return 5;
588 }
589 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700590 appendByte(255);
591 uint64_t value = htobe64(varNumber);
592 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800593 return 9;
594 }
595}
596
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800597inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700598EncodingImpl<encoding::Estimator>::appendVarNumber(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800599{
600 return prependVarNumber(varNumber);
601}
602
Wentao Shang77949212014-02-01 23:42:24 -0800603} // ndn
604
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700605#endif // NDN_ENCODING_ENCODING_BUFFER_HPP