blob: 04642879417a8752e887dad7012b99e66de13117 [file] [log] [blame]
Wentao Shang77949212014-02-01 23:42:24 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07002/**
3 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
Wentao Shang77949212014-02-01 23:42:24 -08005 *
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Wentao Shang77949212014-02-01 23:42:24 -08008 *
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07009 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Wentao Shang <http://irl.cs.ucla.edu/~wentao/>
13 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
Wentao Shang77949212014-02-01 23:42:24 -080014 */
15
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070016#ifndef NDN_ENCODING_ENCODING_BUFFER_HPP
17#define NDN_ENCODING_ENCODING_BUFFER_HPP
Wentao Shang77949212014-02-01 23:42:24 -080018
19#include "../common.hpp"
20
Wentao Shang77949212014-02-01 23:42:24 -080021#include "buffer.hpp"
Alexander Afanasyev233750e2014-02-16 00:50:07 -080022#include "block.hpp"
Wentao Shang77949212014-02-01 23:42:24 -080023
Wentao Shang77949212014-02-01 23:42:24 -080024namespace ndn {
25
Alexander Afanasyev217325b2014-02-06 15:03:28 -080026namespace encoding {
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080027static const bool Buffer = true;
28static const bool Estimator = false;
Alexander Afanasyev217325b2014-02-06 15:03:28 -080029} // encoding
30
31template<bool isRealEncoderNotEstimator>
32class EncodingImpl;
33
34typedef EncodingImpl<encoding::Buffer> EncodingBuffer;
35typedef EncodingImpl<encoding::Estimator> EncodingEstimator;
36
Wentao Shang77949212014-02-01 23:42:24 -080037/**
38 * @brief Class representing wire element of the NDN packet
39 */
Alexander Afanasyev217325b2014-02-06 15:03:28 -080040template<>
41class EncodingImpl<encoding::Buffer>
Wentao Shang77949212014-02-01 23:42:24 -080042{
43public:
Wentao Shang77949212014-02-01 23:42:24 -080044 /**
Alexander Afanasyev217325b2014-02-06 15:03:28 -080045 * @brief Constructor to create a EncodingImpl with specified reserved sizes
46 *
47 * The caller should make sure that that reserveFromBack does not exceed totalReserve,
48 * otherwise behavior is undefined.
Wentao Shang77949212014-02-01 23:42:24 -080049 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070050 EncodingImpl(size_t totalReserve = 8800,
51 size_t reserveFromBack = 400)
52 : m_buffer(new Buffer(totalReserve))
Wentao Shang77949212014-02-01 23:42:24 -080053 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070054 m_begin = m_end = m_buffer->end() - (reserveFromBack < totalReserve ? reserveFromBack : 0);
Wentao Shang77949212014-02-01 23:42:24 -080055 }
56
Alexander Afanasyev15151312014-02-16 00:53:51 -080057 /**
58 * @brief Create EncodingBlock from existing block
59 *
60 * This is a dangerous constructor and should be used with caution.
61 * It will modify contents of the buffer that is used by block and may
62 * impact data in other blocks.
63 *
64 * The primary purpose for this method is to be used to extend Block
65 * after sign operation.
66 */
67 explicit
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070068 EncodingImpl(const Block& block)
Alexander Afanasyev15151312014-02-16 00:53:51 -080069 : m_buffer(const_pointer_cast<Buffer>(block.m_buffer))
70 , m_begin(m_buffer->begin() + (block.begin() - m_buffer->begin()))
71 , m_end(m_buffer->begin() + (block.end() - m_buffer->begin()))
72 {
73 }
Wentao Shang77949212014-02-01 23:42:24 -080074
75 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070076 size() const;
77
78 inline size_t
79 capacity() const;
Wentao Shang77949212014-02-01 23:42:24 -080080
81 inline uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070082 buf();
Wentao Shang77949212014-02-01 23:42:24 -080083
84 inline const uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070085 buf() const;
Wentao Shang77949212014-02-01 23:42:24 -080086
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080087 /**
88 * @brief Create Block from the underlying EncodingBuffer
89 *
90 * @param verifyLength If this parameter set to true, Block's constructor
91 * will be requested to verify consistency of the encoded
92 * length in the Block, otherwise ignored
93 */
Alexander Afanasyev187bc482014-02-06 15:04:04 -080094 inline Block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070095 block(bool verifyLength = true) const;
Alexander Afanasyev187bc482014-02-06 15:04:04 -080096
Wentao Shang77949212014-02-01 23:42:24 -080097 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070098 resize(size_t size, bool addInFront);
Wentao Shang77949212014-02-01 23:42:24 -080099
100 inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700101 begin();
Wentao Shang77949212014-02-01 23:42:24 -0800102
103 inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700104 end();
Wentao Shang77949212014-02-01 23:42:24 -0800105
106 inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700107 begin() const;
Wentao Shang77949212014-02-01 23:42:24 -0800108
109 inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700110 end() const;
Wentao Shang77949212014-02-01 23:42:24 -0800111
112 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700113 prependByte(uint8_t value);
Wentao Shang77949212014-02-01 23:42:24 -0800114
115 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700116 prependByteArray(const uint8_t* array, size_t length);
Wentao Shang77949212014-02-01 23:42:24 -0800117
118 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700119 prependNonNegativeInteger(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800120
121 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700122 prependVarNumber(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800123
124 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700125 appendByte(uint8_t value);
Wentao Shang77949212014-02-01 23:42:24 -0800126
127 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700128 appendByteArray(const uint8_t* array, size_t length);
Wentao Shang77949212014-02-01 23:42:24 -0800129
130 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700131 appendNonNegativeInteger(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800132
133 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700134 appendVarNumber(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800135
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800136 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700137 // removeByteFromFront();
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800138
139 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700140 // removeByteFromEnd();
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800141
142 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700143 // removeVarNumberFromFront(uint64_t varNumber);
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800144
145 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700146 // removeVarNumberFromBack(uint64_t varNumber);
147
Wentao Shang77949212014-02-01 23:42:24 -0800148private:
149 BufferPtr m_buffer;
150
151 // invariant: m_begin always points to the position of last-written byte (if prepending data)
152 Buffer::iterator m_begin;
153 // invariant: m_end always points to the position of next unwritten byte (if appending data)
154 Buffer::iterator m_end;
Alexander Afanasyev15151312014-02-16 00:53:51 -0800155
156 friend class Block;
Wentao Shang77949212014-02-01 23:42:24 -0800157};
158
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800159
160/**
161 * @brief Class representing wire element of the NDN packet
162 */
163template<>
164class EncodingImpl<encoding::Estimator>
165{
166public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700167 EncodingImpl(size_t totalReserve = 8800,
168 size_t reserveFromBack = 400)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800169 {
170 }
171
172 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700173 prependByte(uint8_t value);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800174
175 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700176 prependByteArray(const uint8_t* array, size_t length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800177
178 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700179 prependNonNegativeInteger(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800180
181 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700182 prependVarNumber(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800183
184 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700185 appendByte(uint8_t value);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800186
187 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700188 appendByteArray(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 appendNonNegativeInteger(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800192
193 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700194 appendVarNumber(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800195};
196
197
Wentao Shang77949212014-02-01 23:42:24 -0800198////////////////////////////////////////////////////////////////////////////////
199////////////////////////////////////////////////////////////////////////////////
200////////////////////////////////////////////////////////////////////////////////
201
202inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700203EncodingImpl<encoding::Buffer>::size() const
Wentao Shang77949212014-02-01 23:42:24 -0800204{
205 return m_end - m_begin;
206}
207
208inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700209EncodingImpl<encoding::Buffer>::capacity() const
Wentao Shang77949212014-02-01 23:42:24 -0800210{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700211 return m_buffer->size();
Wentao Shang77949212014-02-01 23:42:24 -0800212}
213
214inline uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700215EncodingImpl<encoding::Buffer>::buf()
Wentao Shang77949212014-02-01 23:42:24 -0800216{
217 return &(*m_begin);
218}
219
220inline const uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700221EncodingImpl<encoding::Buffer>::buf() const
Wentao Shang77949212014-02-01 23:42:24 -0800222{
223 return &(*m_begin);
224}
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800225
226inline Block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700227EncodingImpl<encoding::Buffer>::block(bool verifyLength/* = true*/) const
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800228{
229 return Block(m_buffer,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800230 m_begin, m_end,
231 verifyLength);
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800232}
233
Wentao Shang77949212014-02-01 23:42:24 -0800234inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700235EncodingImpl<encoding::Buffer>::resize(size_t size, bool addInFront)
Wentao Shang77949212014-02-01 23:42:24 -0800236{
237 if (addInFront)
238 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700239 size_t diff_end = m_buffer->end() - m_end;
240 size_t diff_begin = m_buffer->end() - m_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800241
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700242 Buffer* buf = new Buffer(size);
243 std::copy_backward(m_buffer->begin(), m_buffer->end(), buf->end());
Wentao Shang77949212014-02-01 23:42:24 -0800244
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700245 m_buffer.reset(buf);
Wentao Shang77949212014-02-01 23:42:24 -0800246
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700247 m_end = m_buffer->end() - diff_end;
248 m_begin = m_buffer->end() - diff_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800249 }
250 else
251 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700252 size_t diff_end = m_end - m_buffer->begin();
253 size_t diff_begin = m_begin - m_buffer->begin();
Wentao Shang77949212014-02-01 23:42:24 -0800254
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700255 Buffer* buf = new Buffer(size);
256 std::copy(m_buffer->begin(), m_buffer->end(), buf->begin());
Wentao Shang77949212014-02-01 23:42:24 -0800257
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700258 m_buffer.reset(buf);
Wentao Shang77949212014-02-01 23:42:24 -0800259
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700260 m_end = m_buffer->begin() + diff_end;
261 m_begin = m_buffer->begin() + diff_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800262 }
263}
264
265inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700266EncodingImpl<encoding::Buffer>::begin()
Wentao Shang77949212014-02-01 23:42:24 -0800267{
268 return m_begin;
269}
270
271inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700272EncodingImpl<encoding::Buffer>::end()
Wentao Shang77949212014-02-01 23:42:24 -0800273{
274 return m_end;
275}
276
277inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700278EncodingImpl<encoding::Buffer>::begin() const
Wentao Shang77949212014-02-01 23:42:24 -0800279{
280 return m_begin;
281}
282
283inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700284EncodingImpl<encoding::Buffer>::end() const
Wentao Shang77949212014-02-01 23:42:24 -0800285{
286 return m_end;
287}
288
289
290//////////////////////////////////////////////////////////
291// Prepend to the back of the buffer. Resize if needed. //
292//////////////////////////////////////////////////////////
293
294inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700295EncodingImpl<encoding::Buffer>::prependByte(uint8_t value)
Wentao Shang77949212014-02-01 23:42:24 -0800296{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700297 if (m_begin == m_buffer->begin())
298 resize(m_buffer->size() * 2, true);
Wentao Shang77949212014-02-01 23:42:24 -0800299
300 m_begin--;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700301 *m_begin = value;
Wentao Shang77949212014-02-01 23:42:24 -0800302 return 1;
303}
304
305inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700306EncodingImpl<encoding::Estimator>::prependByte(uint8_t value)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800307{
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800308 return 1;
309}
310
311inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700312EncodingImpl<encoding::Buffer>::prependByteArray(const uint8_t* array, size_t length)
Wentao Shang77949212014-02-01 23:42:24 -0800313{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700314 if ((m_buffer->begin() + length) > m_begin)
315 resize(m_buffer->size() * 2 + length, true);
Wentao Shang77949212014-02-01 23:42:24 -0800316
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700317 m_begin -= length;
318 std::copy(array, array + length, m_begin);
319 return length;
Wentao Shang77949212014-02-01 23:42:24 -0800320}
321
322inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700323EncodingImpl<encoding::Estimator>::prependByteArray(const uint8_t* array, size_t length)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800324{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700325 return length;
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800326}
327
328inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700329EncodingImpl<encoding::Buffer>::prependNonNegativeInteger(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800330{
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -0800331 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700332 return prependByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800333 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700334 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
335 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
336 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800337 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700338 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
339 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
340 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800341 }
342 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700343 uint64_t value = htobe64(varNumber);
344 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800345 }
346}
347
348inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700349EncodingImpl<encoding::Estimator>::prependNonNegativeInteger(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800350{
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -0800351 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800352 return 1;
353 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700354 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800355 return 2;
356 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700357 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800358 return 4;
359 }
360 else {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800361 return 8;
362 }
363}
364
365inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700366EncodingImpl<encoding::Buffer>::prependVarNumber(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800367{
368 if (varNumber < 253) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700369 prependByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800370 return 1;
371 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700372 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
373 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
374 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
375 prependByte(253);
Wentao Shang77949212014-02-01 23:42:24 -0800376 return 3;
377 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700378 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
379 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
380 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
381 prependByte(254);
Wentao Shang77949212014-02-01 23:42:24 -0800382 return 5;
383 }
384 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700385 uint64_t value = htobe64(varNumber);
386 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
387 prependByte(255);
Wentao Shang77949212014-02-01 23:42:24 -0800388 return 9;
389 }
390}
391
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800392inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700393EncodingImpl<encoding::Estimator>::prependVarNumber(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800394{
395 if (varNumber < 253) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800396 return 1;
397 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700398 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800399 return 3;
400 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700401 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800402 return 5;
403 }
404 else {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800405 return 9;
406 }
407}
408
Wentao Shang77949212014-02-01 23:42:24 -0800409/////////////////////////////////////////////////////////
410// Append to the back of the buffer. Resize if needed. //
411/////////////////////////////////////////////////////////
412
413inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700414EncodingImpl<encoding::Buffer>::appendByte(uint8_t value)
Wentao Shang77949212014-02-01 23:42:24 -0800415{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700416 if (m_end == m_buffer->end())
417 resize(m_buffer->size() * 2, false);
Wentao Shang77949212014-02-01 23:42:24 -0800418
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700419 *m_end = value;
Wentao Shang77949212014-02-01 23:42:24 -0800420 m_end++;
421 return 1;
422}
423
424inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700425EncodingImpl<encoding::Estimator>::appendByte(uint8_t value)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800426{
427 return 1;
428}
429
430inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700431EncodingImpl<encoding::Buffer>::appendByteArray(const uint8_t* array, size_t length)
Wentao Shang77949212014-02-01 23:42:24 -0800432{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700433 if ((m_end + length) > m_buffer->end())
434 resize(m_buffer->size() * 2 + length, false);
Wentao Shang77949212014-02-01 23:42:24 -0800435
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700436 std::copy(array, array + length, m_end);
437 m_end += length;
438 return length;
Wentao Shang77949212014-02-01 23:42:24 -0800439}
440
441inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700442EncodingImpl<encoding::Estimator>::appendByteArray(const uint8_t* array, size_t length)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800443{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700444 return prependByteArray(array, length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800445}
446
447inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700448EncodingImpl<encoding::Buffer>::appendNonNegativeInteger(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800449{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700450 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
451 return appendByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800452 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700453 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
454 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
455 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800456 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700457 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
458 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
459 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800460 }
461 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700462 uint64_t value = htobe64(varNumber);
463 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800464 }
465}
466
467inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700468EncodingImpl<encoding::Estimator>::appendNonNegativeInteger(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800469{
470 return prependNonNegativeInteger(varNumber);
471}
472
473inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700474EncodingImpl<encoding::Buffer>::appendVarNumber(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800475{
476 if (varNumber < 253) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700477 appendByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800478 return 1;
479 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700480 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
481 appendByte(253);
482 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
483 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800484 return 3;
485 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700486 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
487 appendByte(254);
488 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
489 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800490 return 5;
491 }
492 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700493 appendByte(255);
494 uint64_t value = htobe64(varNumber);
495 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800496 return 9;
497 }
498}
499
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800500inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700501EncodingImpl<encoding::Estimator>::appendVarNumber(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800502{
503 return prependVarNumber(varNumber);
504}
505
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800506/// helper methods
507
508template<bool P>
509inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700510prependNonNegativeIntegerBlock(EncodingImpl<P>& encoder, uint32_t type, uint64_t number)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800511{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700512 size_t valueLength = encoder.prependNonNegativeInteger(number);
513 size_t totalLength = valueLength;
514 totalLength += encoder.prependVarNumber(valueLength);
515 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800516
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700517 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800518}
519
520template<bool P>
521inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700522prependByteArrayBlock(EncodingImpl<P>& encoder, uint32_t type,
523 const uint8_t* array, size_t arraySize)
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800524{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700525 size_t valueLength = encoder.prependByteArray(array, arraySize);
526 size_t totalLength = valueLength;
527 totalLength += encoder.prependVarNumber(valueLength);
528 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800529
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700530 return totalLength;
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800531}
532
533template<bool P>
534inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700535prependBooleanBlock(EncodingImpl<P>& encoder, uint32_t type)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800536{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700537 size_t totalLength = encoder.prependVarNumber(0);
538 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800539
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700540 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800541}
542
543
544template<bool P, class U>
545inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700546prependNestedBlock(EncodingImpl<P>& encoder, uint32_t type, const U& nestedBlock)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800547{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700548 size_t valueLength = nestedBlock.wireEncode(encoder);
549 size_t totalLength = valueLength;
550 totalLength += encoder.prependVarNumber(valueLength);
551 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800552
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700553 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800554}
555
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800556template<bool P>
557inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700558prependBlock(EncodingImpl<P>& encoder, const Block& block)
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800559{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700560 return encoder.prependByteArray(block.wire(), block.size());
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800561}
562
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800563
Wentao Shang77949212014-02-01 23:42:24 -0800564} // ndn
565
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700566#endif // NDN_ENCODING_ENCODING_BUFFER_HPP