blob: 78b1628057604ea8266dfa5f4153fff5b4e1da0e [file] [log] [blame]
Wentao Shang77949212014-02-01 23:42:24 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 *
5 * BSD license, See the LICENSE file for more information
6 *
7 * Author: Wentao Shang <wentao@cs.ucla.edu>
8 */
9
10#ifndef NDN_ENCODING_BUFFER_HPP
11#define NDN_ENCODING_BUFFER_HPP
12
13#include "../common.hpp"
14
Wentao Shang77949212014-02-01 23:42:24 -080015#include "buffer.hpp"
16#include "tlv.hpp"
Alexander Afanasyev233750e2014-02-16 00:50:07 -080017#include "block.hpp"
Wentao Shang77949212014-02-01 23:42:24 -080018
19#include <boost/lexical_cast.hpp>
20
21namespace ndn {
22
Alexander Afanasyev217325b2014-02-06 15:03:28 -080023namespace encoding {
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -080024static const bool Buffer = true;
25static const bool Estimator = false;
Alexander Afanasyev217325b2014-02-06 15:03:28 -080026} // encoding
27
28template<bool isRealEncoderNotEstimator>
29class EncodingImpl;
30
31typedef EncodingImpl<encoding::Buffer> EncodingBuffer;
32typedef EncodingImpl<encoding::Estimator> EncodingEstimator;
33
Wentao Shang77949212014-02-01 23:42:24 -080034/**
35 * @brief Class representing wire element of the NDN packet
36 */
Alexander Afanasyev217325b2014-02-06 15:03:28 -080037template<>
38class EncodingImpl<encoding::Buffer>
Wentao Shang77949212014-02-01 23:42:24 -080039{
40public:
Wentao Shang77949212014-02-01 23:42:24 -080041 /**
Alexander Afanasyev217325b2014-02-06 15:03:28 -080042 * @brief Constructor to create a EncodingImpl with specified reserved sizes
43 *
44 * The caller should make sure that that reserveFromBack does not exceed totalReserve,
45 * otherwise behavior is undefined.
Wentao Shang77949212014-02-01 23:42:24 -080046 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070047 EncodingImpl(size_t totalReserve = 8800,
48 size_t reserveFromBack = 400)
49 : m_buffer(new Buffer(totalReserve))
Wentao Shang77949212014-02-01 23:42:24 -080050 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070051 m_begin = m_end = m_buffer->end() - (reserveFromBack < totalReserve ? reserveFromBack : 0);
Wentao Shang77949212014-02-01 23:42:24 -080052 }
53
Alexander Afanasyev15151312014-02-16 00:53:51 -080054 /**
55 * @brief Create EncodingBlock from existing block
56 *
57 * This is a dangerous constructor and should be used with caution.
58 * It will modify contents of the buffer that is used by block and may
59 * impact data in other blocks.
60 *
61 * The primary purpose for this method is to be used to extend Block
62 * after sign operation.
63 */
64 explicit
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070065 EncodingImpl(const Block& block)
Alexander Afanasyev15151312014-02-16 00:53:51 -080066 : m_buffer(const_pointer_cast<Buffer>(block.m_buffer))
67 , m_begin(m_buffer->begin() + (block.begin() - m_buffer->begin()))
68 , m_end(m_buffer->begin() + (block.end() - m_buffer->begin()))
69 {
70 }
Wentao Shang77949212014-02-01 23:42:24 -080071
72 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070073 size() const;
74
75 inline size_t
76 capacity() const;
Wentao Shang77949212014-02-01 23:42:24 -080077
78 inline uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070079 buf();
Wentao Shang77949212014-02-01 23:42:24 -080080
81 inline const uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070082 buf() const;
Wentao Shang77949212014-02-01 23:42:24 -080083
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080084 /**
85 * @brief Create Block from the underlying EncodingBuffer
86 *
87 * @param verifyLength If this parameter set to true, Block's constructor
88 * will be requested to verify consistency of the encoded
89 * length in the Block, otherwise ignored
90 */
Alexander Afanasyev187bc482014-02-06 15:04:04 -080091 inline Block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070092 block(bool verifyLength = true) const;
Alexander Afanasyev187bc482014-02-06 15:04:04 -080093
Wentao Shang77949212014-02-01 23:42:24 -080094 inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070095 resize(size_t size, bool addInFront);
Wentao Shang77949212014-02-01 23:42:24 -080096
97 inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070098 begin();
Wentao Shang77949212014-02-01 23:42:24 -080099
100 inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700101 end();
Wentao Shang77949212014-02-01 23:42:24 -0800102
103 inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700104 begin() const;
Wentao Shang77949212014-02-01 23:42:24 -0800105
106 inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700107 end() const;
Wentao Shang77949212014-02-01 23:42:24 -0800108
109 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700110 prependByte(uint8_t value);
Wentao Shang77949212014-02-01 23:42:24 -0800111
112 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700113 prependByteArray(const uint8_t* array, size_t length);
Wentao Shang77949212014-02-01 23:42:24 -0800114
115 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700116 prependNonNegativeInteger(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800117
118 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700119 prependVarNumber(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800120
121 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700122 appendByte(uint8_t value);
Wentao Shang77949212014-02-01 23:42:24 -0800123
124 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700125 appendByteArray(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 appendNonNegativeInteger(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800129
130 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700131 appendVarNumber(uint64_t varNumber);
Wentao Shang77949212014-02-01 23:42:24 -0800132
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800133 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700134 // removeByteFromFront();
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800135
136 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700137 // removeByteFromEnd();
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800138
139 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700140 // removeVarNumberFromFront(uint64_t varNumber);
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800141
142 // inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700143 // removeVarNumberFromBack(uint64_t varNumber);
144
Wentao Shang77949212014-02-01 23:42:24 -0800145private:
146 BufferPtr m_buffer;
147
148 // invariant: m_begin always points to the position of last-written byte (if prepending data)
149 Buffer::iterator m_begin;
150 // invariant: m_end always points to the position of next unwritten byte (if appending data)
151 Buffer::iterator m_end;
Alexander Afanasyev15151312014-02-16 00:53:51 -0800152
153 friend class Block;
Wentao Shang77949212014-02-01 23:42:24 -0800154};
155
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800156
157/**
158 * @brief Class representing wire element of the NDN packet
159 */
160template<>
161class EncodingImpl<encoding::Estimator>
162{
163public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700164 EncodingImpl(size_t totalReserve = 8800,
165 size_t reserveFromBack = 400)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800166 {
167 }
168
169 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700170 prependByte(uint8_t value);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800171
172 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700173 prependByteArray(const uint8_t* array, size_t length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800174
175 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700176 prependNonNegativeInteger(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800177
178 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700179 prependVarNumber(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800180
181 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700182 appendByte(uint8_t value);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800183
184 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700185 appendByteArray(const uint8_t* array, size_t length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800186
187 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700188 appendNonNegativeInteger(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800189
190 inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700191 appendVarNumber(uint64_t varNumber);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800192};
193
194
Wentao Shang77949212014-02-01 23:42:24 -0800195////////////////////////////////////////////////////////////////////////////////
196////////////////////////////////////////////////////////////////////////////////
197////////////////////////////////////////////////////////////////////////////////
198
199inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700200EncodingImpl<encoding::Buffer>::size() const
Wentao Shang77949212014-02-01 23:42:24 -0800201{
202 return m_end - m_begin;
203}
204
205inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700206EncodingImpl<encoding::Buffer>::capacity() const
Wentao Shang77949212014-02-01 23:42:24 -0800207{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700208 return m_buffer->size();
Wentao Shang77949212014-02-01 23:42:24 -0800209}
210
211inline uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700212EncodingImpl<encoding::Buffer>::buf()
Wentao Shang77949212014-02-01 23:42:24 -0800213{
214 return &(*m_begin);
215}
216
217inline const uint8_t*
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700218EncodingImpl<encoding::Buffer>::buf() const
Wentao Shang77949212014-02-01 23:42:24 -0800219{
220 return &(*m_begin);
221}
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800222
223inline Block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700224EncodingImpl<encoding::Buffer>::block(bool verifyLength/* = true*/) const
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800225{
226 return Block(m_buffer,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800227 m_begin, m_end,
228 verifyLength);
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800229}
230
Wentao Shang77949212014-02-01 23:42:24 -0800231inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700232EncodingImpl<encoding::Buffer>::resize(size_t size, bool addInFront)
Wentao Shang77949212014-02-01 23:42:24 -0800233{
234 if (addInFront)
235 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700236 size_t diff_end = m_buffer->end() - m_end;
237 size_t diff_begin = m_buffer->end() - m_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800238
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700239 Buffer* buf = new Buffer(size);
240 std::copy_backward(m_buffer->begin(), m_buffer->end(), buf->end());
Wentao Shang77949212014-02-01 23:42:24 -0800241
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700242 m_buffer.reset(buf);
Wentao Shang77949212014-02-01 23:42:24 -0800243
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700244 m_end = m_buffer->end() - diff_end;
245 m_begin = m_buffer->end() - diff_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800246 }
247 else
248 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700249 size_t diff_end = m_end - m_buffer->begin();
250 size_t diff_begin = m_begin - m_buffer->begin();
Wentao Shang77949212014-02-01 23:42:24 -0800251
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700252 Buffer* buf = new Buffer(size);
253 std::copy(m_buffer->begin(), m_buffer->end(), buf->begin());
Wentao Shang77949212014-02-01 23:42:24 -0800254
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700255 m_buffer.reset(buf);
Wentao Shang77949212014-02-01 23:42:24 -0800256
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700257 m_end = m_buffer->begin() + diff_end;
258 m_begin = m_buffer->begin() + diff_begin;
Wentao Shang77949212014-02-01 23:42:24 -0800259 }
260}
261
262inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700263EncodingImpl<encoding::Buffer>::begin()
Wentao Shang77949212014-02-01 23:42:24 -0800264{
265 return m_begin;
266}
267
268inline Buffer::iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700269EncodingImpl<encoding::Buffer>::end()
Wentao Shang77949212014-02-01 23:42:24 -0800270{
271 return m_end;
272}
273
274inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700275EncodingImpl<encoding::Buffer>::begin() const
Wentao Shang77949212014-02-01 23:42:24 -0800276{
277 return m_begin;
278}
279
280inline Buffer::const_iterator
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700281EncodingImpl<encoding::Buffer>::end() const
Wentao Shang77949212014-02-01 23:42:24 -0800282{
283 return m_end;
284}
285
286
287//////////////////////////////////////////////////////////
288// Prepend to the back of the buffer. Resize if needed. //
289//////////////////////////////////////////////////////////
290
291inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700292EncodingImpl<encoding::Buffer>::prependByte(uint8_t value)
Wentao Shang77949212014-02-01 23:42:24 -0800293{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700294 if (m_begin == m_buffer->begin())
295 resize(m_buffer->size() * 2, true);
Wentao Shang77949212014-02-01 23:42:24 -0800296
297 m_begin--;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700298 *m_begin = value;
Wentao Shang77949212014-02-01 23:42:24 -0800299 return 1;
300}
301
302inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700303EncodingImpl<encoding::Estimator>::prependByte(uint8_t value)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800304{
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800305 return 1;
306}
307
308inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700309EncodingImpl<encoding::Buffer>::prependByteArray(const uint8_t* array, size_t length)
Wentao Shang77949212014-02-01 23:42:24 -0800310{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700311 if ((m_buffer->begin() + length) > m_begin)
312 resize(m_buffer->size() * 2 + length, true);
Wentao Shang77949212014-02-01 23:42:24 -0800313
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700314 m_begin -= length;
315 std::copy(array, array + length, m_begin);
316 return length;
Wentao Shang77949212014-02-01 23:42:24 -0800317}
318
319inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700320EncodingImpl<encoding::Estimator>::prependByteArray(const uint8_t* array, size_t length)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800321{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700322 return length;
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800323}
324
325inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700326EncodingImpl<encoding::Buffer>::prependNonNegativeInteger(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800327{
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -0800328 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700329 return prependByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800330 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700331 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
332 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
333 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800334 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700335 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
336 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
337 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800338 }
339 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700340 uint64_t value = htobe64(varNumber);
341 return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800342 }
343}
344
345inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700346EncodingImpl<encoding::Estimator>::prependNonNegativeInteger(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800347{
Alexander Afanasyev2d0b4572014-02-24 16:02:12 -0800348 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800349 return 1;
350 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700351 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800352 return 2;
353 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700354 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800355 return 4;
356 }
357 else {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800358 return 8;
359 }
360}
361
362inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700363EncodingImpl<encoding::Buffer>::prependVarNumber(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800364{
365 if (varNumber < 253) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700366 prependByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800367 return 1;
368 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700369 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
370 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
371 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
372 prependByte(253);
Wentao Shang77949212014-02-01 23:42:24 -0800373 return 3;
374 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700375 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
376 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
377 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
378 prependByte(254);
Wentao Shang77949212014-02-01 23:42:24 -0800379 return 5;
380 }
381 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700382 uint64_t value = htobe64(varNumber);
383 prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
384 prependByte(255);
Wentao Shang77949212014-02-01 23:42:24 -0800385 return 9;
386 }
387}
388
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800389inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700390EncodingImpl<encoding::Estimator>::prependVarNumber(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800391{
392 if (varNumber < 253) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800393 return 1;
394 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700395 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800396 return 3;
397 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700398 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800399 return 5;
400 }
401 else {
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800402 return 9;
403 }
404}
405
Wentao Shang77949212014-02-01 23:42:24 -0800406/////////////////////////////////////////////////////////
407// Append to the back of the buffer. Resize if needed. //
408/////////////////////////////////////////////////////////
409
410inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700411EncodingImpl<encoding::Buffer>::appendByte(uint8_t value)
Wentao Shang77949212014-02-01 23:42:24 -0800412{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700413 if (m_end == m_buffer->end())
414 resize(m_buffer->size() * 2, false);
Wentao Shang77949212014-02-01 23:42:24 -0800415
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700416 *m_end = value;
Wentao Shang77949212014-02-01 23:42:24 -0800417 m_end++;
418 return 1;
419}
420
421inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700422EncodingImpl<encoding::Estimator>::appendByte(uint8_t value)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800423{
424 return 1;
425}
426
427inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700428EncodingImpl<encoding::Buffer>::appendByteArray(const uint8_t* array, size_t length)
Wentao Shang77949212014-02-01 23:42:24 -0800429{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700430 if ((m_end + length) > m_buffer->end())
431 resize(m_buffer->size() * 2 + length, false);
Wentao Shang77949212014-02-01 23:42:24 -0800432
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700433 std::copy(array, array + length, m_end);
434 m_end += length;
435 return length;
Wentao Shang77949212014-02-01 23:42:24 -0800436}
437
438inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700439EncodingImpl<encoding::Estimator>::appendByteArray(const uint8_t* array, size_t length)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800440{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700441 return prependByteArray(array, length);
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800442}
443
444inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700445EncodingImpl<encoding::Buffer>::appendNonNegativeInteger(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800446{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700447 if (varNumber <= std::numeric_limits<uint8_t>::max()) {
448 return appendByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800449 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700450 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
451 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
452 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800453 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700454 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
455 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
456 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800457 }
458 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700459 uint64_t value = htobe64(varNumber);
460 return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800461 }
462}
463
464inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700465EncodingImpl<encoding::Estimator>::appendNonNegativeInteger(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800466{
467 return prependNonNegativeInteger(varNumber);
468}
469
470inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700471EncodingImpl<encoding::Buffer>::appendVarNumber(uint64_t varNumber)
Wentao Shang77949212014-02-01 23:42:24 -0800472{
473 if (varNumber < 253) {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700474 appendByte(static_cast<uint8_t>(varNumber));
Wentao Shang77949212014-02-01 23:42:24 -0800475 return 1;
476 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700477 else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
478 appendByte(253);
479 uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
480 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
Wentao Shang77949212014-02-01 23:42:24 -0800481 return 3;
482 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700483 else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
484 appendByte(254);
485 uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
486 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
Wentao Shang77949212014-02-01 23:42:24 -0800487 return 5;
488 }
489 else {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700490 appendByte(255);
491 uint64_t value = htobe64(varNumber);
492 appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
Wentao Shang77949212014-02-01 23:42:24 -0800493 return 9;
494 }
495}
496
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800497inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700498EncodingImpl<encoding::Estimator>::appendVarNumber(uint64_t varNumber)
Alexander Afanasyev217325b2014-02-06 15:03:28 -0800499{
500 return prependVarNumber(varNumber);
501}
502
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800503/// helper methods
504
505template<bool P>
506inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700507prependNonNegativeIntegerBlock(EncodingImpl<P>& encoder, uint32_t type, uint64_t number)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800508{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700509 size_t valueLength = encoder.prependNonNegativeInteger(number);
510 size_t totalLength = valueLength;
511 totalLength += encoder.prependVarNumber(valueLength);
512 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800513
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700514 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800515}
516
517template<bool P>
518inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700519prependByteArrayBlock(EncodingImpl<P>& encoder, uint32_t type,
520 const uint8_t* array, size_t arraySize)
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800521{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700522 size_t valueLength = encoder.prependByteArray(array, arraySize);
523 size_t totalLength = valueLength;
524 totalLength += encoder.prependVarNumber(valueLength);
525 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800526
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700527 return totalLength;
Alexander Afanasyev0553cd52014-02-18 02:34:45 -0800528}
529
530template<bool P>
531inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700532prependBooleanBlock(EncodingImpl<P>& encoder, uint32_t type)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800533{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700534 size_t totalLength = encoder.prependVarNumber(0);
535 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800536
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700537 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800538}
539
540
541template<bool P, class U>
542inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700543prependNestedBlock(EncodingImpl<P>& encoder, uint32_t type, const U& nestedBlock)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800544{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700545 size_t valueLength = nestedBlock.wireEncode(encoder);
546 size_t totalLength = valueLength;
547 totalLength += encoder.prependVarNumber(valueLength);
548 totalLength += encoder.prependVarNumber(type);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800549
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700550 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800551}
552
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800553template<bool P>
554inline size_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700555prependBlock(EncodingImpl<P>& encoder, const Block& block)
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800556{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700557 return encoder.prependByteArray(block.wire(), block.size());
Alexander Afanasyev809805d2014-02-17 17:20:33 -0800558}
559
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800560
Wentao Shang77949212014-02-01 23:42:24 -0800561} // ndn
562
563#endif // NDN_ENCODING_BUFFER_HPP