blob: 07ee33de03c4a598feae8e48f4e4eb0f19af367f [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
16#ifndef NDN_ENCODING_BUFFER_HPP
17#define NDN_ENCODING_BUFFER_HPP
18
19#include "../common.hpp"
20
Wentao Shang77949212014-02-01 23:42:24 -080021#include "buffer.hpp"
22#include "tlv.hpp"
Alexander Afanasyev233750e2014-02-16 00:50:07 -080023#include "block.hpp"
Wentao Shang77949212014-02-01 23:42:24 -080024
25#include <boost/lexical_cast.hpp>
26
27namespace ndn {
28
Alexander Afanasyev217325b2014-02-06 15:03:28 -080029namespace encoding {
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080030static const bool Buffer = true;
31static const bool Estimator = false;
Alexander Afanasyev217325b2014-02-06 15:03:28 -080032} // encoding
33
34template<bool isRealEncoderNotEstimator>
35class EncodingImpl;
36
37typedef EncodingImpl<encoding::Buffer> EncodingBuffer;
38typedef EncodingImpl<encoding::Estimator> EncodingEstimator;
39
Wentao Shang77949212014-02-01 23:42:24 -080040/**
41 * @brief Class representing wire element of the NDN packet
42 */
Alexander Afanasyev217325b2014-02-06 15:03:28 -080043template<>
44class EncodingImpl<encoding::Buffer>
Wentao Shang77949212014-02-01 23:42:24 -080045{
46public:
Wentao Shang77949212014-02-01 23:42:24 -080047 /**
Alexander Afanasyev217325b2014-02-06 15:03:28 -080048 * @brief Constructor to create a EncodingImpl with specified reserved sizes
49 *
50 * The caller should make sure that that reserveFromBack does not exceed totalReserve,
51 * otherwise behavior is undefined.
Wentao Shang77949212014-02-01 23:42:24 -080052 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070053 EncodingImpl(size_t totalReserve = 8800,
54 size_t reserveFromBack = 400)
55 : m_buffer(new Buffer(totalReserve))
Wentao Shang77949212014-02-01 23:42:24 -080056 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070057 m_begin = m_end = m_buffer->end() - (reserveFromBack < totalReserve ? reserveFromBack : 0);
Wentao Shang77949212014-02-01 23:42:24 -080058 }
59
Alexander Afanasyev15151312014-02-16 00:53:51 -080060 /**
61 * @brief Create EncodingBlock from existing block
62 *
63 * This is a dangerous constructor and should be used with caution.
64 * It will modify contents of the buffer that is used by block and may
65 * impact data in other blocks.
66 *
67 * The primary purpose for this method is to be used to extend Block
68 * after sign operation.
69 */
70 explicit
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070071 EncodingImpl(const Block& block)
Alexander Afanasyev15151312014-02-16 00:53:51 -080072 : m_buffer(const_pointer_cast<Buffer>(block.m_buffer))
73 , m_begin(m_buffer->begin() + (block.begin() - m_buffer->begin()))
74 , m_end(m_buffer->begin() + (block.end() - m_buffer->begin()))
75 {
76 }
Wentao Shang77949212014-02-01 23:42:24 -080077
78 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070079 size() const;
80
81 inline size_t
82 capacity() const;
Wentao Shang77949212014-02-01 23:42:24 -080083
84 inline uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070085 buf();
Wentao Shang77949212014-02-01 23:42:24 -080086
87 inline const uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070088 buf() const;
Wentao Shang77949212014-02-01 23:42:24 -080089
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080090 /**
91 * @brief Create Block from the underlying EncodingBuffer
92 *
93 * @param verifyLength If this parameter set to true, Block's constructor
94 * will be requested to verify consistency of the encoded
95 * length in the Block, otherwise ignored
96 */
Alexander Afanasyev187bc482014-02-06 15:04:04 -080097 inline Block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070098 block(bool verifyLength = true) const;
Alexander Afanasyev187bc482014-02-06 15:04:04 -080099
Wentao Shang77949212014-02-01 23:42:24 -0800100 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700101 resize(size_t size, bool addInFront);
Wentao Shang77949212014-02-01 23:42:24 -0800102
103 inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700104 begin();
Wentao Shang77949212014-02-01 23:42:24 -0800105
106 inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700107 end();
Wentao Shang77949212014-02-01 23:42:24 -0800108
109 inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700110 begin() const;
Wentao Shang77949212014-02-01 23:42:24 -0800111
112 inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700113 end() const;
Wentao Shang77949212014-02-01 23:42:24 -0800114
115 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700116 prependByte(uint8_t value);
Wentao Shang77949212014-02-01 23:42:24 -0800117
118 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700119 prependByteArray(const uint8_t* array, size_t length);
Wentao Shang77949212014-02-01 23:42:24 -0800120
121 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700122 prependNonNegativeInteger(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800123
124 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700125 prependVarNumber(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800126
127 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700128 appendByte(uint8_t value);
Wentao Shang77949212014-02-01 23:42:24 -0800129
130 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700131 appendByteArray(const uint8_t* array, size_t length);
Wentao Shang77949212014-02-01 23:42:24 -0800132
133 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700134 appendNonNegativeInteger(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800135
136 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700137 appendVarNumber(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800138
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800139 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700140 // removeByteFromFront();
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800141
142 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700143 // removeByteFromEnd();
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800144
145 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700146 // removeVarNumberFromFront(uint64_t varNumber);
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800147
148 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700149 // removeVarNumberFromBack(uint64_t varNumber);
150
Wentao Shang77949212014-02-01 23:42:24 -0800151private:
152 BufferPtr m_buffer;
153
154 // invariant: m_begin always points to the position of last-written byte (if prepending data)
155 Buffer::iterator m_begin;
156 // invariant: m_end always points to the position of next unwritten byte (if appending data)
157 Buffer::iterator m_end;
Alexander Afanasyev15151312014-02-16 00:53:51 -0800158
159 friend class Block;
Wentao Shang77949212014-02-01 23:42:24 -0800160};
161
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800162
163/**
164 * @brief Class representing wire element of the NDN packet
165 */
166template<>
167class EncodingImpl<encoding::Estimator>
168{
169public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700170 EncodingImpl(size_t totalReserve = 8800,
171 size_t reserveFromBack = 400)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800172 {
173 }
174
175 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700176 prependByte(uint8_t value);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800177
178 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700179 prependByteArray(const uint8_t* array, size_t length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800180
181 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700182 prependNonNegativeInteger(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800183
184 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700185 prependVarNumber(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800186
187 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700188 appendByte(uint8_t value);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800189
190 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700191 appendByteArray(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 appendNonNegativeInteger(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800195
196 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700197 appendVarNumber(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800198};
199
200
Wentao Shang77949212014-02-01 23:42:24 -0800201////////////////////////////////////////////////////////////////////////////////
202////////////////////////////////////////////////////////////////////////////////
203////////////////////////////////////////////////////////////////////////////////
204
205inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700206EncodingImpl<encoding::Buffer>::size() const
Wentao Shang77949212014-02-01 23:42:24 -0800207{
208 return m_end - m_begin;
209}
210
211inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700212EncodingImpl<encoding::Buffer>::capacity() const
Wentao Shang77949212014-02-01 23:42:24 -0800213{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700214 return m_buffer->size();
Wentao Shang77949212014-02-01 23:42:24 -0800215}
216
217inline uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700218EncodingImpl<encoding::Buffer>::buf()
Wentao Shang77949212014-02-01 23:42:24 -0800219{
220 return &(*m_begin);
221}
222
223inline const uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700224EncodingImpl<encoding::Buffer>::buf() const
Wentao Shang77949212014-02-01 23:42:24 -0800225{
226 return &(*m_begin);
227}
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800228
229inline Block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700230EncodingImpl<encoding::Buffer>::block(bool verifyLength/* = true*/) const
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800231{
232 return Block(m_buffer,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800233 m_begin, m_end,
234 verifyLength);
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800235}
236
Wentao Shang77949212014-02-01 23:42:24 -0800237inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700238EncodingImpl<encoding::Buffer>::resize(size_t size, bool addInFront)
Wentao Shang77949212014-02-01 23:42:24 -0800239{
240 if (addInFront)
241 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700242 size_t diff_end = m_buffer->end() - m_end;
243 size_t diff_begin = m_buffer->end() - m_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800244
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700245 Buffer* buf = new Buffer(size);
246 std::copy_backward(m_buffer->begin(), m_buffer->end(), buf->end());
Wentao Shang77949212014-02-01 23:42:24 -0800247
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700248 m_buffer.reset(buf);
Wentao Shang77949212014-02-01 23:42:24 -0800249
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700250 m_end = m_buffer->end() - diff_end;
251 m_begin = m_buffer->end() - diff_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800252 }
253 else
254 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700255 size_t diff_end = m_end - m_buffer->begin();
256 size_t diff_begin = m_begin - m_buffer->begin();
Wentao Shang77949212014-02-01 23:42:24 -0800257
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700258 Buffer* buf = new Buffer(size);
259 std::copy(m_buffer->begin(), m_buffer->end(), buf->begin());
Wentao Shang77949212014-02-01 23:42:24 -0800260
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700261 m_buffer.reset(buf);
Wentao Shang77949212014-02-01 23:42:24 -0800262
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700263 m_end = m_buffer->begin() + diff_end;
264 m_begin = m_buffer->begin() + diff_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800265 }
266}
267
268inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700269EncodingImpl<encoding::Buffer>::begin()
Wentao Shang77949212014-02-01 23:42:24 -0800270{
271 return m_begin;
272}
273
274inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700275EncodingImpl<encoding::Buffer>::end()
Wentao Shang77949212014-02-01 23:42:24 -0800276{
277 return m_end;
278}
279
280inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700281EncodingImpl<encoding::Buffer>::begin() const
Wentao Shang77949212014-02-01 23:42:24 -0800282{
283 return m_begin;
284}
285
286inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700287EncodingImpl<encoding::Buffer>::end() const
Wentao Shang77949212014-02-01 23:42:24 -0800288{
289 return m_end;
290}
291
292
293//////////////////////////////////////////////////////////
294// Prepend to the back of the buffer. Resize if needed. //
295//////////////////////////////////////////////////////////
296
297inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700298EncodingImpl<encoding::Buffer>::prependByte(uint8_t value)
Wentao Shang77949212014-02-01 23:42:24 -0800299{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700300 if (m_begin == m_buffer->begin())
301 resize(m_buffer->size() * 2, true);
Wentao Shang77949212014-02-01 23:42:24 -0800302
303 m_begin--;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700304 *m_begin = value;
Wentao Shang77949212014-02-01 23:42:24 -0800305 return 1;
306}
307
308inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700309EncodingImpl<encoding::Estimator>::prependByte(uint8_t value)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800310{
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800311 return 1;
312}
313
314inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700315EncodingImpl<encoding::Buffer>::prependByteArray(const uint8_t* array, size_t length)
Wentao Shang77949212014-02-01 23:42:24 -0800316{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700317 if ((m_buffer->begin() + length) > m_begin)
318 resize(m_buffer->size() * 2 + length, true);
Wentao Shang77949212014-02-01 23:42:24 -0800319
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700320 m_begin -= length;
321 std::copy(array, array + length, m_begin);
322 return length;
Wentao Shang77949212014-02-01 23:42:24 -0800323}
324
325inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700326EncodingImpl<encoding::Estimator>::prependByteArray(const uint8_t* array, size_t length)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800327{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700328 return length;
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800329}
330
331inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700332EncodingImpl<encoding::Buffer>::prependNonNegativeInteger(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800333{
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -0800334 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700335 return prependByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800336 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700337 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
338 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
339 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800340 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700341 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
342 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
343 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800344 }
345 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700346 uint64_t value = htobe64(varNumber);
347 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800348 }
349}
350
351inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700352EncodingImpl<encoding::Estimator>::prependNonNegativeInteger(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800353{
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -0800354 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800355 return 1;
356 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700357 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800358 return 2;
359 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700360 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800361 return 4;
362 }
363 else {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800364 return 8;
365 }
366}
367
368inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700369EncodingImpl<encoding::Buffer>::prependVarNumber(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800370{
371 if (varNumber < 253) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700372 prependByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800373 return 1;
374 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700375 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
376 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
377 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
378 prependByte(253);
Wentao Shang77949212014-02-01 23:42:24 -0800379 return 3;
380 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700381 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
382 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
383 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
384 prependByte(254);
Wentao Shang77949212014-02-01 23:42:24 -0800385 return 5;
386 }
387 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700388 uint64_t value = htobe64(varNumber);
389 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
390 prependByte(255);
Wentao Shang77949212014-02-01 23:42:24 -0800391 return 9;
392 }
393}
394
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800395inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700396EncodingImpl<encoding::Estimator>::prependVarNumber(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800397{
398 if (varNumber < 253) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800399 return 1;
400 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700401 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800402 return 3;
403 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700404 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800405 return 5;
406 }
407 else {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800408 return 9;
409 }
410}
411
Wentao Shang77949212014-02-01 23:42:24 -0800412/////////////////////////////////////////////////////////
413// Append to the back of the buffer. Resize if needed. //
414/////////////////////////////////////////////////////////
415
416inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700417EncodingImpl<encoding::Buffer>::appendByte(uint8_t value)
Wentao Shang77949212014-02-01 23:42:24 -0800418{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700419 if (m_end == m_buffer->end())
420 resize(m_buffer->size() * 2, false);
Wentao Shang77949212014-02-01 23:42:24 -0800421
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700422 *m_end = value;
Wentao Shang77949212014-02-01 23:42:24 -0800423 m_end++;
424 return 1;
425}
426
427inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700428EncodingImpl<encoding::Estimator>::appendByte(uint8_t value)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800429{
430 return 1;
431}
432
433inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700434EncodingImpl<encoding::Buffer>::appendByteArray(const uint8_t* array, size_t length)
Wentao Shang77949212014-02-01 23:42:24 -0800435{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700436 if ((m_end + length) > m_buffer->end())
437 resize(m_buffer->size() * 2 + length, false);
Wentao Shang77949212014-02-01 23:42:24 -0800438
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700439 std::copy(array, array + length, m_end);
440 m_end += length;
441 return length;
Wentao Shang77949212014-02-01 23:42:24 -0800442}
443
444inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700445EncodingImpl<encoding::Estimator>::appendByteArray(const uint8_t* array, size_t length)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800446{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700447 return prependByteArray(array, length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800448}
449
450inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700451EncodingImpl<encoding::Buffer>::appendNonNegativeInteger(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800452{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700453 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
454 return appendByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800455 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700456 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
457 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
458 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800459 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700460 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
461 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
462 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800463 }
464 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700465 uint64_t value = htobe64(varNumber);
466 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800467 }
468}
469
470inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700471EncodingImpl<encoding::Estimator>::appendNonNegativeInteger(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800472{
473 return prependNonNegativeInteger(varNumber);
474}
475
476inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700477EncodingImpl<encoding::Buffer>::appendVarNumber(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800478{
479 if (varNumber < 253) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700480 appendByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800481 return 1;
482 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700483 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
484 appendByte(253);
485 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
486 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800487 return 3;
488 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700489 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
490 appendByte(254);
491 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
492 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800493 return 5;
494 }
495 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700496 appendByte(255);
497 uint64_t value = htobe64(varNumber);
498 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800499 return 9;
500 }
501}
502
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800503inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700504EncodingImpl<encoding::Estimator>::appendVarNumber(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800505{
506 return prependVarNumber(varNumber);
507}
508
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800509/// helper methods
510
511template<bool P>
512inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700513prependNonNegativeIntegerBlock(EncodingImpl<P>& encoder, uint32_t type, uint64_t number)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800514{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700515 size_t valueLength = encoder.prependNonNegativeInteger(number);
516 size_t totalLength = valueLength;
517 totalLength += encoder.prependVarNumber(valueLength);
518 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800519
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700520 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800521}
522
523template<bool P>
524inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700525prependByteArrayBlock(EncodingImpl<P>& encoder, uint32_t type,
526 const uint8_t* array, size_t arraySize)
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800527{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700528 size_t valueLength = encoder.prependByteArray(array, arraySize);
529 size_t totalLength = valueLength;
530 totalLength += encoder.prependVarNumber(valueLength);
531 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800532
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700533 return totalLength;
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800534}
535
536template<bool P>
537inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700538prependBooleanBlock(EncodingImpl<P>& encoder, uint32_t type)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800539{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700540 size_t totalLength = encoder.prependVarNumber(0);
541 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800542
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700543 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800544}
545
546
547template<bool P, class U>
548inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700549prependNestedBlock(EncodingImpl<P>& encoder, uint32_t type, const U& nestedBlock)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800550{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700551 size_t valueLength = nestedBlock.wireEncode(encoder);
552 size_t totalLength = valueLength;
553 totalLength += encoder.prependVarNumber(valueLength);
554 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800555
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700556 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800557}
558
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800559template<bool P>
560inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700561prependBlock(EncodingImpl<P>& encoder, const Block& block)
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800562{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700563 return encoder.prependByteArray(block.wire(), block.size());
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800564}
565
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800566
Wentao Shang77949212014-02-01 23:42:24 -0800567} // ndn
568
569#endif // NDN_ENCODING_BUFFER_HPP