22 #ifndef NDN_CXX_ENCODING_TLV_HPP
23 #define NDN_CXX_ENCODING_TLV_HPP
32 #include <boost/endian/conversion.hpp>
53 class Error :
public std::runtime_error
56 using std::runtime_error::runtime_error;
58 Error(
const char* expectedType, uint32_t actualType);
164 return type <= 31 || (type & 0x01);
178 template<
typename Iterator>
180 readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept;
195 template<
typename Iterator>
197 readType(Iterator& begin, Iterator end, uint32_t& type) noexcept;
209 template<
typename Iterator>
225 template<
typename Iterator>
227 readType(Iterator& begin, Iterator end);
255 template<
typename Iterator>
286 template<
typename Iterator>
291 operator()(
size_t size, Iterator& begin, Iterator end, uint64_t& number)
const noexcept
295 for (; begin != end && count < size; ++begin, ++count) {
296 number = (number << 8) | *begin;
298 return count == size;
304 template<
typename Iterator>
309 operator()(
size_t size, Iterator& begin, Iterator end, uint64_t& number)
const noexcept
311 if (begin + size > end) {
323 std::memcpy(&value, &*begin, 2);
325 number = boost::endian::big_to_native(value);
330 std::memcpy(&value, &*begin, 4);
332 number = boost::endian::big_to_native(value);
337 std::memcpy(&value, &*begin, 8);
339 number = boost::endian::big_to_native(value);
354 template<
typename Iterator,
355 typename DecayedIterator = std::decay_t<Iterator>,
356 typename ValueType =
typename std::iterator_traits<DecayedIterator>::value_type>
360 return (std::is_convertible<DecayedIterator, const ValueType*>::value ||
361 std::is_convertible<DecayedIterator,
typename std::basic_string<ValueType>::const_iterator>::value ||
362 std::is_convertible<DecayedIterator,
typename std::vector<ValueType>::const_iterator>::value) &&
363 sizeof(ValueType) == 1 &&
364 !std::is_same<ValueType, bool>::value;
367 template<
typename Iterator>
368 class ReadNumber :
public std::conditional_t<shouldSelectContiguousReadNumber<Iterator>(),
369 ReadNumberFast<Iterator>, ReadNumberSlow<Iterator>>
375 template<
typename Iterator>
382 uint8_t firstOctet = *begin;
384 if (firstOctet < 253) {
389 size_t size = firstOctet == 253 ? 2 :
390 firstOctet == 254 ? 4 : 8;
394 template<
typename Iterator>
396 readType(Iterator& begin, Iterator end, uint32_t& type) noexcept
400 if (!isOk || number ==
Invalid || number > std::numeric_limits<uint32_t>::max()) {
404 type =
static_cast<uint32_t
>(number);
408 template<
typename Iterator>
425 template<
typename Iterator>
430 if (type ==
Invalid || type > std::numeric_limits<uint32_t>::max()) {
434 return static_cast<uint32_t
>(type);
440 return number < 253 ? 1 :
441 number <= std::numeric_limits<uint16_t>::max() ? 3 :
442 number <= std::numeric_limits<uint32_t>::max() ? 5 : 9;
449 os.put(
static_cast<char>(number));
452 else if (number <= std::numeric_limits<uint16_t>::max()) {
453 os.put(
static_cast<char>(253));
454 uint16_t value = boost::endian::native_to_big(
static_cast<uint16_t
>(number));
455 os.write(
reinterpret_cast<const char*
>(&value), 2);
458 else if (number <= std::numeric_limits<uint32_t>::max()) {
459 os.put(
static_cast<char>(254));
460 uint32_t value = boost::endian::native_to_big(
static_cast<uint32_t
>(number));
461 os.write(
reinterpret_cast<const char*
>(&value), 4);
465 os.put(
static_cast<char>(255));
466 uint64_t value = boost::endian::native_to_big(number);
467 os.write(
reinterpret_cast<const char*
>(&value), 8);
472 template<
typename Iterator>
476 if (size != 1 && size != 2 && size != 4 && size != 8) {
483 NDN_THROW(
Error(
"Insufficient data during NonNegativeInteger parsing"));
492 return integer <= std::numeric_limits<uint8_t>::max() ? 1 :
493 integer <= std::numeric_limits<uint16_t>::max() ? 2 :
494 integer <= std::numeric_limits<uint32_t>::max() ? 4 : 8;
500 if (integer <= std::numeric_limits<uint8_t>::max()) {
501 os.put(
static_cast<char>(integer));
504 else if (integer <= std::numeric_limits<uint16_t>::max()) {
505 uint16_t value = boost::endian::native_to_big(
static_cast<uint16_t
>(integer));
506 os.write(
reinterpret_cast<const char*
>(&value), 2);
509 else if (integer <= std::numeric_limits<uint32_t>::max()) {
510 uint32_t value = boost::endian::native_to_big(
static_cast<uint32_t
>(integer));
511 os.write(
reinterpret_cast<const char*
>(&value), 4);
515 uint64_t value = boost::endian::native_to_big(integer);
516 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.
@ ByteOffsetNameComponent
@ SequenceNumNameComponent
@ 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.
constexpr bool isCriticalType(uint32_t type) noexcept
Determine whether a TLV-TYPE is "critical" for evolvability purpose.
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.
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
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.