block-helpers.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2019 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * 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.
20  */
21 
22 #ifndef NDN_ENCODING_BLOCK_HELPERS_HPP
23 #define NDN_ENCODING_BLOCK_HELPERS_HPP
24 
28 
29 namespace ndn {
30 namespace encoding {
31 
38 template<Tag TAG>
39 size_t
40 prependNonNegativeIntegerBlock(EncodingImpl<TAG>& encoder, uint32_t type, uint64_t value);
41 
42 extern template size_t
43 prependNonNegativeIntegerBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, uint64_t);
44 
45 extern template size_t
46 prependNonNegativeIntegerBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, uint64_t);
47 
53 Block
54 makeNonNegativeIntegerBlock(uint32_t type, uint64_t value);
55 
61 uint64_t
62 readNonNegativeInteger(const Block& block);
63 
70 template<typename R>
71 std::enable_if_t<std::is_integral<R>::value, R>
73 {
74  uint64_t value = readNonNegativeInteger(block);
75  if (value > std::numeric_limits<R>::max()) {
76  NDN_THROW(tlv::Error("Value in TLV element of type " + to_string(block.type()) + " is too large"));
77  }
78  return static_cast<R>(value);
79 }
80 
89 template<typename R>
90 std::enable_if_t<std::is_enum<R>::value, R>
92 {
93  return static_cast<R>(readNonNegativeIntegerAs<std::underlying_type_t<R>>(block));
94 }
95 
102 template<Tag TAG>
103 size_t
104 prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type);
105 
106 extern template size_t
107 prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
108 
109 extern template size_t
110 prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
111 
117 Block
118 makeEmptyBlock(uint32_t type);
119 
126 template<Tag TAG>
127 size_t
128 prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value);
129 
130 extern template size_t
131 prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, const std::string&);
132 
133 extern template size_t
134 prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, const std::string&);
135 
141 Block
142 makeStringBlock(uint32_t type, const std::string& value);
143 
149 std::string
150 readString(const Block& block);
151 
158 template<Tag TAG>
159 size_t
160 prependDoubleBlock(EncodingImpl<TAG>& encoder, uint32_t type, double value);
161 
162 extern template size_t
163 prependDoubleBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, double);
164 
165 extern template size_t
166 prependDoubleBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, double);
167 
173 Block
174 makeDoubleBlock(uint32_t type, double value);
175 
181 double
182 readDouble(const Block& block);
183 
190 Block
191 makeBinaryBlock(uint32_t type, const uint8_t* value, size_t length);
192 
199 Block
200 makeBinaryBlock(uint32_t type, const char* value, size_t length);
201 
202 namespace detail {
203 
206 template<class Iterator>
208 {
209 public:
210  BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<Iterator>));
211 
212  static Block
213  makeBlock(uint32_t type, Iterator first, Iterator last)
214  {
215  EncodingEstimator estimator;
216  size_t valueLength = last - first;
217  size_t totalLength = valueLength;
218  totalLength += estimator.prependVarNumber(valueLength);
219  totalLength += estimator.prependVarNumber(type);
220 
221  EncodingBuffer encoder(totalLength, 0);
222  encoder.prependRange(first, last);
223  encoder.prependVarNumber(valueLength);
224  encoder.prependVarNumber(type);
225 
226  return encoder.block();
227  }
228 };
229 
232 template<class Iterator>
234 {
235 public:
236  BOOST_CONCEPT_ASSERT((boost::InputIterator<Iterator>));
237 
238  static Block
239  makeBlock(uint32_t type, Iterator first, Iterator last)
240  {
241  // reserve 4 bytes in front (common for 1(type)-3(length) encoding
242  // Actual size will be adjusted as necessary by the encoder
243  EncodingBuffer encoder(4, 4);
244  size_t valueLength = encoder.appendRange(first, last);
245  encoder.prependVarNumber(valueLength);
246  encoder.prependVarNumber(type);
247 
248  return encoder.block();
249  }
250 };
251 
252 } // namespace detail
253 
261 template<class Iterator>
262 Block
263 makeBinaryBlock(uint32_t type, Iterator first, Iterator last)
264 {
265  using BinaryBlockHelper = std::conditional_t<
266  std::is_base_of<std::random_access_iterator_tag,
267  typename std::iterator_traits<Iterator>::iterator_category>::value,
270 
271  return BinaryBlockHelper::makeBlock(type, first, last);
272 }
273 
281 template<Tag TAG, class U>
282 size_t
283 prependNestedBlock(EncodingImpl<TAG>& encoder, uint32_t type, const U& value)
284 {
285  BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<U>));
286 
287  size_t valueLength = value.wireEncode(encoder);
288  size_t totalLength = valueLength;
289  totalLength += encoder.prependVarNumber(valueLength);
290  totalLength += encoder.prependVarNumber(type);
291 
292  return totalLength;
293 }
294 
301 template<class U>
302 Block
303 makeNestedBlock(uint32_t type, const U& value)
304 {
305  EncodingEstimator estimator;
306  size_t totalLength = prependNestedBlock(estimator, type, value);
307 
308  EncodingBuffer encoder(totalLength, 0);
309  prependNestedBlock(encoder, type, value);
310 
311  return encoder.block();
312 }
313 
314 } // namespace encoding
315 
324 
325 } // namespace ndn
326 
327 #endif // NDN_ENCODING_BLOCK_HELPERS_HPP
Definition: data.cpp:26
size_t appendRange(Iterator first, Iterator last)
Append range of bytes from the range [first, last)
Definition: encoder.hpp:327
EncodingImpl specialization for actual TLV encoding.
size_t prependNonNegativeIntegerBlock(EncodingImpl< TAG > &encoder, uint32_t type, uint64_t value)
Prepend a TLV element containing a non-negative integer.
std::string to_string(const T &val)
Definition: backports.hpp:101
static Block makeBlock(uint32_t type, Iterator first, Iterator last)
Block makeEmptyBlock(uint32_t type)
Create an empty TLV block.
std::enable_if_t< std::is_integral< R >::value, R > readNonNegativeIntegerAs(const Block &block)
Read a non-negative integer from a TLV element and cast to the specified type.
Block makeDoubleBlock(uint32_t type, double value)
Create a TLV element containing an IEEE 754 double-precision floating-point number.
template size_t prependEmptyBlock< EstimatorTag >(EncodingImpl< EstimatorTag > &, uint32_t)
template size_t prependNonNegativeIntegerBlock< EstimatorTag >(EncodingImpl< EstimatorTag > &, uint32_t, uint64_t)
template size_t prependNonNegativeIntegerBlock< EncoderTag >(EncodingImpl< EncoderTag > &, uint32_t, uint64_t)
Block makeNestedBlock(uint32_t type, const U &value)
Create a TLV block containing a nested TLV element.
size_t prependNestedBlock(EncodingImpl< TAG > &encoder, uint32_t type, const U &value)
Prepend a TLV element containing a nested TLV element.
Represents a TLV element of the NDN packet format.
Definition: block.hpp:42
size_t prependStringBlock(EncodingImpl< TAG > &encoder, uint32_t type, const std::string &value)
Prepend a TLV element containing a string.
std::string readString(const Block &block)
Read TLV-VALUE of a TLV element as a string.
Block makeNonNegativeIntegerBlock(uint32_t type, uint64_t value)
Create a TLV block containing a non-negative integer.
uint64_t readNonNegativeInteger(const Block &block)
Read a non-negative integer from a TLV element.
EncodingImpl specialization for TLV size estimation.
#define NDN_THROW(e)
Definition: exception.hpp:61
Create a binary block copying from generic InputIterator.
template size_t prependEmptyBlock< EncoderTag >(EncodingImpl< EncoderTag > &, uint32_t)
size_t prependVarNumber(uint64_t varNumber) const noexcept
Prepend VarNumber varNumber of NDN TLV encoding.
Definition: estimator.cpp:28
size_t prependVarNumber(uint64_t varNumber)
Prepend VarNumber varNumber of NDN TLV encoding.
Definition: encoder.cpp:138
a concept check for TLV abstraction with .wireEncode method
Definition: concepts.hpp:60
template size_t prependStringBlock< EncoderTag >(EncodingImpl< EncoderTag > &, uint32_t, const std::string &)
Block block(bool verifyLength=true) const
Create Block from the underlying buffer.
Definition: encoder.cpp:59
size_t prependEmptyBlock(EncodingImpl< TAG > &encoder, uint32_t type)
Prepend an empty TLV element.
Block makeBinaryBlock(uint32_t type, const uint8_t *value, size_t length)
Create a TLV block copying TLV-VALUE from raw buffer.
Block makeStringBlock(uint32_t type, const std::string &value)
Create a TLV block containing a string.
size_t prependRange(Iterator first, Iterator last)
Prepend range of bytes from the range [first, last)
Definition: encoder.hpp:312
double readDouble(const Block &block)
Read TLV-VALUE of a TLV element as an IEEE 754 double-precision floating-point number.
template size_t prependStringBlock< EstimatorTag >(EncodingImpl< EstimatorTag > &, uint32_t, const std::string &)
template size_t prependDoubleBlock< EncoderTag >(EncodingImpl< EncoderTag > &, uint32_t, double)
template size_t prependDoubleBlock< EstimatorTag >(EncodingImpl< EstimatorTag > &, uint32_t, double)
size_t prependDoubleBlock(EncodingImpl< TAG > &encoder, uint32_t type, double value)
Prepend a TLV element containing an IEEE 754 double-precision floating-point number.
static Block makeBlock(uint32_t type, Iterator first, Iterator last)
uint32_t type() const
Return the TLV-TYPE of the Block.
Definition: block.hpp:261
represents an error in TLV encoding or decoding
Definition: tlv.hpp:51
Create a binary block copying from RandomAccessIterator.