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-2017 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 
25 #include "block.hpp"
26 #include "encoding-buffer.hpp"
27 #include "../util/concepts.hpp"
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 typename std::enable_if<std::is_integral<R>::value, R>::type
73 {
74  uint64_t value = readNonNegativeInteger(block);
75  if (value > std::numeric_limits<R>::max()) {
76  BOOST_THROW_EXCEPTION(tlv::Error("Value in TLV element of type " + to_string(block.type()) +
77  " is too large"));
78  }
79  return static_cast<R>(value);
80 }
81 
90 template<typename R>
91 typename std::enable_if<std::is_enum<R>::value, R>::type
93 {
94  return static_cast<R>(readNonNegativeIntegerAs<typename std::underlying_type<R>::type>(block));
95 }
96 
103 template<Tag TAG>
104 size_t
105 prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type);
106 
107 extern template size_t
108 prependEmptyBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t);
109 
110 extern template size_t
111 prependEmptyBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t);
112 
118 Block
119 makeEmptyBlock(uint32_t type);
120 
127 template<Tag TAG>
128 size_t
129 prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value);
130 
131 extern template size_t
132 prependStringBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, const std::string&);
133 
134 extern template size_t
135 prependStringBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, const std::string&);
136 
142 Block
143 makeStringBlock(uint32_t type, const std::string& value);
144 
150 std::string
151 readString(const Block& block);
152 
159 Block
160 makeBinaryBlock(uint32_t type, const uint8_t* value, size_t length);
161 
168 Block
169 makeBinaryBlock(uint32_t type, const char* value, size_t length);
170 
171 namespace detail {
172 
175 template<class Iterator>
177 {
178 public:
179  BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<Iterator>));
180 
181  static Block
182  makeBlock(uint32_t type, Iterator first, Iterator last)
183  {
184  EncodingEstimator estimator;
185  size_t valueLength = last - first;
186  size_t totalLength = valueLength;
187  totalLength += estimator.prependVarNumber(valueLength);
188  totalLength += estimator.prependVarNumber(type);
189 
190  EncodingBuffer encoder(totalLength, 0);
191  encoder.prependRange(first, last);
192  encoder.prependVarNumber(valueLength);
193  encoder.prependVarNumber(type);
194 
195  return encoder.block();
196  }
197 };
198 
201 template<class Iterator>
203 {
204 public:
205  BOOST_CONCEPT_ASSERT((boost::InputIterator<Iterator>));
206 
207  static Block
208  makeBlock(uint32_t type, Iterator first, Iterator last)
209  {
210  // reserve 4 bytes in front (common for 1(type)-3(length) encoding
211  // Actual size will be adjusted as necessary by the encoder
212  EncodingBuffer encoder(4, 4);
213  size_t valueLength = encoder.appendRange(first, last);
214  encoder.prependVarNumber(valueLength);
215  encoder.prependVarNumber(type);
216 
217  return encoder.block();
218  }
219 };
220 
221 } // namespace detail
222 
230 template<class Iterator>
231 Block
232 makeBinaryBlock(uint32_t type, Iterator first, Iterator last)
233 {
234  using BinaryBlockHelper = typename std::conditional<
235  std::is_base_of<std::random_access_iterator_tag,
236  typename std::iterator_traits<Iterator>::iterator_category>::value,
239 
240  return BinaryBlockHelper::makeBlock(type, first, last);
241 }
242 
250 template<Tag TAG, class U>
251 size_t
252 prependNestedBlock(EncodingImpl<TAG>& encoder, uint32_t type, const U& value)
253 {
255 
256  size_t valueLength = value.wireEncode(encoder);
257  size_t totalLength = valueLength;
258  totalLength += encoder.prependVarNumber(valueLength);
259  totalLength += encoder.prependVarNumber(type);
260 
261  return totalLength;
262 }
263 
270 template<class U>
271 Block
272 makeNestedBlock(uint32_t type, const U& value)
273 {
274  EncodingEstimator estimator;
275  size_t totalLength = prependNestedBlock(estimator, type, value);
276 
277  EncodingBuffer encoder(totalLength, 0);
278  prependNestedBlock(encoder, type, value);
279 
280  return encoder.block();
281 }
282 
283 } // namespace encoding
284 
293 
294 } // namespace ndn
295 
296 #endif // NDN_ENCODING_BLOCK_HELPERS_HPP
Copyright (c) 2013-2017 Regents of the University of California.
Definition: common.hpp:66
size_t appendRange(Iterator first, Iterator last)
Append range of bytes from the range [first, last)
Definition: encoder.hpp:332
BOOST_CONCEPT_ASSERT((boost::EqualityComparable< Data >))
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.
static Block makeBlock(uint32_t type, Iterator first, Iterator last)
Block makeEmptyBlock(uint32_t type)
Create an empty TLV block.
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 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.
Create a binary block copying from generic InputIterator.
template size_t prependEmptyBlock< EncoderTag >(EncodingImpl< EncoderTag > &, uint32_t)
std::enable_if< std::is_integral< R >::value, R >::type readNonNegativeIntegerAs(const Block &block)
Read a non-negative integer from a TLV element and cast to the specified type.
size_t prependVarNumber(uint64_t varNumber)
Prepend VarNumber varNumber of NDN TLV encoding.
Definition: encoder.cpp:146
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 &)
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.
size_t prependVarNumber(uint64_t varNumber)
Prepend VarNumber varNumber of NDN TLV encoding.
Definition: estimator.cpp:57
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:316
Block block(bool verifyLength=true) const
Create Block from the underlying buffer.
Definition: encoder.cpp:60
template size_t prependStringBlock< EstimatorTag >(EncodingImpl< EstimatorTag > &, uint32_t, const std::string &)
uint32_t type() const
Get TLV-TYPE.
Definition: block.hpp:235
std::string to_string(const V &v)
Definition: backports.hpp:84
static Block makeBlock(uint32_t type, Iterator first, Iterator last)
represents an error in TLV encoding or decoding
Create a binary block copying from RandomAccessIterator.