ndn-cxx: NDN C++ Library 0.9.0-33-g832ea91d
Loading...
Searching...
No Matches
tlv.hpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013-2025 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_ENCODING_TLV_HPP
23#define NDN_CXX_ENCODING_TLV_HPP
24
26
27#include <cstring>
28#include <iterator>
29#include <limits>
30#include <vector>
31
32#include <boost/endian/conversion.hpp>
33
34namespace ndn {
35
41inline constexpr size_t MAX_NDN_PACKET_SIZE = 8800;
42
46namespace tlv {
47
53class Error : public std::runtime_error
54{
55public:
56 using std::runtime_error::runtime_error;
57
58 Error(const char* expectedType, uint32_t actualType);
59};
60
66enum : uint32_t {
69 Data = 6,
70
71 Name = 7,
81
85 Nonce = 10,
91
93 Content = 21,
99
106
109 NotAfter = 255,
114
117
120};
121
135
136std::ostream&
137operator<<(std::ostream& os, SignatureTypeValue st);
138
153
154std::ostream&
155operator<<(std::ostream& os, ContentTypeValue ct);
156
161constexpr bool
162isCriticalType(uint32_t type) noexcept
163{
164 return type <= 31 || (type & 0x01);
165}
166
178template<typename Iterator>
179[[nodiscard]] constexpr bool
180readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept;
181
195template<typename Iterator>
196[[nodiscard]] constexpr bool
197readType(Iterator& begin, Iterator end, uint32_t& type) noexcept;
198
209template<typename Iterator>
210constexpr uint64_t
211readVarNumber(Iterator& begin, Iterator end);
212
225template<typename Iterator>
226constexpr uint32_t
227readType(Iterator& begin, Iterator end);
228
232[[nodiscard]] constexpr size_t
233sizeOfVarNumber(uint64_t number) noexcept;
234
239size_t
240writeVarNumber(std::ostream& os, uint64_t number);
241
255template<typename Iterator>
256constexpr uint64_t
257readNonNegativeInteger(size_t size, Iterator& begin, Iterator end);
258
262[[nodiscard]] constexpr size_t
263sizeOfNonNegativeInteger(uint64_t integer) noexcept;
264
269size_t
270writeNonNegativeInteger(std::ostream& os, uint64_t integer);
271
273// Inline definitions
275
276namespace detail {
277
286template<typename Iterator,
287 typename DecayedIterator = std::decay_t<Iterator>,
288 typename ValueType = typename std::iterator_traits<DecayedIterator>::value_type>
290#ifndef _LIBCPP_VERSION
291 std::disjunction<
292#endif
293 std::conjunction<
294 std::bool_constant<sizeof(ValueType) == 1>,
295 std::negation<std::is_same<ValueType, bool>>,
296 std::disjunction<
297 std::is_convertible<DecayedIterator, const ValueType*>,
298 std::is_convertible<DecayedIterator, typename std::vector<ValueType>::const_iterator>>>
299// ugly hack to unbreak the build with libc++ >= 19, which doesn't define char_traits<unsigned char>
300#ifndef _LIBCPP_VERSION
301 ,
302 std::conjunction<
303 std::is_same<ValueType, char>,
304 std::is_convertible<DecayedIterator, typename std::basic_string<ValueType>::const_iterator>>>
305#endif
306 ;
307
308template<typename Iterator>
309constexpr bool
310readNumber(size_t size, Iterator& begin, Iterator end, uint64_t& number) noexcept
311{
312 if constexpr (IsContiguousIterator<Iterator>()) {
313 // fast path
314 if (begin + size > end) {
315 return false;
316 }
317 switch (size) {
318 case 1: {
319 number = *begin;
320 ++begin;
321 return true;
322 }
323 case 2: {
324 uint16_t value = 0;
325 std::memcpy(&value, &*begin, 2);
326 begin += 2;
327 number = boost::endian::big_to_native(value);
328 return true;
329 }
330 case 4: {
331 uint32_t value = 0;
332 std::memcpy(&value, &*begin, 4);
333 begin += 4;
334 number = boost::endian::big_to_native(value);
335 return true;
336 }
337 case 8: {
338 uint64_t value = 0;
339 std::memcpy(&value, &*begin, 8);
340 begin += 8;
341 number = boost::endian::big_to_native(value);
342 return true;
343 }
344 default: {
346 }
347 }
348 }
349 else {
350 // slow path
351 number = 0;
352 size_t count = 0;
353 for (; begin != end && count < size; ++begin, ++count) {
354 number = (number << 8) | *begin;
355 }
356 return count == size;
357 }
358}
359
360} // namespace detail
361
362template<typename Iterator>
363constexpr bool
364readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept
365{
366 if (begin == end)
367 return false;
368
369 uint8_t firstOctet = *begin;
370 ++begin;
371 if (firstOctet < 253) {
372 number = firstOctet;
373 return true;
374 }
375
376 size_t len = 1U << (firstOctet & 0b11);
377 return detail::readNumber(len, begin, end, number);
378}
379
380template<typename Iterator>
381constexpr bool
382readType(Iterator& begin, Iterator end, uint32_t& type) noexcept
383{
384 uint64_t number = 0;
385 bool isOk = readVarNumber(begin, end, number);
386 if (!isOk || number == Invalid || number > std::numeric_limits<uint32_t>::max()) {
387 return false;
388 }
389
390 type = static_cast<uint32_t>(number);
391 return true;
392}
393
394template<typename Iterator>
395constexpr uint64_t
396readVarNumber(Iterator& begin, Iterator end)
397{
398 uint64_t number = 0;
399 bool isOk = readVarNumber(begin, end, number);
400 if (!isOk) {
401 NDN_THROW(Error("Insufficient data during TLV parsing"));
402 }
403
404 return number;
405}
406
407template<typename Iterator>
408constexpr uint32_t
409readType(Iterator& begin, Iterator end)
410{
411 uint64_t type = readVarNumber(begin, end);
412 if (type == Invalid || type > std::numeric_limits<uint32_t>::max()) {
413 NDN_THROW(Error("Illegal TLV-TYPE " + to_string(type)));
414 }
415
416 return static_cast<uint32_t>(type);
417}
418
419constexpr size_t
420sizeOfVarNumber(uint64_t number) noexcept
421{
422 return number < 253 ? 1 :
423 number <= std::numeric_limits<uint16_t>::max() ? 3 :
424 number <= std::numeric_limits<uint32_t>::max() ? 5 : 9;
425}
426
427template<typename Iterator>
428constexpr uint64_t
429readNonNegativeInteger(size_t len, Iterator& begin, Iterator end)
430{
431 if (len != 1 && len != 2 && len != 4 && len != 8) {
432 NDN_THROW(Error("Invalid NonNegativeInteger length " + to_string(len)));
433 }
434
435 uint64_t number = 0;
436 bool isOk = detail::readNumber(len, begin, end, number);
437 if (!isOk) {
438 NDN_THROW(Error("Insufficient data during NonNegativeInteger parsing"));
439 }
440
441 return number;
442}
443
444constexpr size_t
445sizeOfNonNegativeInteger(uint64_t integer) noexcept
446{
447 return integer <= std::numeric_limits<uint8_t>::max() ? 1 :
448 integer <= std::numeric_limits<uint16_t>::max() ? 2 :
449 integer <= std::numeric_limits<uint32_t>::max() ? 4 : 8;
450}
451
452} // namespace tlv
453} // namespace ndn
454
455#endif // NDN_CXX_ENCODING_TLV_HPP
#define NDN_CXX_UNREACHABLE
Definition backports.hpp:57
Represents a Data packet.
Definition data.hpp:39
Represents an Interest packet.
Definition interest.hpp:50
A MetaInfo holds the meta info which is signed inside the Data packet.
Definition meta-info.hpp:62
Represents an absolute name.
Definition name.hpp:45
Represents a SignatureInfo or InterestSignatureInfo TLV element.
Represents an error in TLV encoding or decoding.
Definition tlv.hpp:54
Common includes and macros used throughout the library.
#define NDN_THROW(e)
Definition exception.hpp:56
std::disjunction< std::conjunction< std::bool_constant< sizeof(ValueType)==1 >, std::negation< std::is_same< ValueType, bool > >, std::disjunction< std::is_convertible< DecayedIterator, const ValueType * >, std::is_convertible< DecayedIterator, typename std::vector< ValueType >::const_iterator > > >, std::conjunction< std::is_same< ValueType, char >, std::is_convertible< DecayedIterator, typename std::basic_string< ValueType >::const_iterator > > > IsContiguousIterator
Determine whether to select the readNumber() implementation for ContiguousIterator.
Definition tlv.hpp:306
constexpr bool readNumber(size_t size, Iterator &begin, Iterator end, uint64_t &number) noexcept
Definition tlv.hpp:310
@ SignatureSeqNum
Definition tlv.hpp:105
@ KeyDigest
Definition tlv.hpp:102
@ TimestampNameComponent
Definition tlv.hpp:79
@ FinalBlockId
Definition tlv.hpp:98
@ GenericNameComponent
Definition tlv.hpp:72
@ DescriptionValue
Definition tlv.hpp:113
@ SignatureNonce
Definition tlv.hpp:103
@ InterestLifetime
Definition tlv.hpp:86
@ HopLimit
Definition tlv.hpp:87
@ DescriptionKey
Definition tlv.hpp:112
@ AppPrivateBlock2
Definition tlv.hpp:119
@ InterestSignatureInfo
Definition tlv.hpp:89
@ ApplicationParameters
Definition tlv.hpp:88
@ ByteOffsetNameComponent
Definition tlv.hpp:77
@ ForwardingHint
Definition tlv.hpp:84
@ AdditionalDescription
Definition tlv.hpp:110
@ SignatureType
Definition tlv.hpp:100
@ NameComponentMin
Definition tlv.hpp:115
@ InterestSignatureValue
Definition tlv.hpp:90
@ SignatureTime
Definition tlv.hpp:104
@ VersionNameComponent
Definition tlv.hpp:78
@ AppPrivateBlock1
Definition tlv.hpp:118
@ Content
Definition tlv.hpp:93
@ CanBePrefix
Definition tlv.hpp:82
@ Invalid
Definition tlv.hpp:67
@ DescriptionEntry
Definition tlv.hpp:111
@ ContentType
Definition tlv.hpp:96
@ SequenceNumNameComponent
Definition tlv.hpp:80
@ NameComponentMax
Definition tlv.hpp:116
@ ValidityPeriod
Definition tlv.hpp:107
@ NotAfter
Definition tlv.hpp:109
@ FreshnessPeriod
Definition tlv.hpp:97
@ KeywordNameComponent
Definition tlv.hpp:75
@ ParametersSha256DigestComponent
Definition tlv.hpp:74
@ SignatureValue
Definition tlv.hpp:95
@ ImplicitSha256DigestComponent
Definition tlv.hpp:73
@ NotBefore
Definition tlv.hpp:108
@ SegmentNameComponent
Definition tlv.hpp:76
@ MustBeFresh
Definition tlv.hpp:83
@ Nonce
Definition tlv.hpp:85
constexpr size_t sizeOfVarNumber(uint64_t number) noexcept
Get the number of bytes necessary to hold the value of number encoded as VAR-NUMBER.
Definition tlv.hpp:420
constexpr bool readVarNumber(Iterator &begin, Iterator end, uint64_t &number) noexcept
Read VAR-NUMBER in NDN-TLV encoding.
Definition tlv.hpp:364
constexpr bool readType(Iterator &begin, Iterator end, uint32_t &type) noexcept
Read TLV-TYPE.
Definition tlv.hpp:382
constexpr bool isCriticalType(uint32_t type) noexcept
Determine whether a TLV-TYPE is "critical" for evolvability purpose.
Definition tlv.hpp:162
ContentTypeValue
ContentType values.
Definition tlv.hpp:144
@ ContentType_Key
public key, certificate
Definition tlv.hpp:147
@ ContentType_Manifest
Definition tlv.hpp:149
@ ContentType_Link
another name that identifies the actual data content
Definition tlv.hpp:146
@ ContentType_Blob
payload
Definition tlv.hpp:145
@ ContentType_Flic
File-Like ICN Collection.
Definition tlv.hpp:151
@ ContentType_PrefixAnn
prefix announcement
Definition tlv.hpp:150
@ ContentType_Nack
application-level nack
Definition tlv.hpp:148
size_t writeNonNegativeInteger(std::ostream &os, uint64_t integer)
Write a NonNegativeInteger to the specified stream.
Definition tlv.cpp:113
std::ostream & operator<<(std::ostream &os, SignatureTypeValue st)
Definition tlv.cpp:34
size_t writeVarNumber(std::ostream &os, uint64_t number)
Write VAR-NUMBER to the specified stream.
Definition tlv.cpp:86
constexpr size_t sizeOfNonNegativeInteger(uint64_t integer) noexcept
Get the number of bytes necessary to hold the value of integer encoded as NonNegativeInteger.
Definition tlv.hpp:445
SignatureTypeValue
SignatureType values.
Definition tlv.hpp:127
@ SignatureSha256WithRsa
Definition tlv.hpp:129
@ DigestSha256
Definition tlv.hpp:128
@ SignatureHmacWithSha256
Definition tlv.hpp:131
@ SignatureEd25519
Definition tlv.hpp:132
@ SignatureSha256WithEcdsa
Definition tlv.hpp:130
@ NullSignature
Definition tlv.hpp:133
Definition data.cpp:25
constexpr size_t MAX_NDN_PACKET_SIZE
Practical size limit of a network-layer packet.
Definition tlv.hpp:41