22 #ifndef NDN_ENCODING_TLV_HPP
23 #define NDN_ENCODING_TLV_HPP
30 #include <type_traits>
33 #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);
111 [[deprecated(
"use GenericNameComponent")]]
176 return type <= 31 || (type & 0x01);
190 template<
typename Iterator>
192 readVarNumber(Iterator& begin, Iterator end, uint64_t& number) noexcept;
207 template<
typename Iterator>
209 readType(Iterator& begin, Iterator end, uint32_t& type) noexcept;
221 template<
typename Iterator>
237 template<
typename Iterator>
239 readType(Iterator& begin, Iterator end);
267 template<
typename Iterator>
298 template<
typename Iterator>
303 operator()(
size_t size, Iterator& begin, Iterator end, uint64_t& number)
const noexcept
307 for (; begin != end && count < size; ++begin, ++count) {
308 number = (number << 8) | *begin;
310 return count == size;
316 template<
typename Iterator>
321 operator()(
size_t size, Iterator& begin, Iterator end, uint64_t& number)
const noexcept
323 if (begin + size > end) {
335 std::memcpy(&value, &*begin, 2);
337 number = boost::endian::big_to_native(value);
342 std::memcpy(&value, &*begin, 4);
344 number = boost::endian::big_to_native(value);
349 std::memcpy(&value, &*begin, 8);
351 number = boost::endian::big_to_native(value);
366 template<
typename Iterator,
367 typename DecayedIterator = std::decay_t<Iterator>,
368 typename ValueType =
typename std::iterator_traits<DecayedIterator>::value_type>
372 return (std::is_convertible<DecayedIterator, const ValueType*>::value ||
373 std::is_convertible<DecayedIterator,
typename std::basic_string<ValueType>::const_iterator>::value ||
374 std::is_convertible<DecayedIterator,
typename std::vector<ValueType>::const_iterator>::value) &&
375 sizeof(ValueType) == 1 &&
376 !std::is_same<ValueType, bool>::value;
379 template<
typename Iterator>
380 class ReadNumber :
public std::conditional_t<shouldSelectContiguousReadNumber<Iterator>(),
381 ReadNumberFast<Iterator>, ReadNumberSlow<Iterator>>
387 template<
typename Iterator>
394 uint8_t firstOctet = *begin;
396 if (firstOctet < 253) {
401 size_t size = firstOctet == 253 ? 2 :
402 firstOctet == 254 ? 4 : 8;
406 template<
typename Iterator>
408 readType(Iterator& begin, Iterator end, uint32_t& type) noexcept
412 if (!isOk || number ==
Invalid || number > std::numeric_limits<uint32_t>::max()) {
416 type =
static_cast<uint32_t
>(number);
420 template<
typename Iterator>
437 template<
typename Iterator>
442 if (type ==
Invalid || type > std::numeric_limits<uint32_t>::max()) {
446 return static_cast<uint32_t
>(type);
452 return number < 253 ? 1 :
453 number <= std::numeric_limits<uint16_t>::max() ? 3 :
454 number <= std::numeric_limits<uint32_t>::max() ? 5 : 9;
461 os.put(
static_cast<char>(number));
464 else if (number <= std::numeric_limits<uint16_t>::max()) {
465 os.put(
static_cast<char>(253));
466 uint16_t value = boost::endian::native_to_big(
static_cast<uint16_t
>(number));
467 os.write(
reinterpret_cast<const char*
>(&value), 2);
470 else if (number <= std::numeric_limits<uint32_t>::max()) {
471 os.put(
static_cast<char>(254));
472 uint32_t value = boost::endian::native_to_big(
static_cast<uint32_t
>(number));
473 os.write(
reinterpret_cast<const char*
>(&value), 4);
477 os.put(
static_cast<char>(255));
478 uint64_t value = boost::endian::native_to_big(number);
479 os.write(
reinterpret_cast<const char*
>(&value), 8);
484 template<
typename Iterator>
488 if (size != 1 && size != 2 && size != 4 && size != 8) {
495 NDN_THROW(
Error(
"Insufficient data during nonNegativeInteger parsing"));
504 return integer <= std::numeric_limits<uint8_t>::max() ? 1 :
505 integer <= std::numeric_limits<uint16_t>::max() ? 2 :
506 integer <= std::numeric_limits<uint32_t>::max() ? 4 : 8;
512 if (integer <= std::numeric_limits<uint8_t>::max()) {
513 os.put(
static_cast<char>(integer));
516 else if (integer <= std::numeric_limits<uint16_t>::max()) {
517 uint16_t value = boost::endian::native_to_big(
static_cast<uint16_t
>(integer));
518 os.write(
reinterpret_cast<const char*
>(&value), 2);
521 else if (integer <= std::numeric_limits<uint32_t>::max()) {
522 uint32_t value = boost::endian::native_to_big(
static_cast<uint32_t
>(integer));
523 os.write(
reinterpret_cast<const char*
>(&value), 4);
527 uint64_t value = boost::endian::native_to_big(integer);
528 os.write(
reinterpret_cast<const char*
>(&value), 8);
536 #endif // NDN_ENCODING_TLV_HPP