blob: e3e86f41352b07fde47ee8bd4e769afe29f8c2f1 [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 Afanasyev74633892015-02-08 18:08:46 -08003 * Copyright (c) 2013-2015 Regents of the University of California.
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -08004 *
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07005 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -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 Afanasyev13bb51a2014-01-02 19:13:26 -080020 */
21
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070022#ifndef NDN_ENCODING_BLOCK_HELPERS_HPP
23#define NDN_ENCODING_BLOCK_HELPERS_HPP
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080024
25#include "block.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070026#include "encoding-buffer.hpp"
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080027
Alexander Afanasyev74633892015-02-08 18:08:46 -080028#include <iterator>
29
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080030namespace ndn {
31
Alexander Afanasyev74633892015-02-08 18:08:46 -080032/**
33 * @deprecated Use Encoder::prependBlock and Estimator::prependBlock instead
34 */
35template<bool P>
36inline size_t
37prependBlock(EncodingImpl<P>& encoder, const Block& block)
38{
39 return encoder.prependBlock(block);
40}
41
42/**
43 * @deprecated Use Encoder::prependByteArrayBlock and Estimator::prependByteArrayBlock instead
44 */
45template<bool P>
46inline size_t
47prependByteArrayBlock(EncodingImpl<P>& encoder,
48 uint32_t type, const uint8_t* array, size_t arraySize)
49{
50 return encoder.prependByteArrayBlock(type, array, arraySize);
51}
52
53template<bool P>
54inline size_t
55prependNonNegativeIntegerBlock(EncodingImpl<P>& encoder, uint32_t type, uint64_t number)
56{
57 size_t valueLength = encoder.prependNonNegativeInteger(number);
58 size_t totalLength = valueLength;
59 totalLength += encoder.prependVarNumber(valueLength);
60 totalLength += encoder.prependVarNumber(type);
61
62 return totalLength;
63}
64
65template<bool P>
66inline size_t
67prependBooleanBlock(EncodingImpl<P>& encoder, uint32_t type)
68{
69 size_t totalLength = encoder.prependVarNumber(0);
70 totalLength += encoder.prependVarNumber(type);
71
72 return totalLength;
73}
74
75template<bool P, class U>
76inline size_t
77prependNestedBlock(EncodingImpl<P>& encoder, uint32_t type, const U& nestedBlock)
78{
79 size_t valueLength = nestedBlock.wireEncode(encoder);
80 size_t totalLength = valueLength;
81 totalLength += encoder.prependVarNumber(valueLength);
82 totalLength += encoder.prependVarNumber(type);
83
84 return totalLength;
85}
86
87
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080088inline Block
89nonNegativeIntegerBlock(uint32_t type, uint64_t value)
90{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070091 EncodingEstimator estimator;
92 size_t totalLength = prependNonNegativeIntegerBlock(estimator, type, value);
93
94 EncodingBuffer encoder(totalLength, 0);
95 prependNonNegativeIntegerBlock(encoder, type, value);
96
97 return encoder.block();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080098}
99
100inline uint64_t
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700101readNonNegativeInteger(const Block& block)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800102{
103 Buffer::const_iterator begin = block.value_begin();
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600104 return tlv::readNonNegativeInteger(block.value_size(), begin, block.value_end());
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800105}
106
107inline Block
108booleanBlock(uint32_t type)
109{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700110 EncodingEstimator estimator;
111 size_t totalLength = prependBooleanBlock(estimator, type);
112
113 EncodingBuffer encoder(totalLength, 0);
114 prependBooleanBlock(encoder, type);
115
116 return encoder.block();
117}
118
119inline Block
120dataBlock(uint32_t type, const uint8_t* data, size_t dataSize)
121{
122 EncodingEstimator estimator;
Alexander Afanasyev74633892015-02-08 18:08:46 -0800123 size_t totalLength = estimator.prependByteArrayBlock(type, data, dataSize);
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700124
125 EncodingBuffer encoder(totalLength, 0);
Alexander Afanasyev74633892015-02-08 18:08:46 -0800126 encoder.prependByteArrayBlock(type, data, dataSize);
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700127
128 return encoder.block();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800129}
130
131inline Block
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700132dataBlock(uint32_t type, const char* data, size_t dataSize)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800133{
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700134 return dataBlock(type, reinterpret_cast<const uint8_t*>(data), dataSize);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800135}
136
Alexander Afanasyev74633892015-02-08 18:08:46 -0800137/**
138 * @brief Helper class template to create a data block when RandomAccessIterator is used
139 */
140template<class Iterator>
141class DataBlockFast
142{
143public:
144 BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<Iterator>));
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800145
Alexander Afanasyev74633892015-02-08 18:08:46 -0800146 static Block
147 makeBlock(uint32_t type, Iterator first, Iterator last)
148 {
149 EncodingEstimator estimator;
150 size_t valueLength = last - first;
151 size_t totalLength = valueLength;
152 totalLength += estimator.prependVarNumber(valueLength);
153 totalLength += estimator.prependVarNumber(type);
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700154
Alexander Afanasyev74633892015-02-08 18:08:46 -0800155 EncodingBuffer encoder(totalLength, 0);
156 encoder.prependRange(first, last);
157 encoder.prependVarNumber(valueLength);
158 encoder.prependVarNumber(type);
159
160 return encoder.block();
161 }
162};
163
164/**
165 * @brief Helper class template to create a data block when generic InputIterator is used
166 */
167template<class Iterator>
168class DataBlockSlow
169{
170public:
171 BOOST_CONCEPT_ASSERT((boost::InputIterator<Iterator>));
172
173 static Block
174 makeBlock(uint32_t type, Iterator first, Iterator last)
175 {
176 // reserve 4 bytes in front (common for 1(type)-3(length) encoding
177 // Actual size will be adjusted as necessary by the encoder
178 EncodingBuffer encoder(4, 4);
179 size_t valueLength = encoder.appendRange(first, last);
180 encoder.prependVarNumber(valueLength);
181 encoder.prependVarNumber(type);
182
183 return encoder.block();
184 }
185};
186
187/**
188 * @brief Free function to create a block given @p type and range [@p first, @p last) of bytes
189 * @tparam Iterator iterator type satisfying at least InputIterator concept. Implementation
190 * is more optimal when the iterator type satisfies RandomAccessIterator concept
191 * It is required that sizeof(std::iterator_traits<Iterator>::value_type) == 1.
192 */
193template<class Iterator>
194inline Block
195dataBlock(uint32_t type, Iterator first, Iterator last)
196{
197 static_assert(sizeof(typename std::iterator_traits<Iterator>::value_type) == 1,
198 "Iterator should point only to char or unsigned char");
199
200 typedef typename boost::mpl::if_<
201 std::is_base_of<std::random_access_iterator_tag,
202 typename std::iterator_traits<Iterator>::iterator_category>,
203 DataBlockFast<Iterator>,
204 DataBlockSlow<Iterator>>::type DataBlock;
205
206 return DataBlock::makeBlock(type, first, last);
207}
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700208
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800209} // namespace ndn
210
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700211#endif // NDN_ENCODING_BLOCK_HELPERS_HPP