blob: f1e14ff58484caca44e75ed46f28230817d4e6bb [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi9da07c52017-08-06 16:59:30 +00002/*
3 * Copyright (c) 2013-2017 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
Junxiao Shi9da07c52017-08-06 16:59:30 +000034/** @brief Prepend a TLV element containing a non-negative integer
35 * @param encoder an EncodingBuffer or EncodingEstimator
36 * @param type TLV-TYPE number
37 * @param value non-negative integer value
38 * @sa makeNonNegativeIntegerBlock, readNonNegativeInteger
Alexander Afanasyev74633892015-02-08 18:08:46 -080039 */
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070040template<Tag TAG>
41size_t
42prependNonNegativeIntegerBlock(EncodingImpl<TAG>& encoder, uint32_t type, uint64_t value);
Alexander Afanasyev74633892015-02-08 18:08:46 -080043
Junxiao Shi9da07c52017-08-06 16:59:30 +000044extern template size_t
45prependNonNegativeIntegerBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, uint64_t);
46
47extern template size_t
48prependNonNegativeIntegerBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, uint64_t);
49
50/** @brief Create a TLV block containing a non-negative integer
51 * @param type TLV-TYPE number
52 * @param value non-negative integer value
53 * @sa prependNonNegativeIntegerBlock, readNonNegativeInteger
Alexander Afanasyev74633892015-02-08 18:08:46 -080054 */
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070055Block
56makeNonNegativeIntegerBlock(uint32_t type, uint64_t value);
Alexander Afanasyev74633892015-02-08 18:08:46 -080057
Junxiao Shi9da07c52017-08-06 16:59:30 +000058/** @brief Read a non-negative integer from a TLV element
59 * @param block the TLV element
60 * @throw tlv::Error block does not contain a non-negative integer
61 * @sa prependNonNegativeIntegerBlock, makeNonNegativeIntegerBlock
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070062 */
63uint64_t
64readNonNegativeInteger(const Block& block);
Alexander Afanasyev74633892015-02-08 18:08:46 -080065
Junxiao Shi9da07c52017-08-06 16:59:30 +000066/** @brief Prepend an empty TLV element
67 * @param encoder an EncodingBuffer or EncodingEstimator
68 * @param type TLV-TYPE number
69 * @details The TLV element has zero-length TLV-VALUE.
70 * @sa makeEmptyBlock
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070071 */
72template<Tag TAG>
73size_t
74prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type);
Alexander Afanasyev74633892015-02-08 18:08:46 -080075
Junxiao Shi9da07c52017-08-06 16:59:30 +000076extern template size_t
77prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
78
79extern template size_t
80prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
81
82/** @brief Create an empty TLV block
83 * @param type TLV-TYPE number
84 * @return A TLV block with zero-length TLV-VALUE
85 * @sa prependEmptyBlock
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070086 */
87Block
88makeEmptyBlock(uint32_t type);
Alexander Afanasyev74633892015-02-08 18:08:46 -080089
Junxiao Shi9da07c52017-08-06 16:59:30 +000090/** @brief Prepend a TLV element containing a string.
91 * @param encoder an EncodingBuffer or EncodingEstimator
92 * @param type TLV-TYPE number
93 * @param value string value, may contain NUL octets
94 * @sa makeStringBlock, readString
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070095 */
96template<Tag TAG>
97size_t
98prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value);
Alexander Afanasyev74633892015-02-08 18:08:46 -080099
Junxiao Shi9da07c52017-08-06 16:59:30 +0000100extern template size_t
101prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, const std::string&);
102
103extern template size_t
104prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, const std::string&);
105
106/** @brief Create a TLV block containing a string.
107 * @param type TLV-TYPE number
108 * @param value string value, may contain NUL octets
109 * @sa prependStringBlock, readString
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700110 */
111Block
112makeStringBlock(uint32_t type, const std::string& value);
Alexander Afanasyev74633892015-02-08 18:08:46 -0800113
Junxiao Shi9da07c52017-08-06 16:59:30 +0000114/** @brief Read TLV-VALUE of a TLV element as a string.
115 * @param block the TLV element
116 * @return a string, may contain NUL octets
117 * @sa prependStringBlock, makeStringBlock
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700118 */
119std::string
120readString(const Block& block);
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700121
Junxiao Shi9da07c52017-08-06 16:59:30 +0000122/** @brief Create a TLV block copying TLV-VALUE from raw buffer.
123 * @param type TLV-TYPE number
124 * @param value raw buffer as TLV-VALUE
125 * @param length length of value buffer
126 * @sa Encoder::prependByteArrayBlock
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700127 */
128Block
129makeBinaryBlock(uint32_t type, const uint8_t* value, size_t length);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800130
Junxiao Shi9da07c52017-08-06 16:59:30 +0000131/** @brief Create a TLV block copying TLV-VALUE from raw buffer.
132 * @param type TLV-TYPE number
133 * @param value raw buffer as TLV-VALUE
134 * @param length length of value buffer
135 * @sa Encoder::prependByteArrayBlock
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700136 */
137Block
138makeBinaryBlock(uint32_t type, const char* value, size_t length);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800139
Junxiao Shi9da07c52017-08-06 16:59:30 +0000140namespace detail {
141
142/** @brief Create a binary block copying from RandomAccessIterator
Alexander Afanasyev74633892015-02-08 18:08:46 -0800143 */
144template<class Iterator>
Junxiao Shi9da07c52017-08-06 16:59:30 +0000145class BinaryBlockFast
Alexander Afanasyev74633892015-02-08 18:08:46 -0800146{
147public:
148 BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<Iterator>));
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800149
Alexander Afanasyev74633892015-02-08 18:08:46 -0800150 static Block
151 makeBlock(uint32_t type, Iterator first, Iterator last)
152 {
153 EncodingEstimator estimator;
154 size_t valueLength = last - first;
155 size_t totalLength = valueLength;
156 totalLength += estimator.prependVarNumber(valueLength);
157 totalLength += estimator.prependVarNumber(type);
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700158
Alexander Afanasyev74633892015-02-08 18:08:46 -0800159 EncodingBuffer encoder(totalLength, 0);
160 encoder.prependRange(first, last);
161 encoder.prependVarNumber(valueLength);
162 encoder.prependVarNumber(type);
163
164 return encoder.block();
165 }
166};
167
Junxiao Shi9da07c52017-08-06 16:59:30 +0000168/** @brief Create a binary block copying from generic InputIterator
Alexander Afanasyev74633892015-02-08 18:08:46 -0800169 */
170template<class Iterator>
Junxiao Shi9da07c52017-08-06 16:59:30 +0000171class BinaryBlockSlow
Alexander Afanasyev74633892015-02-08 18:08:46 -0800172{
173public:
174 BOOST_CONCEPT_ASSERT((boost::InputIterator<Iterator>));
175
176 static Block
177 makeBlock(uint32_t type, Iterator first, Iterator last)
178 {
179 // reserve 4 bytes in front (common for 1(type)-3(length) encoding
180 // Actual size will be adjusted as necessary by the encoder
181 EncodingBuffer encoder(4, 4);
182 size_t valueLength = encoder.appendRange(first, last);
183 encoder.prependVarNumber(valueLength);
184 encoder.prependVarNumber(type);
185
186 return encoder.block();
187 }
188};
189
Junxiao Shi9da07c52017-08-06 16:59:30 +0000190} // namespace detail
191
192/** @brief Create a TLV block copying TLV-VALUE from iterators.
193 * @tparam Iterator an InputIterator dereferencable to an 1-octet type; faster implementation is
194 * available for RandomAccessIterator
195 * @param type TLV-TYPE number
196 * @param first begin iterator
197 * @param last past-the-end iterator
Alexander Afanasyev74633892015-02-08 18:08:46 -0800198 */
199template<class Iterator>
Junxiao Shi9da07c52017-08-06 16:59:30 +0000200Block
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700201makeBinaryBlock(uint32_t type, Iterator first, Iterator last)
Alexander Afanasyev74633892015-02-08 18:08:46 -0800202{
Junxiao Shi9da07c52017-08-06 16:59:30 +0000203 static_assert(sizeof(typename std::iterator_traits<Iterator>::value_type) == 1, "");
Alexander Afanasyev74633892015-02-08 18:08:46 -0800204
Junxiao Shi9da07c52017-08-06 16:59:30 +0000205 using BinaryBlockHelper = typename std::conditional<
Alexander Afanasyev74633892015-02-08 18:08:46 -0800206 std::is_base_of<std::random_access_iterator_tag,
Junxiao Shi9da07c52017-08-06 16:59:30 +0000207 typename std::iterator_traits<Iterator>::iterator_category>::value,
208 detail::BinaryBlockFast<Iterator>,
209 detail::BinaryBlockSlow<Iterator>>::type;
Alexander Afanasyev74633892015-02-08 18:08:46 -0800210
Junxiao Shi9da07c52017-08-06 16:59:30 +0000211 return BinaryBlockHelper::makeBlock(type, first, last);
Alexander Afanasyev74633892015-02-08 18:08:46 -0800212}
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700213
Junxiao Shi9da07c52017-08-06 16:59:30 +0000214/** @brief Prepend a TLV element containing a nested TLV element.
215 * @tparam U type that satisfies WireEncodableWithEncodingBuffer concept
216 * @param encoder an EncodingBuffer or EncodingEstimator
217 * @param type TLV-TYPE number for outer TLV element
218 * @param value an object to be encoded as inner TLV element
219 * @sa makeNestedBlock
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700220 */
221template<Tag TAG, class U>
Junxiao Shi9da07c52017-08-06 16:59:30 +0000222size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700223prependNestedBlock(EncodingImpl<TAG>& encoder, uint32_t type, const U& value)
224{
225 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<U>));
226
227 size_t valueLength = value.wireEncode(encoder);
228 size_t totalLength = valueLength;
229 totalLength += encoder.prependVarNumber(valueLength);
230 totalLength += encoder.prependVarNumber(type);
231
232 return totalLength;
233}
234
Junxiao Shi9da07c52017-08-06 16:59:30 +0000235/** @brief Create a TLV block containing a nested TLV element.
236 * @tparam U type that satisfies WireEncodableWithEncodingBuffer concept
237 * @param type TLV-TYPE number for outer TLV element
238 * @param value an object to be encoded as inner TLV element
239 * @sa prependNestedBlock
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700240 */
241template<class U>
Junxiao Shi9da07c52017-08-06 16:59:30 +0000242Block
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700243makeNestedBlock(uint32_t type, const U& value)
244{
245 EncodingEstimator estimator;
246 size_t totalLength = prependNestedBlock(estimator, type, value);
247
248 EncodingBuffer encoder(totalLength, 0);
249 prependNestedBlock(encoder, type, value);
250
251 return encoder.block();
252}
253
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700254} // namespace encoding
255
256using encoding::makeNonNegativeIntegerBlock;
257using encoding::readNonNegativeInteger;
258using encoding::makeEmptyBlock;
259using encoding::makeStringBlock;
260using encoding::readString;
261using encoding::makeBinaryBlock;
262using encoding::makeNestedBlock;
263
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800264} // namespace ndn
265
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700266#endif // NDN_ENCODING_BLOCK_HELPERS_HPP