blob: 4c5185e39c51fe863dad0f54350583e0164daa65 [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 Afanasyev197e5652014-06-13 16:56:31 -0700148 inline size_t
149 appendBlock(const Block& block);
150
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800151 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700152 // removeByteFromFront();
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800153
154 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700155 // removeByteFromEnd();
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800156
157 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700158 // removeVarNumberFromFront(uint64_t varNumber);
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800159
160 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700161 // removeVarNumberFromBack(uint64_t varNumber);
162
Wentao Shang77949212014-02-01 23:42:24 -0800163private:
164 BufferPtr m_buffer;
165
166 // invariant: m_begin always points to the position of last-written byte (if prepending data)
167 Buffer::iterator m_begin;
168 // invariant: m_end always points to the position of next unwritten byte (if appending data)
169 Buffer::iterator m_end;
Alexander Afanasyev15151312014-02-16 00:53:51 -0800170
171 friend class Block;
Wentao Shang77949212014-02-01 23:42:24 -0800172};
173
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800174
175/**
176 * @brief Class representing wire element of the NDN packet
177 */
178template<>
179class EncodingImpl<encoding::Estimator>
180{
181public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700182 EncodingImpl(size_t totalReserve = 8800,
183 size_t reserveFromBack = 400)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800184 {
185 }
186
187 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700188 prependByte(uint8_t value);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800189
190 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700191 prependByteArray(const uint8_t* array, size_t length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800192
193 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700194 prependNonNegativeInteger(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800195
196 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700197 prependVarNumber(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800198
199 inline size_t
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300200 prependBlock(const Block& block);
201
202 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700203 appendByte(uint8_t value);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800204
205 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700206 appendByteArray(const uint8_t* array, size_t length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800207
208 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700209 appendNonNegativeInteger(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800210
211 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700212 appendVarNumber(uint64_t varNumber);
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700213
214 inline size_t
215 appendBlock(const Block& block);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800216};
217
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300218////////////////////////////////////////////////////////////////////////////////
219////////////////////////////////////////////////////////////////////////////////
220////////////////////////////////////////////////////////////////////////////////
221
222/// helper methods
223
224template<bool P>
225inline size_t
226prependNonNegativeIntegerBlock(EncodingImpl<P>& encoder, uint32_t type, uint64_t number)
227{
228 size_t valueLength = encoder.prependNonNegativeInteger(number);
229 size_t totalLength = valueLength;
230 totalLength += encoder.prependVarNumber(valueLength);
231 totalLength += encoder.prependVarNumber(type);
232
233 return totalLength;
234}
235
236template<bool P>
237inline size_t
238prependByteArrayBlock(EncodingImpl<P>& encoder, uint32_t type,
239 const uint8_t* array, size_t arraySize)
240{
241 size_t valueLength = encoder.prependByteArray(array, arraySize);
242 size_t totalLength = valueLength;
243 totalLength += encoder.prependVarNumber(valueLength);
244 totalLength += encoder.prependVarNumber(type);
245
246 return totalLength;
247}
248
249template<bool P>
250inline size_t
251prependBooleanBlock(EncodingImpl<P>& encoder, uint32_t type)
252{
253 size_t totalLength = encoder.prependVarNumber(0);
254 totalLength += encoder.prependVarNumber(type);
255
256 return totalLength;
257}
258
259
260template<bool P, class U>
261inline size_t
262prependNestedBlock(EncodingImpl<P>& encoder, uint32_t type, const U& nestedBlock)
263{
264 size_t valueLength = nestedBlock.wireEncode(encoder);
265 size_t totalLength = valueLength;
266 totalLength += encoder.prependVarNumber(valueLength);
267 totalLength += encoder.prependVarNumber(type);
268
269 return totalLength;
270}
271
272template<bool P>
273inline size_t
274prependBlock(EncodingImpl<P>& encoder, const Block& block)
275{
276 return encoder.prependByteArray(block.wire(), block.size());
277}
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800278
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700279template<bool P>
280inline size_t
281appendByteArrayBlock(EncodingImpl<P>& encoder, uint32_t type,
282 const uint8_t* array, size_t arraySize)
283{
284 size_t totalLength = encoder.appendVarNumber(type);
285 totalLength += encoder.appendVarNumber(arraySize);
286 totalLength += encoder.appendByteArray(array, arraySize);
287
288 return totalLength;
289}
290
291template<bool P>
292inline size_t
293appendBlock(EncodingImpl<P>& encoder, const Block& block)
294{
295 return encoder.appendByteArray(block.wire(), block.size());
296}
297
Wentao Shang77949212014-02-01 23:42:24 -0800298////////////////////////////////////////////////////////////////////////////////
299////////////////////////////////////////////////////////////////////////////////
300////////////////////////////////////////////////////////////////////////////////
301
302inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700303EncodingImpl<encoding::Buffer>::size() const
Wentao Shang77949212014-02-01 23:42:24 -0800304{
305 return m_end - m_begin;
306}
307
308inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700309EncodingImpl<encoding::Buffer>::capacity() const
Wentao Shang77949212014-02-01 23:42:24 -0800310{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700311 return m_buffer->size();
Wentao Shang77949212014-02-01 23:42:24 -0800312}
313
314inline uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700315EncodingImpl<encoding::Buffer>::buf()
Wentao Shang77949212014-02-01 23:42:24 -0800316{
317 return &(*m_begin);
318}
319
320inline const uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700321EncodingImpl<encoding::Buffer>::buf() const
Wentao Shang77949212014-02-01 23:42:24 -0800322{
323 return &(*m_begin);
324}
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800325
326inline Block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700327EncodingImpl<encoding::Buffer>::block(bool verifyLength/* = true*/) const
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800328{
329 return Block(m_buffer,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800330 m_begin, m_end,
331 verifyLength);
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800332}
333
Wentao Shang77949212014-02-01 23:42:24 -0800334inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700335EncodingImpl<encoding::Buffer>::resize(size_t size, bool addInFront)
Wentao Shang77949212014-02-01 23:42:24 -0800336{
337 if (addInFront)
338 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700339 size_t diff_end = m_buffer->end() - m_end;
340 size_t diff_begin = m_buffer->end() - m_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800341
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700342 Buffer* buf = new Buffer(size);
343 std::copy_backward(m_buffer->begin(), m_buffer->end(), buf->end());
Wentao Shang77949212014-02-01 23:42:24 -0800344
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700345 m_buffer.reset(buf);
Wentao Shang77949212014-02-01 23:42:24 -0800346
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700347 m_end = m_buffer->end() - diff_end;
348 m_begin = m_buffer->end() - diff_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800349 }
350 else
351 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700352 size_t diff_end = m_end - m_buffer->begin();
353 size_t diff_begin = m_begin - m_buffer->begin();
Wentao Shang77949212014-02-01 23:42:24 -0800354
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700355 Buffer* buf = new Buffer(size);
356 std::copy(m_buffer->begin(), m_buffer->end(), buf->begin());
Wentao Shang77949212014-02-01 23:42:24 -0800357
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700358 m_buffer.reset(buf);
Wentao Shang77949212014-02-01 23:42:24 -0800359
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700360 m_end = m_buffer->begin() + diff_end;
361 m_begin = m_buffer->begin() + diff_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800362 }
363}
364
365inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700366EncodingImpl<encoding::Buffer>::begin()
Wentao Shang77949212014-02-01 23:42:24 -0800367{
368 return m_begin;
369}
370
371inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700372EncodingImpl<encoding::Buffer>::end()
Wentao Shang77949212014-02-01 23:42:24 -0800373{
374 return m_end;
375}
376
377inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700378EncodingImpl<encoding::Buffer>::begin() const
Wentao Shang77949212014-02-01 23:42:24 -0800379{
380 return m_begin;
381}
382
383inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700384EncodingImpl<encoding::Buffer>::end() const
Wentao Shang77949212014-02-01 23:42:24 -0800385{
386 return m_end;
387}
388
389
390//////////////////////////////////////////////////////////
391// Prepend to the back of the buffer. Resize if needed. //
392//////////////////////////////////////////////////////////
393
394inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700395EncodingImpl<encoding::Buffer>::prependByte(uint8_t value)
Wentao Shang77949212014-02-01 23:42:24 -0800396{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700397 if (m_begin == m_buffer->begin())
398 resize(m_buffer->size() * 2, true);
Wentao Shang77949212014-02-01 23:42:24 -0800399
400 m_begin--;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700401 *m_begin = value;
Wentao Shang77949212014-02-01 23:42:24 -0800402 return 1;
403}
404
405inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700406EncodingImpl<encoding::Estimator>::prependByte(uint8_t value)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800407{
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800408 return 1;
409}
410
411inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700412EncodingImpl<encoding::Buffer>::prependByteArray(const uint8_t* array, size_t length)
Wentao Shang77949212014-02-01 23:42:24 -0800413{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700414 if ((m_buffer->begin() + length) > m_begin)
415 resize(m_buffer->size() * 2 + length, true);
Wentao Shang77949212014-02-01 23:42:24 -0800416
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700417 m_begin -= length;
418 std::copy(array, array + length, m_begin);
419 return length;
Wentao Shang77949212014-02-01 23:42:24 -0800420}
421
422inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700423EncodingImpl<encoding::Estimator>::prependByteArray(const uint8_t* array, size_t length)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800424{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700425 return length;
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800426}
427
428inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700429EncodingImpl<encoding::Buffer>::prependNonNegativeInteger(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800430{
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -0800431 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700432 return prependByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800433 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700434 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
435 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
436 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800437 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700438 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
439 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
440 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800441 }
442 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700443 uint64_t value = htobe64(varNumber);
444 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800445 }
446}
447
448inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700449EncodingImpl<encoding::Estimator>::prependNonNegativeInteger(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800450{
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -0800451 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800452 return 1;
453 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700454 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800455 return 2;
456 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700457 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800458 return 4;
459 }
460 else {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800461 return 8;
462 }
463}
464
465inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700466EncodingImpl<encoding::Buffer>::prependVarNumber(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800467{
468 if (varNumber < 253) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700469 prependByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800470 return 1;
471 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700472 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
473 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
474 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
475 prependByte(253);
Wentao Shang77949212014-02-01 23:42:24 -0800476 return 3;
477 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700478 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
479 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
480 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
481 prependByte(254);
Wentao Shang77949212014-02-01 23:42:24 -0800482 return 5;
483 }
484 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700485 uint64_t value = htobe64(varNumber);
486 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
487 prependByte(255);
Wentao Shang77949212014-02-01 23:42:24 -0800488 return 9;
489 }
490}
491
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800492inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700493EncodingImpl<encoding::Estimator>::prependVarNumber(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800494{
495 if (varNumber < 253) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800496 return 1;
497 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700498 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800499 return 3;
500 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700501 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800502 return 5;
503 }
504 else {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800505 return 9;
506 }
507}
508
Alexander Afanasyeve881e932014-06-08 14:47:03 +0300509inline size_t
510EncodingImpl<encoding::Buffer>::prependBlock(const Block& block)
511{
512 if (block.hasWire()) {
513 return prependByteArray(block.wire(), block.size());
514 }
515 else {
516 return prependByteArrayBlock(*this, block.type(), block.value(), block.value_size());
517 }
518}
519
520inline size_t
521EncodingImpl<encoding::Estimator>::prependBlock(const Block& block)
522{
523 if (block.hasWire()) {
524 return block.size();
525 }
526 else {
527 return prependByteArrayBlock(*this, block.type(), block.value(), block.value_size());
528 }
529}
530
Wentao Shang77949212014-02-01 23:42:24 -0800531/////////////////////////////////////////////////////////
532// Append to the back of the buffer. Resize if needed. //
533/////////////////////////////////////////////////////////
534
535inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700536EncodingImpl<encoding::Buffer>::appendByte(uint8_t value)
Wentao Shang77949212014-02-01 23:42:24 -0800537{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700538 if (m_end == m_buffer->end())
539 resize(m_buffer->size() * 2, false);
Wentao Shang77949212014-02-01 23:42:24 -0800540
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700541 *m_end = value;
Wentao Shang77949212014-02-01 23:42:24 -0800542 m_end++;
543 return 1;
544}
545
546inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700547EncodingImpl<encoding::Estimator>::appendByte(uint8_t value)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800548{
549 return 1;
550}
551
552inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700553EncodingImpl<encoding::Buffer>::appendByteArray(const uint8_t* array, size_t length)
Wentao Shang77949212014-02-01 23:42:24 -0800554{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700555 if ((m_end + length) > m_buffer->end())
556 resize(m_buffer->size() * 2 + length, false);
Wentao Shang77949212014-02-01 23:42:24 -0800557
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700558 std::copy(array, array + length, m_end);
559 m_end += length;
560 return length;
Wentao Shang77949212014-02-01 23:42:24 -0800561}
562
563inline size_t
Alexander Afanasyev197e5652014-06-13 16:56:31 -0700564EncodingImpl<encoding::Buffer>::appendBlock(const Block& block)
565{
566 if (block.hasWire()) {
567 return appendByteArray(block.wire(), block.size());
568 }
569 else {
570 return appendByteArrayBlock(*this, block.type(), block.value(), block.value_size());
571 }
572}
573
574inline size_t
575EncodingImpl<encoding::Estimator>::appendBlock(const Block& block)
576{
577 if (block.hasWire()) {
578 return block.size();
579 }
580 else {
581 return appendByteArrayBlock(*this, block.type(), block.value(), block.value_size());
582 }
583}
584
585inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700586EncodingImpl<encoding::Estimator>::appendByteArray(const uint8_t* array, size_t length)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800587{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700588 return prependByteArray(array, length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800589}
590
591inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700592EncodingImpl<encoding::Buffer>::appendNonNegativeInteger(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800593{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700594 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
595 return appendByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800596 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700597 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
598 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
599 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800600 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700601 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
602 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
603 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800604 }
605 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700606 uint64_t value = htobe64(varNumber);
607 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800608 }
609}
610
611inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700612EncodingImpl<encoding::Estimator>::appendNonNegativeInteger(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800613{
614 return prependNonNegativeInteger(varNumber);
615}
616
617inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700618EncodingImpl<encoding::Buffer>::appendVarNumber(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800619{
620 if (varNumber < 253) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700621 appendByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800622 return 1;
623 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700624 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
625 appendByte(253);
626 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
627 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800628 return 3;
629 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700630 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
631 appendByte(254);
632 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
633 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800634 return 5;
635 }
636 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700637 appendByte(255);
638 uint64_t value = htobe64(varNumber);
639 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800640 return 9;
641 }
642}
643
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800644inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700645EncodingImpl<encoding::Estimator>::appendVarNumber(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800646{
647 return prependVarNumber(varNumber);
648}
649
Wentao Shang77949212014-02-01 23:42:24 -0800650} // ndn
651
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700652#endif // NDN_ENCODING_ENCODING_BUFFER_HPP