blob: fcc8458d70af061b4527839b0934b6962a5d0cee [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 Afanasyevd5c48e02015-06-24 11:58:14 -070027#include "../util/concepts.hpp"
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080028
Alexander Afanasyev74633892015-02-08 18:08:46 -080029#include <iterator>
30
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080031namespace ndn {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070032namespace encoding {
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080033
Alexander Afanasyev74633892015-02-08 18:08:46 -080034/**
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070035 * @brief Helper to prepend TLV block type @p type containing non-negative integer @p value
36 * @see makeNonNegativeIntegerBlock, readNonNegativeInteger
Alexander Afanasyev74633892015-02-08 18:08:46 -080037 */
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070038template<Tag TAG>
39size_t
40prependNonNegativeIntegerBlock(EncodingImpl<TAG>& encoder, uint32_t type, uint64_t value);
Alexander Afanasyev74633892015-02-08 18:08:46 -080041
42/**
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070043 * @brief Create a TLV block type @p type containing non-negative integer @p value
44 * @see prependNonNegativeIntegerBlock, readNonNegativeInteger
Alexander Afanasyev74633892015-02-08 18:08:46 -080045 */
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070046Block
47makeNonNegativeIntegerBlock(uint32_t type, uint64_t value);
Alexander Afanasyev74633892015-02-08 18:08:46 -080048
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070049/**
50 * @brief Helper to read a non-negative integer from a block
51 * @see prependNonNegativeIntegerBlock, makeNonNegativeIntegerBlock
52 * @throw tlv::Error if block does not contain a valid nonNegativeInteger
53 */
54uint64_t
55readNonNegativeInteger(const Block& block);
Alexander Afanasyev74633892015-02-08 18:08:46 -080056
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070057////////
Alexander Afanasyev74633892015-02-08 18:08:46 -080058
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070059/**
60 * @brief Helper to prepend TLV block type @p type containing no value (i.e., a boolean block)
61 * @see makeEmptyBlock
62 */
63template<Tag TAG>
64size_t
65prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type);
Alexander Afanasyev74633892015-02-08 18:08:46 -080066
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070067/**
68 * @brief Create a TLV block type @p type containing no value (i.e., a boolean block)
69 * @see prependEmptyBlock
70 */
71Block
72makeEmptyBlock(uint32_t type);
Alexander Afanasyev74633892015-02-08 18:08:46 -080073
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070074////////
Alexander Afanasyev74633892015-02-08 18:08:46 -080075
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070076/**
77 * @brief Helper to prepend TLV block type @p type with value from a string @p value
78 * @see makeStringBlock, readString
79 */
80template<Tag TAG>
81size_t
82prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value);
Alexander Afanasyev74633892015-02-08 18:08:46 -080083
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070084/**
Alexander Afanasyevf2a46222015-09-17 18:01:30 -070085 * @brief Create a TLV block type @p type with value from a string @p value
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070086 * @see prependStringBlock, readString
87 */
88Block
89makeStringBlock(uint32_t type, const std::string& value);
Alexander Afanasyev74633892015-02-08 18:08:46 -080090
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070091/**
92 * @brief Helper to read a string value from a block
93 * @see prependStringBlock, makeStringBlock
94 */
95std::string
96readString(const Block& block);
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070097
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070098////////
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070099
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700100/**
101 * @brief Create a TLV block type @p type with value from a buffer @p value of size @p length
102 */
103Block
104makeBinaryBlock(uint32_t type, const uint8_t* value, size_t length);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800105
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700106/**
107 * @brief Create a TLV block type @p type with value from a buffer @p value of size @p length
108 */
109Block
110makeBinaryBlock(uint32_t type, const char* value, size_t length);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800111
Alexander Afanasyev74633892015-02-08 18:08:46 -0800112/**
113 * @brief Helper class template to create a data block when RandomAccessIterator is used
114 */
115template<class Iterator>
116class DataBlockFast
117{
118public:
119 BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<Iterator>));
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800120
Alexander Afanasyev74633892015-02-08 18:08:46 -0800121 static Block
122 makeBlock(uint32_t type, Iterator first, Iterator last)
123 {
124 EncodingEstimator estimator;
125 size_t valueLength = last - first;
126 size_t totalLength = valueLength;
127 totalLength += estimator.prependVarNumber(valueLength);
128 totalLength += estimator.prependVarNumber(type);
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700129
Alexander Afanasyev74633892015-02-08 18:08:46 -0800130 EncodingBuffer encoder(totalLength, 0);
131 encoder.prependRange(first, last);
132 encoder.prependVarNumber(valueLength);
133 encoder.prependVarNumber(type);
134
135 return encoder.block();
136 }
137};
138
139/**
140 * @brief Helper class template to create a data block when generic InputIterator is used
141 */
142template<class Iterator>
143class DataBlockSlow
144{
145public:
146 BOOST_CONCEPT_ASSERT((boost::InputIterator<Iterator>));
147
148 static Block
149 makeBlock(uint32_t type, Iterator first, Iterator last)
150 {
151 // reserve 4 bytes in front (common for 1(type)-3(length) encoding
152 // Actual size will be adjusted as necessary by the encoder
153 EncodingBuffer encoder(4, 4);
154 size_t valueLength = encoder.appendRange(first, last);
155 encoder.prependVarNumber(valueLength);
156 encoder.prependVarNumber(type);
157
158 return encoder.block();
159 }
160};
161
162/**
163 * @brief Free function to create a block given @p type and range [@p first, @p last) of bytes
164 * @tparam Iterator iterator type satisfying at least InputIterator concept. Implementation
165 * is more optimal when the iterator type satisfies RandomAccessIterator concept
166 * It is required that sizeof(std::iterator_traits<Iterator>::value_type) == 1.
167 */
168template<class Iterator>
169inline Block
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700170makeBinaryBlock(uint32_t type, Iterator first, Iterator last)
Alexander Afanasyev74633892015-02-08 18:08:46 -0800171{
172 static_assert(sizeof(typename std::iterator_traits<Iterator>::value_type) == 1,
173 "Iterator should point only to char or unsigned char");
174
175 typedef typename boost::mpl::if_<
176 std::is_base_of<std::random_access_iterator_tag,
177 typename std::iterator_traits<Iterator>::iterator_category>,
178 DataBlockFast<Iterator>,
179 DataBlockSlow<Iterator>>::type DataBlock;
180
181 return DataBlock::makeBlock(type, first, last);
182}
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700183
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700184////////
185
186/**
187 * @brief Prepend a TLV block of type @p type with WireEncodable @p value as a value
188 * @tparam U type that satisfies WireEncodableWithEncodingBuffer concept
189 * @see makeNestedBlock
190 */
191template<Tag TAG, class U>
192inline size_t
193prependNestedBlock(EncodingImpl<TAG>& encoder, uint32_t type, const U& value)
194{
195 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<U>));
196
197 size_t valueLength = value.wireEncode(encoder);
198 size_t totalLength = valueLength;
199 totalLength += encoder.prependVarNumber(valueLength);
200 totalLength += encoder.prependVarNumber(type);
201
202 return totalLength;
203}
204
205/**
206 * @brief Create a TLV block of type @p type with WireEncodable @p value as a value
207 * @tparam U type that satisfies WireEncodableWithEncodingBuffer concept
208 * @see prependNestedBlock
209 */
210template<class U>
211inline Block
212makeNestedBlock(uint32_t type, const U& value)
213{
214 EncodingEstimator estimator;
215 size_t totalLength = prependNestedBlock(estimator, type, value);
216
217 EncodingBuffer encoder(totalLength, 0);
218 prependNestedBlock(encoder, type, value);
219
220 return encoder.block();
221}
222
223#define NDN_CXX_ENABLE_DEPRECATED_BLOCK_HELPERS
224#ifdef NDN_CXX_ENABLE_DEPRECATED_BLOCK_HELPERS
225
226/**
227 * @deprecated Use Encoder::prependBlock and Estimator::prependBlock instead
228 */
229template<Tag TAG>
230inline size_t
231prependBlock(EncodingImpl<TAG>& encoder, const Block& block)
232{
233 return encoder.prependBlock(block);
234}
235
236/**
237 * @deprecated Use Encoder::prependByteArrayBlock and Estimator::prependByteArrayBlock instead
238 */
239template<Tag TAG>
240inline size_t
241prependByteArrayBlock(EncodingImpl<TAG>& encoder,
242 uint32_t type, const uint8_t* array, size_t arraySize)
243{
244 return encoder.prependByteArrayBlock(type, array, arraySize);
245}
246
247/**
248 * @deprecated Use makeNonNegativeIntegerBlock instead
249 */
250inline Block
251nonNegativeIntegerBlock(uint32_t type, uint64_t value)
252{
253 return makeNonNegativeIntegerBlock(type, value);
254}
255
256/**
257 * @deprecated Use prependEmptyBlock instead
258 */
259template<Tag TAG>
260size_t
261prependBooleanBlock(EncodingImpl<TAG>& encoder, uint32_t type)
262{
263 return prependEmptyBlock(encoder, type);
264}
265
266/**
267 * @deprecated Use makeEmptyBlock instead
268 */
269inline Block
270booleanBlock(uint32_t type)
271{
272 return makeEmptyBlock(type);
273}
274
275/**
276 * @deprecated Use makeBinaryBlock instead
277 */
278inline Block
279dataBlock(uint32_t type, const uint8_t* data, size_t dataSize)
280{
281 return makeBinaryBlock(type, data, dataSize);
282}
283
284/**
285 * @deprecated Use makeBinaryBlock instead
286 */
287inline Block
288dataBlock(uint32_t type, const char* data, size_t dataSize)
289{
290 return makeBinaryBlock(type, data, dataSize);
291}
292
293/**
294 * @deprecated Use makeBinaryBlock instead
295 */
296template<class Iterator>
297inline Block
298dataBlock(uint32_t type, Iterator first, Iterator last)
299{
300 return makeBinaryBlock(type, first, last);
301}
302
303/**
304 * @deprecated Use makeNestedBlock instead
305 */
306template<class U>
307inline Block
308nestedBlock(uint32_t type, const U& value)
309{
310 return makeNestedBlock(type, value);
311}
312
313#endif // NDN_CXX_ENABLE_DEPRECATED_BLOCK_HELPERS
314
315} // namespace encoding
316
317using encoding::makeNonNegativeIntegerBlock;
318using encoding::readNonNegativeInteger;
319using encoding::makeEmptyBlock;
320using encoding::makeStringBlock;
321using encoding::readString;
322using encoding::makeBinaryBlock;
323using encoding::makeNestedBlock;
324
325#ifdef NDN_CXX_ENABLE_DEPRECATED_BLOCK_HELPERS
326
327using encoding::nonNegativeIntegerBlock;
328using encoding::booleanBlock;
329using encoding::dataBlock;
330
331#endif // NDN_CXX_ENABLE_DEPRECATED_BLOCK_HELPERS
332
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800333} // namespace ndn
334
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700335#endif // NDN_ENCODING_BLOCK_HELPERS_HPP