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-2022 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  NDN_THROW(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
63  " must be empty"));
64  }
65  return EmptyValue{};
66  }
67 };
68 
69 template<typename TlvType>
70 struct DecodeHelper<TlvType, NonNegativeIntegerTag>
71 {
72  static uint64_t
73  decode(const Block& wire)
74  {
75  return readNonNegativeInteger(wire);
76  }
77 };
78 
79 template<typename TlvType>
80 struct DecodeHelper<TlvType, uint64_t>
81 {
82  static uint64_t
83  decode(const Block& wire)
84  {
85  if (wire.value_size() != sizeof(uint64_t)) {
86  NDN_THROW(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
87  " must contain a 64-bit integer"));
88  }
89  uint64_t n = 0;
90  std::memcpy(&n, wire.value(), sizeof(n));
91  return boost::endian::big_to_native(n);
92  }
93 };
94 
95 template<typename TlvType>
96 struct DecodeHelper<TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
97 {
98  static std::pair<Buffer::const_iterator, Buffer::const_iterator>
99  decode(const Block& wire)
100  {
101  if (wire.value_size() == 0) {
102  NDN_THROW(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
103  " cannot be empty"));
104  }
105  return {wire.value_begin(), wire.value_end()};
106  }
107 };
108 
109 template<typename encoding::Tag TAG, typename TlvType, typename T>
111 {
112  static
113  BOOST_CONCEPT_REQUIRES(((WireEncodableWithEncodingBuffer<T>)), (size_t))
114  encode(EncodingImpl<TAG>& encoder, const T& value)
115  {
116  return value.wireEncode(encoder);
117  }
118 };
119 
120 template<typename encoding::Tag TAG, typename TlvType>
121 struct EncodeHelper<TAG, TlvType, EmptyValue>
122 {
123  static size_t
125  {
126  return prependEmptyBlock(encoder, TlvType::value);
127  }
128 };
129 
130 template<typename encoding::Tag TAG, typename TlvType>
131 struct EncodeHelper<TAG, TlvType, NonNegativeIntegerTag>
132 {
133  static size_t
134  encode(EncodingImpl<TAG>& encoder, uint64_t value)
135  {
136  return prependNonNegativeIntegerBlock(encoder, TlvType::value, value);
137  }
138 };
139 
140 template<typename encoding::Tag TAG, typename TlvType>
141 struct EncodeHelper<TAG, TlvType, uint64_t>
142 {
143  static size_t
144  encode(EncodingImpl<TAG>& encoder, uint64_t value)
145  {
146  boost::endian::native_to_big_inplace(value);
147  return prependBinaryBlock(encoder, TlvType::value,
148  {reinterpret_cast<const uint8_t*>(&value), sizeof(value)});
149  }
150 };
151 
152 template<typename encoding::Tag TAG, typename TlvType>
153 struct EncodeHelper<TAG, TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
154 {
155  static size_t
156  encode(EncodingImpl<TAG>& encoder, const std::pair<Buffer::const_iterator, Buffer::const_iterator>& value)
157  {
158  size_t length = 0;
159  length += encoder.prependRange(value.first, value.second);
160  length += encoder.prependVarNumber(length);
161  length += encoder.prependVarNumber(TlvType::value);
162  return length;
163  }
164 };
165 
174 template<typename LOCATION, typename VALUE, uint64_t TYPE, bool REPEATABLE = false,
175  typename DECODER_TAG = VALUE, typename ENCODER_TAG = VALUE>
177 {
178 public:
179  typedef LOCATION FieldLocation;
180  typedef VALUE ValueType;
181  typedef std::integral_constant<uint64_t, TYPE> TlvType;
182  typedef std::integral_constant<bool, REPEATABLE> IsRepeatable;
183 
189  static ValueType
190  decode(const Block& wire)
191  {
192  if (wire.type() != TlvType::value) {
193  NDN_THROW(ndn::tlv::Error("Unexpected TLV-TYPE " + to_string(wire.type())));
194  }
195 
197  }
198 
203  template<typename encoding::Tag TAG>
204  static size_t
205  encode(EncodingImpl<TAG>& encoder, const ValueType& value)
206  {
208  }
209 };
210 
211 } // namespace lp
212 } // namespace ndn
213 
214 #endif // NDN_CXX_LP_FIELD_DECL_HPP
Represents a TLV element of the NDN packet format.
Definition: block.hpp:45
const_iterator value_end() const noexcept
Get end iterator of TLV-VALUE.
Definition: block.hpp:311
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
Definition: block.hpp:277
const_iterator value_begin() const noexcept
Get begin iterator of TLV-VALUE.
Definition: block.hpp:301
size_t value_size() const noexcept
Return the size of TLV-VALUE, i.e., the TLV-LENGTH.
Definition: block.hpp:321
const uint8_t * value() const noexcept
Return a raw pointer to the beginning of TLV-VALUE.
Definition: block.cpp:306
A concept check for TLV abstraction with a wireDecode(Block) method and constructible from Block.
Definition: concepts.hpp:81
A concept check for TLV abstraction with a wireEncode(EncodingBuffer) method.
Definition: concepts.hpp:61
Declare a field.
Definition: field-decl.hpp:177
std::integral_constant< uint64_t, TYPE > TlvType
Definition: field-decl.hpp:181
LOCATION FieldLocation
Definition: field-decl.hpp:179
static size_t encode(EncodingImpl< TAG > &encoder, const ValueType &value)
Encode a field and prepend to encoder.
Definition: field-decl.hpp:205
std::integral_constant< bool, REPEATABLE > IsRepeatable
Definition: field-decl.hpp:182
static ValueType decode(const Block &wire)
Decode a field.
Definition: field-decl.hpp:190
Represents an error in TLV encoding or decoding.
Definition: tlv.hpp:54
#define NDN_THROW(e)
Definition: exception.hpp:61
uint64_t readNonNegativeInteger(const Block &block)
Read a non-negative integer from a TLV element.
size_t prependNonNegativeIntegerBlock(EncodingImpl< TAG > &encoder, uint32_t type, uint64_t value)
Prepend a TLV element containing a non-negative integer.
size_t prependEmptyBlock(EncodingImpl< TAG > &encoder, uint32_t type)
Prepend an empty TLV element.
size_t prependBinaryBlock(EncodingImpl< TAG > &encoder, uint32_t type, span< const uint8_t > value)
Prepend a TLV element containing a sequence of raw bytes.
std::string to_string(const errinfo_stacktrace &x)
Definition: exception.cpp:31
Definition: data.cpp:25
static EmptyValue decode(const Block &wire)
Definition: field-decl.hpp:59
static std::pair< Buffer::const_iterator, Buffer::const_iterator > decode(const Block &wire)
Definition: field-decl.hpp:99
static uint64_t decode(const Block &wire)
Definition: field-decl.hpp:83
static T decode(const Block &wire)
Definition: field-decl.hpp:47
Represents a zero-length TLV-VALUE.
Definition: empty-value.hpp:34
static size_t encode(EncodingImpl< TAG > &encoder, EmptyValue)
Definition: field-decl.hpp:124
static size_t encode(EncodingImpl< TAG > &encoder, uint64_t value)
Definition: field-decl.hpp:134
static size_t encode(EncodingImpl< TAG > &encoder, const std::pair< Buffer::const_iterator, Buffer::const_iterator > &value)
Definition: field-decl.hpp:156
static size_t encode(EncodingImpl< TAG > &encoder, uint64_t value)
Definition: field-decl.hpp:144
static size_t encode(EncodingImpl< TAG > &encoder, const T &value)
Definition: field-decl.hpp:114