22 #ifndef NDN_CXX_ENCODING_TLV_HPP
23 #define NDN_CXX_ENCODING_TLV_HPP
32 #include <boost/endian/conversion.hpp>
52 class Error :
public std::runtime_error
55 using std::runtime_error::runtime_error;
57 Error(
const char* expectedType, uint32_t actualType);
180 return type <= 31 || (type & 0x01);
194 template<
typename Iterator>
196 readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept;
211 template<
typename Iterator>
213 readType(Iterator& begin, Iterator end, uint32_t& type) noexcept;
225 template<
typename Iterator>
241 template<
typename Iterator>
243 readType(Iterator& begin, Iterator end);
271 template<
typename Iterator>
302 template<
typename Iterator>
307 operator()(
size_t size, Iterator& begin, Iterator end, uint64_t& number)
const noexcept
311 for (; begin != end && count < size; ++begin, ++count) {
312 number = (number << 8) | *begin;
314 return count == size;
320 template<
typename Iterator>
325 operator()(
size_t size, Iterator& begin, Iterator end, uint64_t& number)
const noexcept
327 if (begin + size > end) {
339 std::memcpy(&value, &*begin, 2);
341 number = boost::endian::big_to_native(value);
346 std::memcpy(&value, &*begin, 4);
348 number = boost::endian::big_to_native(value);
353 std::memcpy(&value, &*begin, 8);
355 number = boost::endian::big_to_native(value);
370 template<
typename Iterator,
371 typename DecayedIterator = std::decay_t<Iterator>,
372 typename ValueType =
typename std::iterator_traits<DecayedIterator>::value_type>
376 return (std::is_convertible<DecayedIterator, const ValueType*>::value ||
377 std::is_convertible<DecayedIterator,
typename std::basic_string<ValueType>::const_iterator>::value ||
378 std::is_convertible<DecayedIterator,
typename std::vector<ValueType>::const_iterator>::value) &&
379 sizeof(ValueType) == 1 &&
380 !std::is_same<ValueType, bool>::value;
383 template<
typename Iterator>
384 class ReadNumber :
public std::conditional_t<shouldSelectContiguousReadNumber<Iterator>(),
385 ReadNumberFast<Iterator>, ReadNumberSlow<Iterator>>
391 template<
typename Iterator>
398 uint8_t firstOctet = *begin;
400 if (firstOctet < 253) {
405 size_t size = firstOctet == 253 ? 2 :
406 firstOctet == 254 ? 4 : 8;
410 template<
typename Iterator>
412 readType(Iterator& begin, Iterator end, uint32_t& type) noexcept
416 if (!isOk || number ==
Invalid || number > std::numeric_limits<uint32_t>::max()) {
420 type =
static_cast<uint32_t
>(number);
424 template<
typename Iterator>
441 template<
typename Iterator>
446 if (type ==
Invalid || type > std::numeric_limits<uint32_t>::max()) {
450 return static_cast<uint32_t
>(type);
456 return number < 253 ? 1 :
457 number <= std::numeric_limits<uint16_t>::max() ? 3 :
458 number <= std::numeric_limits<uint32_t>::max() ? 5 : 9;
465 os.put(
static_cast<char>(number));
468 else if (number <= std::numeric_limits<uint16_t>::max()) {
469 os.put(
static_cast<char>(253));
470 uint16_t value = boost::endian::native_to_big(
static_cast<uint16_t
>(number));
471 os.write(
reinterpret_cast<const char*
>(&value), 2);
474 else if (number <= std::numeric_limits<uint32_t>::max()) {
475 os.put(
static_cast<char>(254));
476 uint32_t value = boost::endian::native_to_big(
static_cast<uint32_t
>(number));
477 os.write(
reinterpret_cast<const char*
>(&value), 4);
481 os.put(
static_cast<char>(255));
482 uint64_t value = boost::endian::native_to_big(number);
483 os.write(
reinterpret_cast<const char*
>(&value), 8);
488 template<
typename Iterator>
492 if (size != 1 && size != 2 && size != 4 && size != 8) {
499 NDN_THROW(
Error(
"Insufficient data during NonNegativeInteger parsing"));
508 return integer <= std::numeric_limits<uint8_t>::max() ? 1 :
509 integer <= std::numeric_limits<uint16_t>::max() ? 2 :
510 integer <= std::numeric_limits<uint32_t>::max() ? 4 : 8;
516 if (integer <= std::numeric_limits<uint8_t>::max()) {
517 os.put(
static_cast<char>(integer));
520 else if (integer <= std::numeric_limits<uint16_t>::max()) {
521 uint16_t value = boost::endian::native_to_big(
static_cast<uint16_t
>(integer));
522 os.write(
reinterpret_cast<const char*
>(&value), 2);
525 else if (integer <= std::numeric_limits<uint32_t>::max()) {
526 uint32_t value = boost::endian::native_to_big(
static_cast<uint32_t
>(integer));
527 os.write(
reinterpret_cast<const char*
>(&value), 4);
531 uint64_t value = boost::endian::native_to_big(integer);
532 os.write(
reinterpret_cast<const char*
>(&value), 8);
#define NDN_CXX_NODISCARD
#define NDN_CXX_UNREACHABLE
Represents a Data packet.
Represents an Interest packet.
Represents an absolute name.
Represents a SignatureInfo or InterestSignatureInfo TLV element.
represents an error in TLV encoding or decoding
Error(const char *expectedType, uint32_t actualType)
Function object to read a number from ContiguousIterator.
constexpr bool operator()(size_t size, Iterator &begin, Iterator end, uint64_t &number) const noexcept
Function object to read a number from InputIterator.
constexpr bool operator()(size_t size, Iterator &begin, Iterator end, uint64_t &number) const noexcept
Common includes and macros used throughout the library.
std::string to_string(const errinfo_stacktrace &x)
constexpr bool shouldSelectContiguousReadNumber()
Determine whether to select ReadNumber implementation for ContiguousIterator.
@ ParametersSha256DigestComponent
@ ImplicitSha256DigestComponent
constexpr size_t sizeOfVarNumber(uint64_t number) noexcept
Get the number of bytes necessary to hold the value of number encoded as VAR-NUMBER.
bool readVarNumber(Iterator &begin, Iterator end, uint64_t &number) noexcept
Read VAR-NUMBER in NDN-TLV encoding.
ContentTypeValue
ContentType values.
@ ContentType_Key
public key, certificate
@ ContentType_Link
another name that identifies the actual data content
@ ContentType_Blob
payload
@ ContentType_Flic
File-Like ICN Collection.
@ ContentType_PrefixAnn
prefix announcement
@ ContentType_Nack
application-level nack
size_t writeNonNegativeInteger(std::ostream &os, uint64_t integer)
Write a NonNegativeInteger to the specified stream.
bool readType(Iterator &begin, Iterator end, uint32_t &type) noexcept
Read TLV-TYPE.
constexpr bool isCriticalType(uint32_t type)
Determine whether a TLV-TYPE is "critical" for evolvability purpose.
@ ByteOffsetNameComponent
@ SequenceNumNameComponent
std::ostream & operator<<(std::ostream &os, SignatureTypeValue st)
size_t writeVarNumber(std::ostream &os, uint64_t number)
Write VAR-NUMBER to the specified stream.
constexpr size_t sizeOfNonNegativeInteger(uint64_t integer) noexcept
Get the number of bytes necessary to hold the value of integer encoded as NonNegativeInteger.
SignatureTypeValue
SignatureType values.
@ SignatureHmacWithSha256
@ SignatureSha256WithEcdsa
@ PublisherPublicKeyLocator
uint64_t readNonNegativeInteger(size_t size, Iterator &begin, Iterator end)
Read a NonNegativeInteger in NDN-TLV encoding.
const size_t MAX_NDN_PACKET_SIZE
Practical size limit of a network-layer packet.