field-decl.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_CXX_LP_FIELD_DECL_HPP
23 #define NDN_CXX_LP_FIELD_DECL_HPP
24 
26 #include "ndn-cxx/lp/field.hpp"
27 #include "ndn-cxx/lp/sequence.hpp"
28 #include "ndn-cxx/lp/tlv.hpp"
31 
32 #include <boost/concept/requires.hpp>
33 #include <boost/endian/conversion.hpp>
34 
35 namespace ndn {
36 namespace lp {
37 
40 struct NonNegativeIntegerTag;
41 
42 template<typename TlvType, typename T>
44 {
45  static
46  BOOST_CONCEPT_REQUIRES(((WireDecodable<T>)), (T))
47  decode(const Block& wire)
48  {
49  T type;
50  type.wireDecode(wire);
51  return type;
52  }
53 };
54 
55 template<typename TlvType>
56 struct DecodeHelper<TlvType, EmptyValue>
57 {
58  static EmptyValue
59  decode(const Block& wire)
60  {
61  if (wire.value_size() != 0) {
62  BOOST_THROW_EXCEPTION(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
63  " must be empty"));
64  }
65 
66  return EmptyValue{};
67  }
68 };
69 
70 template<typename TlvType>
71 struct DecodeHelper<TlvType, NonNegativeIntegerTag>
72 {
73  static uint64_t
74  decode(const Block& wire)
75  {
76  return readNonNegativeInteger(wire);
77  }
78 };
79 
80 template<typename TlvType>
81 struct DecodeHelper<TlvType, uint64_t>
82 {
83  static uint64_t
84  decode(const Block& wire)
85  {
86  if (wire.value_size() != sizeof(uint64_t)) {
87  BOOST_THROW_EXCEPTION(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
88  " should contain a 64-bit integer"));
89  }
90  uint64_t n = 0;
91  std::memcpy(&n, wire.value(), sizeof(n));
92  return boost::endian::big_to_native(n);
93  }
94 };
95 
96 template<typename TlvType>
97 struct DecodeHelper<TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
98 {
99  static std::pair<Buffer::const_iterator, Buffer::const_iterator>
100  decode(const Block& wire)
101  {
102  if (wire.value_size() == 0) {
103  BOOST_THROW_EXCEPTION(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
104  " cannot be empty"));
105  }
106 
107  return std::make_pair(wire.value_begin(), wire.value_end());
108  }
109 };
110 
111 template<typename encoding::Tag TAG, typename TlvType, typename T>
113 {
114  static
115  BOOST_CONCEPT_REQUIRES(((WireEncodableWithEncodingBuffer<T>)), (size_t))
116  encode(EncodingImpl<TAG>& encoder, const T& value)
117  {
118  return value.wireEncode(encoder);
119  }
120 };
121 
122 template<typename encoding::Tag TAG, typename TlvType>
123 struct EncodeHelper<TAG, TlvType, EmptyValue>
124 {
125  static size_t
126  encode(EncodingImpl<TAG>& encoder, const EmptyValue value)
127  {
128  size_t length = 0;
129  length += encoder.prependVarNumber(0);
130  length += encoder.prependVarNumber(TlvType::value);
131  return length;
132  }
133 };
134 
135 template<typename encoding::Tag TAG, typename TlvType>
136 struct EncodeHelper<TAG, TlvType, NonNegativeIntegerTag>
137 {
138  static size_t
139  encode(EncodingImpl<TAG>& encoder, uint64_t value)
140  {
141  return prependNonNegativeIntegerBlock(encoder, TlvType::value, value);
142  }
143 };
144 
145 template<typename encoding::Tag TAG, typename TlvType>
146 struct EncodeHelper<TAG, TlvType, uint64_t>
147 {
148  static size_t
149  encode(EncodingImpl<TAG>& encoder, uint64_t value)
150  {
151  boost::endian::native_to_big_inplace(value);
152  return encoder.prependByteArrayBlock(TlvType::value,
153  reinterpret_cast<const uint8_t*>(&value), sizeof(value));
154  }
155 };
156 
157 template<typename encoding::Tag TAG, typename TlvType>
158 struct EncodeHelper<TAG, TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
159 {
160  static size_t
161  encode(EncodingImpl<TAG>& encoder, const std::pair<Buffer::const_iterator, Buffer::const_iterator>& value)
162  {
163  size_t length = 0;
164  length += encoder.prependRange(value.first, value.second);
165  length += encoder.prependVarNumber(length);
166  length += encoder.prependVarNumber(TlvType::value);
167  return length;
168  }
169 };
170 
179 template<typename LOCATION, typename VALUE, uint64_t TYPE, bool REPEATABLE = false,
180  typename DECODER_TAG = VALUE, typename ENCODER_TAG = VALUE>
182 {
183 public:
184  typedef LOCATION FieldLocation;
185  typedef VALUE ValueType;
186  typedef std::integral_constant<uint64_t, TYPE> TlvType;
187  typedef std::integral_constant<bool, REPEATABLE> IsRepeatable;
188 
194  static ValueType
195  decode(const Block& wire)
196  {
197  if (wire.type() != TlvType::value) {
198  BOOST_THROW_EXCEPTION(ndn::tlv::Error("Unexpected TLV-TYPE " + to_string(wire.type())));
199  }
200 
202  }
203 
208  template<typename encoding::Tag TAG>
209  static size_t
210  encode(EncodingImpl<TAG>& encoder, const ValueType& value)
211  {
213  }
214 };
215 
216 } // namespace lp
217 } // namespace ndn
218 
219 #endif // NDN_CXX_LP_FIELD_DECL_HPP
static ValueType decode(const Block &wire)
Decode a field.
Definition: field-decl.hpp:195
Definition: data.cpp:26
static T decode(const Block &wire)
Definition: field-decl.hpp:47
LOCATION FieldLocation
Definition: field-decl.hpp:184
size_t prependNonNegativeIntegerBlock(EncodingImpl< TAG > &encoder, uint32_t type, uint64_t value)
Prepend a TLV element containing a non-negative integer.
std::integral_constant< bool, REPEATABLE > IsRepeatable
Definition: field-decl.hpp:187
static size_t encode(EncodingImpl< TAG > &encoder, uint64_t value)
Definition: field-decl.hpp:139
STL namespace.
Represents a TLV element of NDN packet format.
Definition: block.hpp:42
static size_t encode(EncodingImpl< TAG > &encoder, const EmptyValue value)
Definition: field-decl.hpp:126
Buffer::const_iterator value_begin() const
Get begin iterator of TLV-VALUE.
Definition: block.hpp:269
Buffer::const_iterator value_end() const
Get end iterator of TLV-VALUE.
Definition: block.hpp:278
uint64_t readNonNegativeInteger(const Block &block)
Read a non-negative integer from a TLV element.
static size_t encode(EncodingImpl< TAG > &encoder, const T &value)
Definition: field-decl.hpp:116
Declare a field.
Definition: field-decl.hpp:181
a concept check for TLV abstraction with .wireEncode method
Definition: concepts.hpp:60
static size_t encode(EncodingImpl< TAG > &encoder, uint64_t value)
Definition: field-decl.hpp:149
size_t value_size() const
Get size of TLV-VALUE aka TLV-LENGTH.
Definition: block.cpp:316
uint32_t type() const
Get TLV-TYPE.
Definition: block.hpp:249
represents a zero-length TLV-VALUE
Definition: empty-value.hpp:33
static size_t encode(EncodingImpl< TAG > &encoder, const ValueType &value)
Encode a field and prepend to encoder.
Definition: field-decl.hpp:210
static size_t encode(EncodingImpl< TAG > &encoder, const std::pair< Buffer::const_iterator, Buffer::const_iterator > &value)
Definition: field-decl.hpp:161
static std::pair< Buffer::const_iterator, Buffer::const_iterator > decode(const Block &wire)
Definition: field-decl.hpp:100
static uint64_t decode(const Block &wire)
Definition: field-decl.hpp:84
const uint8_t * value() const
Get pointer to TLV-VALUE.
Definition: block.cpp:310
std::string to_string(const V &v)
Definition: backports.hpp:67
a concept check for TLV abstraction with .wireDecode method and constructible from Block ...
Definition: concepts.hpp:80
std::integral_constant< uint64_t, TYPE > TlvType
Definition: field-decl.hpp:186
represents an error in TLV encoding or decoding
Definition: tlv.hpp:52
static EmptyValue decode(const Block &wire)
Definition: field-decl.hpp:59