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-2023 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 
28 
29 #include <boost/concept/requires.hpp>
30 #include <boost/endian/conversion.hpp>
31 
32 namespace ndn::lp {
33 
37 struct NonNegativeIntegerTag;
38 
39 template<typename TlvType, typename T>
41 {
42  static
43  BOOST_CONCEPT_REQUIRES(((WireDecodable<T>)), (T))
44  decode(const Block& wire)
45  {
46  T type;
47  type.wireDecode(wire);
48  return type;
49  }
50 };
51 
52 template<typename TlvType>
53 struct DecodeHelper<TlvType, EmptyValue>
54 {
55  static EmptyValue
56  decode(const Block& wire)
57  {
58  if (wire.value_size() != 0) {
59  NDN_THROW(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
60  " must be empty"));
61  }
62  return EmptyValue{};
63  }
64 };
65 
66 template<typename TlvType>
67 struct DecodeHelper<TlvType, NonNegativeIntegerTag>
68 {
69  static uint64_t
70  decode(const Block& wire)
71  {
72  return readNonNegativeInteger(wire);
73  }
74 };
75 
76 template<typename TlvType>
77 struct DecodeHelper<TlvType, uint64_t>
78 {
79  static uint64_t
80  decode(const Block& wire)
81  {
82  if (wire.value_size() != sizeof(uint64_t)) {
83  NDN_THROW(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
84  " must contain a 64-bit integer"));
85  }
86  uint64_t n = 0;
87  std::memcpy(&n, wire.value(), sizeof(n));
88  return boost::endian::big_to_native(n);
89  }
90 };
91 
92 template<typename TlvType>
93 struct DecodeHelper<TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
94 {
95  static std::pair<Buffer::const_iterator, Buffer::const_iterator>
96  decode(const Block& wire)
97  {
98  if (wire.value_size() == 0) {
99  NDN_THROW(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
100  " cannot be empty"));
101  }
102  return {wire.value_begin(), wire.value_end()};
103  }
104 };
105 
106 template<typename encoding::Tag TAG, typename TlvType, typename T>
108 {
109  static
110  BOOST_CONCEPT_REQUIRES(((WireEncodableWithEncodingBuffer<T>)), (size_t))
111  encode(EncodingImpl<TAG>& encoder, const T& value)
112  {
113  return value.wireEncode(encoder);
114  }
115 };
116 
117 template<typename encoding::Tag TAG, typename TlvType>
118 struct EncodeHelper<TAG, TlvType, EmptyValue>
119 {
120  static size_t
122  {
123  return prependEmptyBlock(encoder, TlvType::value);
124  }
125 };
126 
127 template<typename encoding::Tag TAG, typename TlvType>
128 struct EncodeHelper<TAG, TlvType, NonNegativeIntegerTag>
129 {
130  static size_t
131  encode(EncodingImpl<TAG>& encoder, uint64_t value)
132  {
133  return prependNonNegativeIntegerBlock(encoder, TlvType::value, value);
134  }
135 };
136 
137 template<typename encoding::Tag TAG, typename TlvType>
138 struct EncodeHelper<TAG, TlvType, uint64_t>
139 {
140  static size_t
141  encode(EncodingImpl<TAG>& encoder, uint64_t value)
142  {
143  boost::endian::native_to_big_inplace(value);
144  return prependBinaryBlock(encoder, TlvType::value,
145  {reinterpret_cast<const uint8_t*>(&value), sizeof(value)});
146  }
147 };
148 
149 template<typename encoding::Tag TAG, typename TlvType>
150 struct EncodeHelper<TAG, TlvType, std::pair<Buffer::const_iterator, Buffer::const_iterator>>
151 {
152  static size_t
153  encode(EncodingImpl<TAG>& encoder, const std::pair<Buffer::const_iterator, Buffer::const_iterator>& value)
154  {
155  size_t length = 0;
156  length += encoder.prependRange(value.first, value.second);
157  length += encoder.prependVarNumber(length);
158  length += encoder.prependVarNumber(TlvType::value);
159  return length;
160  }
161 };
162 
171 template<typename LOCATION, typename VALUE, uint32_t TYPE, bool REPEATABLE = false,
172  typename DECODER_TAG = VALUE, typename ENCODER_TAG = VALUE>
174 {
175 public:
176  using FieldLocation = LOCATION;
177  using ValueType = VALUE;
178  using TlvType = std::integral_constant<uint32_t, TYPE>;
179  using IsRepeatable = std::bool_constant<REPEATABLE>;
180 
186  static ValueType
187  decode(const Block& wire)
188  {
189  if (wire.type() != TlvType::value) {
190  NDN_THROW(ndn::tlv::Error("Unexpected TLV-TYPE " + to_string(wire.type())));
191  }
192 
194  }
195 
200  template<typename encoding::Tag TAG>
201  static size_t
202  encode(EncodingImpl<TAG>& encoder, const ValueType& value)
203  {
205  }
206 };
207 
208 } // namespace ndn::lp
209 
210 #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:338
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
Definition: block.hpp:275
const_iterator value_begin() const noexcept
Get begin iterator of TLV-VALUE.
Definition: block.hpp:328
size_t value_size() const noexcept
Return the size of TLV-VALUE, i.e., the TLV-LENGTH.
Definition: block.hpp:299
const uint8_t * value() const noexcept
Return a raw pointer to the beginning of TLV-VALUE.
Definition: block.cpp:308
A concept check for TLV abstraction with a wireDecode(Block) method and constructible from Block.
Definition: concepts.hpp:82
A concept check for TLV abstraction with a wireEncode(EncodingBuffer) method.
Definition: concepts.hpp:62
Declare a field.
Definition: field-decl.hpp:174
std::integral_constant< uint32_t, TYPE > TlvType
Definition: field-decl.hpp:178
std::bool_constant< REPEATABLE > IsRepeatable
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:202
LOCATION FieldLocation
Definition: field-decl.hpp:176
static ValueType decode(const Block &wire)
Decode a field.
Definition: field-decl.hpp:187
Represents an error in TLV encoding or decoding.
Definition: tlv.hpp:54
#define NDN_THROW(e)
Definition: exception.hpp:56
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:30
Contains classes and functions related to NDNLPv2.
static EmptyValue decode(const Block &wire)
Definition: field-decl.hpp:56
static std::pair< Buffer::const_iterator, Buffer::const_iterator > decode(const Block &wire)
Definition: field-decl.hpp:96
static uint64_t decode(const Block &wire)
Definition: field-decl.hpp:80
static T decode(const Block &wire)
Definition: field-decl.hpp:44
Represents a zero-length TLV-VALUE.
Definition: empty-value.hpp:33
static size_t encode(EncodingImpl< TAG > &encoder, EmptyValue)
Definition: field-decl.hpp:121
static size_t encode(EncodingImpl< TAG > &encoder, uint64_t value)
Definition: field-decl.hpp:131
static size_t encode(EncodingImpl< TAG > &encoder, const std::pair< Buffer::const_iterator, Buffer::const_iterator > &value)
Definition: field-decl.hpp:153
static size_t encode(EncodingImpl< TAG > &encoder, uint64_t value)
Definition: field-decl.hpp:141
static size_t encode(EncodingImpl< TAG > &encoder, const T &value)
Definition: field-decl.hpp:111