encoding: convert to span

Change-Id: I8bd73284fbd5acc0ff8ad2626af9b4324e9df7a1
diff --git a/ndn-cxx/data.cpp b/ndn-cxx/data.cpp
index fff95b8..a54458c 100644
--- a/ndn-cxx/data.cpp
+++ b/ndn-cxx/data.cpp
@@ -60,7 +60,7 @@
     if (!m_signatureInfo) {
       NDN_THROW(Error("Requested wire format, but Data has not been signed"));
     }
-    totalLength += encoder.prependBlock(m_signatureValue);
+    totalLength += prependBlock(encoder, m_signatureValue);
   }
 
   // SignatureInfo
@@ -68,7 +68,7 @@
 
   // Content
   if (hasContent()) {
-    totalLength += encoder.prependBlock(m_content);
+    totalLength += prependBlock(encoder, m_content);
   }
 
   // MetaInfo
@@ -91,10 +91,12 @@
 Data::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, bool) const;
 
 const Block&
-Data::wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const
+Data::wireEncode(EncodingBuffer& encoder, span<const uint8_t> signature) const
 {
   size_t totalLength = encoder.size();
-  totalLength += encoder.appendBlock(signatureValue);
+  totalLength += encoder.appendVarNumber(tlv::SignatureValue);
+  totalLength += encoder.appendVarNumber(signature.size());
+  totalLength += encoder.appendBytes(signature);
 
   encoder.prependVarNumber(totalLength);
   encoder.prependVarNumber(tlv::Data);
@@ -261,7 +263,7 @@
 Data&
 Data::setContent(span<const uint8_t> value)
 {
-  m_content = makeBinaryBlock(tlv::Content, value.data(), value.size());
+  m_content = makeBinaryBlock(tlv::Content, value);
   resetWire();
   return *this;
 }
diff --git a/ndn-cxx/data.hpp b/ndn-cxx/data.hpp
index c75e138..040774a 100644
--- a/ndn-cxx/data.hpp
+++ b/ndn-cxx/data.hpp
@@ -60,36 +60,39 @@
   explicit
   Data(const Block& wire);
 
-  /** @brief Prepend wire encoding to @p encoder
-   *  @param encoder EncodingEstimator or EncodingBuffer instance.
-   *  @param wantUnsignedPortionOnly If true, prepend only Name, MetaInfo, Content, and
-   *         SignatureInfo to @p encoder, but omit SignatureValue and the outermost TLV
-   *         Type and Length of the Data element. This is intended to be used with
-   *         wireEncode(EncodingBuffer&, const Block&) const.
-   *  @throw Error %Signature is not present and @p wantUnsignedPortionOnly is false.
+  /**
+   * @brief Prepend wire encoding to @p encoder.
+   * @param encoder EncodingEstimator or EncodingBuffer instance.
+   * @param wantUnsignedPortionOnly If true, prepend only Name, MetaInfo, Content, and
+   *        SignatureInfo to @p encoder, but omit SignatureValue and the outermost TLV
+   *        Type and Length of the %Data element. This is intended to be used with
+   *        wireEncode(EncodingBuffer&, span<const uint8_t>) const.
+   * @throw Error Signature is not present and @p wantUnsignedPortionOnly is false.
    */
   template<encoding::Tag TAG>
   size_t
   wireEncode(EncodingImpl<TAG>& encoder, bool wantUnsignedPortionOnly = false) const;
 
-  /** @brief Finalize Data packet encoding with the specified SignatureValue
-   *  @param encoder EncodingBuffer containing Name, MetaInfo, Content, and SignatureInfo, but
-   *                 without SignatureValue and the outermost Type-Length of the Data element.
-   *  @param signatureValue SignatureValue element.
+  /**
+   * @brief Finalize Data packet encoding with the specified signature.
+   * @param encoder EncodingBuffer containing Name, MetaInfo, Content, and SignatureInfo, but
+   *                without SignatureValue and the outermost Type-Length of the %Data element.
+   * @param signature Raw signature bytes, without TLV Type and Length; this will become the
+   *                  TLV-VALUE of the SignatureValue element added to the packet.
    *
-   *  This method is intended to be used in concert with `wireEncode(encoder, true)`, e.g.:
-   *  @code
-   *     Data data;
-   *     ...
-   *     EncodingBuffer encoder;
-   *     data.wireEncode(encoder, true);
-   *     ...
-   *     Block signatureValue = <sign_over_unsigned_portion>(encoder.buf(), encoder.size());
-   *     data.wireEncode(encoder, signatureValue)
-   *  @endcode
+   * This method is intended to be used in concert with `wireEncode(encoder, true)`, e.g.:
+   * @code
+   * Data data;
+   * ...
+   * EncodingBuffer encoder;
+   * data.wireEncode(encoder, true);
+   * ...
+   * auto signature = create_signature_over_signed_portion(encoder.data(), encoder.size());
+   * data.wireEncode(encoder, signature);
+   * @endcode
    */
   const Block&
-  wireEncode(EncodingBuffer& encoder, const Block& signatureValue) const;
+  wireEncode(EncodingBuffer& encoder, span<const uint8_t> signature) const;
 
   /** @brief Encode into a Block.
    *  @pre Data must be signed.
diff --git a/ndn-cxx/encoding/block-helpers.cpp b/ndn-cxx/encoding/block-helpers.cpp
index f7ea61e..99ada84 100644
--- a/ndn-cxx/encoding/block-helpers.cpp
+++ b/ndn-cxx/encoding/block-helpers.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -34,12 +34,11 @@
 size_t
 prependNonNegativeIntegerBlock(EncodingImpl<TAG>& encoder, uint32_t type, uint64_t value)
 {
-  size_t valueLength = encoder.prependNonNegativeInteger(value);
-  size_t totalLength = valueLength;
-  totalLength += encoder.prependVarNumber(valueLength);
-  totalLength += encoder.prependVarNumber(type);
+  size_t length = encoder.prependNonNegativeInteger(value);
+  length += encoder.prependVarNumber(length);
+  length += encoder.prependVarNumber(type);
 
-  return totalLength;
+  return length;
 }
 
 template size_t
@@ -73,10 +72,10 @@
 size_t
 prependEmptyBlock(EncodingImpl<TAG>& encoder, uint32_t type)
 {
-  size_t totalLength = encoder.prependVarNumber(0);
-  totalLength += encoder.prependVarNumber(type);
+  size_t length = encoder.prependVarNumber(0);
+  length += encoder.prependVarNumber(type);
 
-  return totalLength;
+  return length;
 }
 
 template size_t
@@ -103,7 +102,7 @@
 size_t
 prependStringBlock(EncodingImpl<TAG>& encoder, uint32_t type, const std::string& value)
 {
-  return encoder.prependByteArrayBlock(type, reinterpret_cast<const uint8_t*>(value.data()), value.size());
+  return prependBinaryBlock(encoder, type, {reinterpret_cast<const uint8_t*>(value.data()), value.size()});
 }
 
 template size_t
@@ -135,7 +134,7 @@
   uint64_t temp = 0;
   std::memcpy(&temp, &value, 8);
   endian::native_to_big_inplace(temp);
-  return encoder.prependByteArrayBlock(type, reinterpret_cast<const uint8_t*>(&temp), 8);
+  return prependBinaryBlock(encoder, type, {reinterpret_cast<const uint8_t*>(&temp), 8});
 }
 
 template size_t
@@ -177,17 +176,55 @@
 
 // ---- binary ----
 
+template<Tag TAG>
+size_t
+prependBinaryBlock(EncodingImpl<TAG>& encoder, uint32_t type, span<const uint8_t> value)
+{
+  size_t length = encoder.prependBytes(value);
+  length += encoder.prependVarNumber(length);
+  length += encoder.prependVarNumber(type);
+
+  return length;
+}
+
+template size_t
+prependBinaryBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, span<const uint8_t>);
+
+template size_t
+prependBinaryBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, span<const uint8_t>);
+
 Block
 makeBinaryBlock(uint32_t type, span<const uint8_t> value)
 {
   EncodingEstimator estimator;
-  size_t totalLength = estimator.prependByteArrayBlock(type, value.data(), value.size());
+  size_t totalLength = prependBinaryBlock(estimator, type, value);
 
   EncodingBuffer encoder(totalLength, 0);
-  encoder.prependByteArrayBlock(type, value.data(), value.size());
+  prependBinaryBlock(encoder, type, value);
 
   return encoder.block();
 }
 
+// ---- block ----
+
+template<Tag TAG>
+size_t
+prependBlock(EncodingImpl<TAG>& encoder, const Block& block)
+{
+  if (block.hasWire()) {
+    return encoder.prependBytes({block.wire(), block.size()});
+  }
+  else {
+    // FIXME: blindly calling Block::value() is not safe if the value is not wire-encoded
+    return prependBinaryBlock(encoder, block.type(), {block.value(), block.value_size()});
+  }
+}
+
+template size_t
+prependBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, const Block&);
+
+template size_t
+prependBlock<EncoderTag>(EncodingImpl<EncoderTag>&, const Block&);
+
 } // namespace encoding
 } // namespace ndn
diff --git a/ndn-cxx/encoding/block-helpers.hpp b/ndn-cxx/encoding/block-helpers.hpp
index 3418d76..8224a77 100644
--- a/ndn-cxx/encoding/block-helpers.hpp
+++ b/ndn-cxx/encoding/block-helpers.hpp
@@ -25,7 +25,6 @@
 #include "ndn-cxx/encoding/block.hpp"
 #include "ndn-cxx/encoding/encoding-buffer.hpp"
 #include "ndn-cxx/util/concepts.hpp"
-#include "ndn-cxx/util/span.hpp"
 
 namespace ndn {
 namespace encoding {
@@ -182,10 +181,28 @@
 double
 readDouble(const Block& block);
 
-/** @brief Create a TLV block copying the TLV-VALUE from a range.
- *  @param type TLV-TYPE number
- *  @param value range of bytes to use as TLV-VALUE
- *  @sa Encoder::prependByteArrayBlock
+/**
+ * @brief Prepend a TLV element containing a sequence of raw bytes.
+ * @param encoder an EncodingBuffer or EncodingEstimator
+ * @param type TLV-TYPE number
+ * @param value range of bytes to use as TLV-VALUE
+ * @sa makeBinaryBlock
+ */
+template<Tag TAG>
+size_t
+prependBinaryBlock(EncodingImpl<TAG>& encoder, uint32_t type, span<const uint8_t> value);
+
+extern template size_t
+prependBinaryBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, uint32_t, span<const uint8_t>);
+
+extern template size_t
+prependBinaryBlock<EncoderTag>(EncodingImpl<EncoderTag>&, uint32_t, span<const uint8_t>);
+
+/**
+ * @brief Create a TLV block copying the TLV-VALUE from a byte range.
+ * @param type TLV-TYPE number
+ * @param value range of bytes to use as TLV-VALUE
+ * @sa prependBinaryBlock
  */
 Block
 makeBinaryBlock(uint32_t type, span<const uint8_t> value);
@@ -194,8 +211,9 @@
  *  @param type TLV-TYPE number
  *  @param value raw buffer as TLV-VALUE
  *  @param length length of value buffer
- *  @sa Encoder::prependByteArrayBlock
+ *  @deprecated
  */
+[[deprecated("use the overload that takes a span<>")]]
 inline Block
 makeBinaryBlock(uint32_t type, const uint8_t* value, size_t length)
 {
@@ -206,7 +224,7 @@
  *  @param type TLV-TYPE number
  *  @param value raw buffer as TLV-VALUE
  *  @param length length of value buffer
- *  @sa Encoder::prependByteArrayBlock
+ *  @deprecated
  */
 inline Block
 makeBinaryBlock(uint32_t type, const char* value, size_t length)
@@ -216,7 +234,8 @@
 
 namespace detail {
 
-/** @brief Create a binary block copying from RandomAccessIterator.
+/**
+ * @brief Create a binary block copying from RandomAccessIterator.
  */
 template<class Iterator>
 class BinaryBlockFast
@@ -242,7 +261,8 @@
   }
 };
 
-/** @brief Create a binary block copying from generic InputIterator.
+/**
+ * @brief Create a binary block copying from generic InputIterator.
  */
 template<class Iterator>
 class BinaryBlockSlow
@@ -272,6 +292,7 @@
  *  @param type TLV-TYPE number
  *  @param first begin iterator
  *  @param last past-the-end iterator
+ *  @sa prependBinaryBlock
  */
 template<class Iterator>
 Block
@@ -286,6 +307,21 @@
   return BinaryBlockHelper::makeBlock(type, first, last);
 }
 
+/**
+ * @brief Prepend a TLV element.
+ * @param encoder an EncodingBuffer or EncodingEstimator
+ * @param block the TLV element
+ */
+template<Tag TAG>
+size_t
+prependBlock(EncodingImpl<TAG>& encoder, const Block& block);
+
+extern template size_t
+prependBlock<EstimatorTag>(EncodingImpl<EstimatorTag>&, const Block&);
+
+extern template size_t
+prependBlock<EncoderTag>(EncodingImpl<EncoderTag>&, const Block&);
+
 /** @brief Prepend a TLV element containing a nested TLV element.
  *  @tparam U type that satisfies WireEncodableWithEncodingBuffer concept
  *  @param encoder an EncodingBuffer or EncodingEstimator
diff --git a/ndn-cxx/encoding/block.cpp b/ndn-cxx/encoding/block.cpp
index 052b049..56a1477 100644
--- a/ndn-cxx/encoding/block.cpp
+++ b/ndn-cxx/encoding/block.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -48,6 +48,30 @@
 Block&
 Block::operator=(const Block&) = default;
 
+Block::Block(span<const uint8_t> buffer)
+{
+  auto pos = buffer.begin();
+  const auto end = buffer.end();
+
+  m_type = tlv::readType(pos, end);
+  uint64_t length = tlv::readVarNumber(pos, end);
+  // pos now points to TLV-VALUE
+
+  BOOST_ASSERT(pos <= end);
+  if (length > static_cast<uint64_t>(std::distance(pos, end))) {
+    NDN_THROW(Error("Not enough bytes in the buffer to fully parse TLV"));
+  }
+  std::advance(pos, length);
+  // pos now points to the end of the TLV
+
+  m_buffer = std::make_shared<Buffer>(buffer.begin(), pos);
+  m_begin = m_buffer->begin();
+  m_end = m_buffer->end();
+  m_valueBegin = std::prev(m_end, length);
+  m_valueEnd = m_buffer->end();
+  m_size = m_buffer->size();
+}
+
 Block::Block(const EncodingBuffer& buffer)
   : Block(buffer.getBuffer(), buffer.begin(), buffer.end(), true)
 {
@@ -65,7 +89,7 @@
   , m_end(end)
   , m_valueBegin(m_begin)
   , m_valueEnd(m_end)
-  , m_size(m_end - m_begin)
+  , m_size(static_cast<size_t>(std::distance(m_begin, m_end)))
 {
   if (m_buffer->empty()) {
     NDN_THROW(std::invalid_argument("Buffer is empty"));
@@ -102,32 +126,13 @@
   , m_valueBegin(valueBegin)
   , m_valueEnd(valueEnd)
   , m_type(type)
-  , m_size(m_end - m_begin)
+  , m_size(static_cast<size_t>(std::distance(m_begin, m_end)))
 {
 }
 
 Block::Block(const uint8_t* buf, size_t bufSize)
+  : Block(make_span(buf, bufSize))
 {
-  const uint8_t* pos = buf;
-  const uint8_t* const end = buf + bufSize;
-
-  m_type = tlv::readType(pos, end);
-  uint64_t length = tlv::readVarNumber(pos, end);
-  // pos now points to TLV-VALUE
-
-  BOOST_ASSERT(pos <= end);
-  if (length > static_cast<uint64_t>(end - pos)) {
-    NDN_THROW(Error("Not enough bytes in the buffer to fully parse TLV"));
-  }
-
-  BOOST_ASSERT(pos > buf);
-  uint64_t typeLengthSize = static_cast<uint64_t>(pos - buf);
-  m_size = typeLengthSize + length;
-
-  m_buffer = make_shared<Buffer>(buf, m_size);
-  m_begin = m_buffer->begin();
-  m_end = m_valueEnd = m_buffer->end();
-  m_valueBegin = m_begin + typeLengthSize;
 }
 
 Block::Block(uint32_t type)
@@ -158,6 +163,70 @@
   m_size = tlv::sizeOfVarNumber(m_type) + tlv::sizeOfVarNumber(value_size()) + value_size();
 }
 
+std::tuple<bool, Block>
+Block::fromBuffer(ConstBufferPtr buffer, size_t offset)
+{
+  auto begin = std::next(buffer->begin(), offset);
+  auto pos = begin;
+  const auto end = buffer->end();
+
+  uint32_t type = 0;
+  bool isOk = tlv::readType(pos, end, type);
+  if (!isOk) {
+    return std::make_tuple(false, Block());
+  }
+
+  uint64_t length = 0;
+  isOk = tlv::readVarNumber(pos, end, length);
+  if (!isOk) {
+    return std::make_tuple(false, Block());
+  }
+  // pos now points to TLV-VALUE
+
+  BOOST_ASSERT(pos <= end);
+  if (length > static_cast<uint64_t>(std::distance(pos, end))) {
+    return std::make_tuple(false, Block());
+  }
+
+  return std::make_tuple(true, Block(std::move(buffer), type, begin, pos + length, pos, pos + length));
+}
+
+std::tuple<bool, Block>
+Block::fromBuffer(span<const uint8_t> buffer)
+{
+  auto pos = buffer.begin();
+  const auto end = buffer.end();
+
+  uint32_t type = 0;
+  bool isOk = tlv::readType(pos, end, type);
+  if (!isOk) {
+    return std::make_tuple(false, Block());
+  }
+  uint64_t length = 0;
+  isOk = tlv::readVarNumber(pos, end, length);
+  if (!isOk) {
+    return std::make_tuple(false, Block());
+  }
+  // pos now points to TLV-VALUE
+
+  BOOST_ASSERT(pos <= end);
+  if (length > static_cast<uint64_t>(std::distance(pos, end))) {
+    return std::make_tuple(false, Block());
+  }
+  std::advance(pos, length);
+  // pos now points to the end of the TLV
+
+  auto b = std::make_shared<Buffer>(buffer.begin(), pos);
+  return std::make_tuple(true, Block(b, type, b->begin(), b->end(),
+                                     std::prev(b->end(), length), b->end()));
+}
+
+std::tuple<bool, Block>
+Block::fromBuffer(const uint8_t* buf, size_t bufSize)
+{
+  return fromBuffer({buf, bufSize});
+}
+
 Block
 Block::fromStream(std::istream& is)
 {
@@ -176,7 +245,7 @@
   }
 
   EncodingBuffer eb(tlSize + length, length);
-  uint8_t* valueBuf = eb.buf();
+  uint8_t* valueBuf = eb.data();
   is.read(reinterpret_cast<char*>(valueBuf), length);
   if (length != static_cast<uint64_t>(is.gcount())) {
     NDN_THROW(Error("Not enough bytes from stream to fully parse TLV"));
@@ -190,60 +259,6 @@
   return Block(eb.getBuffer());
 }
 
-std::tuple<bool, Block>
-Block::fromBuffer(ConstBufferPtr buffer, size_t offset)
-{
-  auto begin = buffer->begin() + offset;
-  auto pos = begin;
-
-  uint32_t type = 0;
-  bool isOk = tlv::readType(pos, buffer->end(), type);
-  if (!isOk) {
-    return std::make_tuple(false, Block());
-  }
-
-  uint64_t length = 0;
-  isOk = tlv::readVarNumber(pos, buffer->end(), length);
-  if (!isOk) {
-    return std::make_tuple(false, Block());
-  }
-  // pos now points to TLV-VALUE
-
-  if (length > static_cast<uint64_t>(buffer->end() - pos)) {
-    return std::make_tuple(false, Block());
-  }
-
-  return std::make_tuple(true, Block(std::move(buffer), type, begin, pos + length, pos, pos + length));
-}
-
-std::tuple<bool, Block>
-Block::fromBuffer(const uint8_t* buf, size_t bufSize)
-{
-  const uint8_t* pos = buf;
-  const uint8_t* const end = buf + bufSize;
-
-  uint32_t type = 0;
-  bool isOk = tlv::readType(pos, end, type);
-  if (!isOk) {
-    return std::make_tuple(false, Block());
-  }
-  uint64_t length = 0;
-  isOk = tlv::readVarNumber(pos, end, length);
-  if (!isOk) {
-    return std::make_tuple(false, Block());
-  }
-  // pos now points to TLV-VALUE
-
-  if (length > static_cast<uint64_t>(end - pos)) {
-    return std::make_tuple(false, Block());
-  }
-
-  size_t typeLengthSize = pos - buf;
-  auto b = make_shared<Buffer>(buf, pos + length);
-  return std::make_tuple(true, Block(b, type, b->begin(), b->end(),
-                                     b->begin() + typeLengthSize, b->end()));
-}
-
 // ---- wire format ----
 
 void
@@ -342,7 +357,7 @@
     }
     // pos now points to TLV-VALUE of sub element
 
-    auto subEnd = pos + length;
+    auto subEnd = std::next(pos, length);
     m_elements.emplace_back(m_buffer, type, begin, subEnd, pos, subEnd);
 
     begin = subEnd;
diff --git a/ndn-cxx/encoding/block.hpp b/ndn-cxx/encoding/block.hpp
index 41a1b30..9da1946 100644
--- a/ndn-cxx/encoding/block.hpp
+++ b/ndn-cxx/encoding/block.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -27,6 +27,7 @@
 #include "ndn-cxx/encoding/buffer.hpp"
 #include "ndn-cxx/encoding/encoding-buffer-fwd.hpp"
 #include "ndn-cxx/encoding/tlv.hpp"
+#include "ndn-cxx/util/span.hpp"
 
 namespace boost {
 namespace asio {
@@ -36,8 +37,9 @@
 
 namespace ndn {
 
-/** @brief Represents a TLV element of the NDN packet format.
- *  @sa https://named-data.net/doc/NDN-packet-spec/0.3/tlv.html#tlv-encoding
+/**
+ * @brief Represents a TLV element of the NDN packet format.
+ * @sa https://named-data.net/doc/NDN-packet-spec/0.3/tlv.html
  */
 class Block
 {
@@ -76,6 +78,15 @@
   Block&
   operator=(Block&&) noexcept;
 
+  /** @brief Parse Block from a byte range
+   *  @param buffer sequence of bytes containing a TLV element; the element must be found at
+   *                the beginning of the buffer but does not need to span the entire buffer
+   *  @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH exceeds the size of @p buffer
+   *  @note This constructor copies the TLV element octets to an internal buffer.
+   */
+  explicit
+  Block(span<const uint8_t> buffer);
+
   /** @brief Parse Block from an EncodingBuffer
    *  @param buffer an EncodingBuffer containing one TLV element
    *  @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
@@ -85,8 +96,8 @@
 
   /** @brief Parse Block from a wire Buffer
    *  @param buffer a Buffer containing one TLV element
-   *  @note This constructor takes shared ownership of @p buffer.
    *  @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
+   *  @note This constructor takes shared ownership of @p buffer.
    */
   explicit
   Block(const ConstBufferPtr& buffer);
@@ -98,7 +109,6 @@
    *  @param verifyLength if true, check TLV-LENGTH equals size of TLV-VALUE
    *  @throw std::invalid_argument @p buffer is empty, or [@p begin,@p end) range is not within @p buffer
    *  @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
-   *  @note This overload automatically detects TLV-TYPE and position of TLV-VALUE.
    */
   Block(ConstBufferPtr buffer, Buffer::const_iterator begin, Buffer::const_iterator end,
         bool verifyLength = true);
@@ -130,8 +140,10 @@
    *  @param buf pointer to the first octet of a TLV element
    *  @param bufSize size of the raw buffer; may be greater than the actual size of the TLV element
    *  @throw tlv::Error Type-Length parsing fails, or size of TLV-VALUE exceeds @p bufSize
-   *  @note This overload copies the TLV element octets into an internal wire buffer.
+   *  @note This constructor copies the TLV element octets to an internal buffer.
+   *  @deprecated
    */
+  [[deprecated("use the constructor that takes a span<>")]]
   Block(const uint8_t* buf, size_t bufSize);
 
   /** @brief Create a zero-length Block with the specified TLV-TYPE
@@ -152,6 +164,37 @@
    */
   Block(uint32_t type, const Block& value);
 
+  /** @brief Try to parse Block from a wire buffer
+   *  @param buffer a Buffer containing a TLV element at offset @p offset
+   *  @param offset begin position of the TLV element within @p buffer
+   *  @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
+   *  @note This function does not throw upon decoding failure.
+   */
+  NDN_CXX_NODISCARD static std::tuple<bool, Block>
+  fromBuffer(ConstBufferPtr buffer, size_t offset = 0);
+
+  /** @brief Try to parse Block from a byte range
+   *  @param buffer sequence of bytes containing a TLV element; the element must be found at
+   *                the beginning of the buffer but does not need to span the entire buffer
+   *  @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
+   *  @note This overload copies the TLV element octets to an internal buffer.
+   *  @note This function does not throw upon decoding failure.
+   */
+  NDN_CXX_NODISCARD static std::tuple<bool, Block>
+  fromBuffer(span<const uint8_t> buffer);
+
+  /** @brief Try to parse Block from a raw buffer
+   *  @param buf pointer to the first octet of a TLV element
+   *  @param bufSize size of the raw buffer; may be greater than the actual size of the TLV element
+   *  @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
+   *  @note This overload copies the TLV element octets to an internal buffer.
+   *  @note This function does not throw upon decoding failure.
+   *  @deprecated
+   */
+  [[deprecated("use the overload that takes a span<>")]]
+  NDN_CXX_NODISCARD static std::tuple<bool, Block>
+  fromBuffer(const uint8_t* buf, size_t bufSize);
+
   /** @brief Parse Block from an input stream
    *  @throw tlv::Error TLV-LENGTH is zero or exceeds upper bound
    *  @warning If decoding fails, bytes are still consumed from the input stream.
@@ -159,25 +202,6 @@
   static Block
   fromStream(std::istream& is);
 
-  /** @brief Try to parse Block from a wire buffer
-   *  @param buffer a Buffer containing a TLV element at offset @p offset
-   *  @param offset begin position of the TLV element within @p buffer
-   *  @note This function does not throw upon decoding failure.
-   *  @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
-   */
-  NDN_CXX_NODISCARD static std::tuple<bool, Block>
-  fromBuffer(ConstBufferPtr buffer, size_t offset);
-
-  /** @brief Try to parse Block from a raw buffer
-   *  @param buf pointer to the first octet of a TLV element
-   *  @param bufSize size of the raw buffer; may be greater than the actual size of the TLV element
-   *  @note This function does not throw upon decoding failure.
-   *  @note This overload copies the TLV element octets into an internal wire buffer.
-   *  @return `true` and the parsed Block if parsing succeeds; otherwise `false` and an invalid Block
-   */
-  NDN_CXX_NODISCARD static std::tuple<bool, Block>
-  fromBuffer(const uint8_t* buf, size_t bufSize);
-
 public: // wire format
   /** @brief Check if the Block is valid
    *
diff --git a/ndn-cxx/encoding/encoder.cpp b/ndn-cxx/encoding/encoder.cpp
index 2323c26..7cc9e17 100644
--- a/ndn-cxx/encoding/encoder.cpp
+++ b/ndn-cxx/encoding/encoder.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -95,68 +95,40 @@
 }
 
 size_t
-Encoder::prependByte(uint8_t value)
+Encoder::prependBytes(span<const uint8_t> bytes)
 {
-  reserveFront(1);
-
-  m_begin--;
-  *m_begin = value;
-  return 1;
+  return prependRange(bytes.begin(), bytes.end());
 }
 
 size_t
-Encoder::appendByte(uint8_t value)
+Encoder::appendBytes(span<const uint8_t> bytes)
 {
-  reserveBack(1);
-
-  *m_end = value;
-  m_end++;
-  return 1;
-}
-
-size_t
-Encoder::prependByteArray(const uint8_t* array, size_t length)
-{
-  reserveFront(length);
-
-  m_begin -= length;
-  std::copy(array, array + length, m_begin);
-  return length;
-}
-
-size_t
-Encoder::appendByteArray(const uint8_t* array, size_t length)
-{
-  reserveBack(length);
-
-  std::copy(array, array + length, m_end);
-  m_end += length;
-  return length;
+  return appendRange(bytes.begin(), bytes.end());
 }
 
 size_t
 Encoder::prependVarNumber(uint64_t varNumber)
 {
   if (varNumber < 253) {
-    prependByte(static_cast<uint8_t>(varNumber));
+    prependBytes({static_cast<uint8_t>(varNumber)});
     return 1;
   }
   else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
     uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
-    prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
-    prependByte(253);
+    prependBytes({reinterpret_cast<const uint8_t*>(&value), 2});
+    prependBytes({253});
     return 3;
   }
   else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
     uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
-    prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
-    prependByte(254);
+    prependBytes({reinterpret_cast<const uint8_t*>(&value), 4});
+    prependBytes({254});
     return 5;
   }
   else {
     uint64_t value = endian::native_to_big(varNumber);
-    prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
-    prependByte(255);
+    prependBytes({reinterpret_cast<const uint8_t*>(&value), 8});
+    prependBytes({255});
     return 9;
   }
 }
@@ -165,25 +137,25 @@
 Encoder::appendVarNumber(uint64_t varNumber)
 {
   if (varNumber < 253) {
-    appendByte(static_cast<uint8_t>(varNumber));
+    appendBytes({static_cast<uint8_t>(varNumber)});
     return 1;
   }
   else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
-    appendByte(253);
+    appendBytes({253});
     uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
-    appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
+    appendBytes({reinterpret_cast<const uint8_t*>(&value), 2});
     return 3;
   }
   else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
-    appendByte(254);
+    appendBytes({254});
     uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
-    appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
+    appendBytes({reinterpret_cast<const uint8_t*>(&value), 4});
     return 5;
   }
   else {
-    appendByte(255);
+    appendBytes({255});
     uint64_t value = endian::native_to_big(varNumber);
-    appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
+    appendBytes({reinterpret_cast<const uint8_t*>(&value), 8});
     return 9;
   }
 }
@@ -192,19 +164,19 @@
 Encoder::prependNonNegativeInteger(uint64_t varNumber)
 {
   if (varNumber <= std::numeric_limits<uint8_t>::max()) {
-    return prependByte(static_cast<uint8_t>(varNumber));
+    return prependBytes({static_cast<uint8_t>(varNumber)});
   }
   else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
     uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
-    return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
+    return prependBytes({reinterpret_cast<const uint8_t*>(&value), 2});
   }
   else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
     uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
-    return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
+    return prependBytes({reinterpret_cast<const uint8_t*>(&value), 4});
   }
   else {
     uint64_t value = endian::native_to_big(varNumber);
-    return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
+    return prependBytes({reinterpret_cast<const uint8_t*>(&value), 8});
   }
 }
 
@@ -212,26 +184,26 @@
 Encoder::appendNonNegativeInteger(uint64_t varNumber)
 {
   if (varNumber <= std::numeric_limits<uint8_t>::max()) {
-    return appendByte(static_cast<uint8_t>(varNumber));
+    return appendBytes({static_cast<uint8_t>(varNumber)});
   }
   else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
     uint16_t value = endian::native_to_big(static_cast<uint16_t>(varNumber));
-    return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
+    return appendBytes({reinterpret_cast<const uint8_t*>(&value), 2});
   }
   else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
     uint32_t value = endian::native_to_big(static_cast<uint32_t>(varNumber));
-    return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
+    return appendBytes({reinterpret_cast<const uint8_t*>(&value), 4});
   }
   else {
     uint64_t value = endian::native_to_big(varNumber);
-    return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
+    return appendBytes({reinterpret_cast<const uint8_t*>(&value), 8});
   }
 }
 
 size_t
 Encoder::prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize)
 {
-  size_t totalLength = prependByteArray(array, arraySize);
+  size_t totalLength = prependBytes({array, arraySize});
   totalLength += prependVarNumber(arraySize);
   totalLength += prependVarNumber(type);
 
@@ -243,16 +215,18 @@
 {
   size_t totalLength = appendVarNumber(type);
   totalLength += appendVarNumber(arraySize);
-  totalLength += appendByteArray(array, arraySize);
+  totalLength += appendBytes({array, arraySize});
 
   return totalLength;
 }
 
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
 size_t
 Encoder::prependBlock(const Block& block)
 {
   if (block.hasWire()) {
-    return prependByteArray(block.wire(), block.size());
+    return prependBytes({block.wire(), block.size()});
   }
   else {
     return prependByteArrayBlock(block.type(), block.value(), block.value_size());
@@ -263,7 +237,7 @@
 Encoder::appendBlock(const Block& block)
 {
   if (block.hasWire()) {
-    return appendByteArray(block.wire(), block.size());
+    return appendBytes({block.wire(), block.size()});
   }
   else {
     return appendByteArrayBlock(block.type(), block.value(), block.value_size());
diff --git a/ndn-cxx/encoding/encoder.hpp b/ndn-cxx/encoding/encoder.hpp
index d875cbf..186ee2a 100644
--- a/ndn-cxx/encoding/encoder.hpp
+++ b/ndn-cxx/encoding/encoder.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -28,36 +28,70 @@
 namespace encoding {
 
 /**
- * @brief Helper class to perform TLV encoding
- * Interface of this class (mostly) matches interface of Estimator class
+ * @brief Helper class to perform TLV encoding.
+ *
+ * The interface of this class (mostly) matches that of the Estimator class.
+ *
  * @sa Estimator
  */
 class Encoder : noncopyable
 {
 public: // common interface between Encoder and Estimator
   /**
-   * @brief Prepend a byte
+   * @brief Prepend a sequence of bytes
    */
   size_t
-  prependByte(uint8_t value);
+  prependBytes(span<const uint8_t> bytes);
+
+  /**
+   * @brief Append a sequence of bytes
+   */
+  size_t
+  appendBytes(span<const uint8_t> bytes);
+
+  /**
+   * @brief Prepend a byte
+   * @deprecated
+   */
+  [[deprecated("use prependBytes()")]]
+  size_t
+  prependByte(uint8_t value)
+  {
+    return prependBytes({value});
+  }
 
   /**
    * @brief Append a byte
+   * @deprecated
    */
+  [[deprecated("use appendBytes()")]]
   size_t
-  appendByte(uint8_t value);
+  appendByte(uint8_t value)
+  {
+    return appendBytes({value});
+  }
 
   /**
    * @brief Prepend a byte array @p array of length @p length
+   * @deprecated
    */
+  [[deprecated("use prependBytes()")]]
   size_t
-  prependByteArray(const uint8_t* array, size_t length);
+  prependByteArray(const uint8_t* array, size_t length)
+  {
+    return prependBytes({array, length});
+  }
 
   /**
    * @brief Append a byte array @p array of length @p length
+   * @deprecated
    */
+  [[deprecated("use appendBytes()")]]
   size_t
-  appendByteArray(const uint8_t* array, size_t length);
+  appendByteArray(const uint8_t* array, size_t length)
+  {
+    return appendBytes({array, length});
+  }
 
   /**
    * @brief Prepend range of bytes from the range [@p first, @p last)
@@ -74,54 +108,62 @@
   appendRange(Iterator first, Iterator last);
 
   /**
-   * @brief Prepend VarNumber @p varNumber of NDN TLV encoding
-   * @sa http://named-data.net/doc/ndn-tlv/
+   * @brief Prepend @p number encoded as a VAR-NUMBER in NDN-TLV format
+   * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html
    */
   size_t
-  prependVarNumber(uint64_t varNumber);
+  prependVarNumber(uint64_t number);
 
   /**
-   * @brief Prepend VarNumber @p varNumber of NDN TLV encoding
-   * @sa http://named-data.net/doc/ndn-tlv/
+   * @brief Append @p number encoded as a VAR-NUMBER in NDN-TLV format
+   * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html
    */
   size_t
-  appendVarNumber(uint64_t varNumber);
+  appendVarNumber(uint64_t number);
 
   /**
-   * @brief Prepend non-negative integer @p integer of NDN TLV encoding
-   * @sa http://named-data.net/doc/ndn-tlv/
+   * @brief Prepend @p integer encoded as a NonNegativeInteger in NDN-TLV format
+   * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html
    */
   size_t
   prependNonNegativeInteger(uint64_t integer);
 
   /**
-   * @brief Append non-negative integer @p integer of NDN TLV encoding
-   * @sa http://named-data.net/doc/ndn-tlv/
+   * @brief Append @p integer encoded as a NonNegativeInteger in NDN-TLV format
+   * @sa https://named-data.net/doc/NDN-packet-spec/current/tlv.html
    */
   size_t
   appendNonNegativeInteger(uint64_t integer);
 
   /**
    * @brief Prepend TLV block of type @p type and value from buffer @p array of size @p arraySize
+   * @deprecated
    */
+  [[deprecated("use encoding::prependBinaryBlock()")]]
   size_t
   prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize);
 
   /**
    * @brief Append TLV block of type @p type and value from buffer @p array of size @p arraySize
+   * @deprecated
    */
+  [[deprecated]]
   size_t
   appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize);
 
   /**
    * @brief Prepend TLV block @p block
+   * @deprecated
    */
+  [[deprecated("use encoding::prependBlock()")]]
   size_t
   prependBlock(const Block& block);
 
   /**
    * @brief Append TLV block @p block
+   * @deprecated
    */
+  [[deprecated]]
   size_t
   appendBlock(const Block& block);
 
@@ -183,56 +225,103 @@
    * @brief Get size of the underlying buffer
    */
   size_t
-  capacity() const noexcept;
+  capacity() const noexcept
+  {
+    return m_buffer->size();
+  }
 
   /**
    * @brief Get underlying buffer
    */
   shared_ptr<Buffer>
-  getBuffer() const noexcept;
+  getBuffer() const noexcept
+  {
+    return m_buffer;
+  }
 
 public: // accessors
   /**
-   * @brief Get an iterator pointing to the first byte of the encoded buffer
+   * @brief Returns an iterator pointing to the first byte of the encoded buffer
    */
   iterator
-  begin();
+  begin() noexcept
+  {
+    return m_begin;
+  }
 
   /**
-   * @brief Get an iterator pointing to the past-the-end byte of the encoded buffer
+   * @brief Returns an iterator pointing to the first byte of the encoded buffer
+   */
+  const_iterator
+  begin() const noexcept
+  {
+    return m_begin;
+  }
+
+  /**
+   * @brief Returns an iterator pointing to the past-the-end byte of the encoded buffer
    */
   iterator
-  end();
+  end() noexcept
+  {
+    return m_end;
+  }
 
   /**
-   * @brief Get an iterator pointing to the first byte of the encoded buffer
+   * @brief Returns an iterator pointing to the past-the-end byte of the encoded buffer
    */
   const_iterator
-  begin() const;
+  end() const noexcept
+  {
+    return m_end;
+  }
 
   /**
-   * @brief Get an iterator pointing to the past-the-end byte of the encoded buffer
-   */
-  const_iterator
-  end() const;
-
-  /**
-   * @brief Get a pointer to the first byte of the encoded buffer
+   * @brief Returns a pointer to the first byte of the encoded buffer
    */
   uint8_t*
-  buf();
+  data() noexcept
+  {
+    return &*m_begin;
+  }
 
   /**
-   * @brief Get a pointer to the first byte of the encoded buffer
+   * @brief Returns a pointer to the first byte of the encoded buffer
    */
   const uint8_t*
-  buf() const;
+  data() const noexcept
+  {
+    return &*m_begin;
+  }
 
   /**
-   * @brief Get the size of the encoded buffer
+   * @deprecated
+   */
+  [[deprecated("use data()")]]
+  uint8_t*
+  buf() noexcept
+  {
+    return data();
+  }
+
+  /**
+   * @deprecated
+   */
+  [[deprecated("use data()")]]
+  const uint8_t*
+  buf() const noexcept
+  {
+    return data();
+  }
+
+  /**
+   * @brief Returns the size of the encoded buffer
    */
   size_t
-  size() const noexcept;
+  size() const noexcept
+  {
+    return static_cast<size_t>(std::distance(m_begin, m_end));
+  }
 
   /**
    * @brief Create Block from the underlying buffer
@@ -253,60 +342,6 @@
   iterator m_end;
 };
 
-inline size_t
-Encoder::size() const noexcept
-{
-  return m_end - m_begin;
-}
-
-inline shared_ptr<Buffer>
-Encoder::getBuffer() const noexcept
-{
-  return m_buffer;
-}
-
-inline size_t
-Encoder::capacity() const noexcept
-{
-  return m_buffer->size();
-}
-
-inline Buffer::iterator
-Encoder::begin()
-{
-  return m_begin;
-}
-
-inline Buffer::iterator
-Encoder::end()
-{
-  return m_end;
-}
-
-inline Buffer::const_iterator
-Encoder::begin() const
-{
-  return m_begin;
-}
-
-inline Buffer::const_iterator
-Encoder::end() const
-{
-  return m_end;
-}
-
-inline uint8_t*
-Encoder::buf()
-{
-  return &(*m_begin);
-}
-
-inline const uint8_t*
-Encoder::buf() const
-{
-  return &(*m_begin);
-}
-
 template<class Iterator>
 size_t
 Encoder::prependRange(Iterator first, Iterator last)
@@ -317,7 +352,7 @@
   size_t length = std::distance(first, last);
   reserveFront(length);
 
-  m_begin -= length;
+  std::advance(m_begin, -length);
   std::copy(first, last, m_begin);
   return length;
 }
@@ -333,7 +368,7 @@
   reserveBack(length);
 
   std::copy(first, last, m_end);
-  m_end += length;
+  std::advance(m_end, length);
   return length;
 }
 
diff --git a/ndn-cxx/encoding/estimator.cpp b/ndn-cxx/encoding/estimator.cpp
index a6d0c24..299e0f5 100644
--- a/ndn-cxx/encoding/estimator.cpp
+++ b/ndn-cxx/encoding/estimator.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -24,6 +24,8 @@
 namespace ndn {
 namespace encoding {
 
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
 size_t
 Estimator::prependBlock(const Block& block) const
 {
@@ -35,5 +37,11 @@
   }
 }
 
+size_t
+Estimator::appendBlock(const Block& block) const
+{
+  return prependBlock(block);
+}
+
 } // namespace encoding
 } // namespace ndn
diff --git a/ndn-cxx/encoding/estimator.hpp b/ndn-cxx/encoding/estimator.hpp
index 9f43c1f..ff85695 100644
--- a/ndn-cxx/encoding/estimator.hpp
+++ b/ndn-cxx/encoding/estimator.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -38,9 +38,29 @@
 {
 public: // common interface between Encoder and Estimator
   /**
-   * @brief Prepend a single byte
+   * @brief Prepend a sequence of bytes
    */
   constexpr size_t
+  prependBytes(span<const uint8_t> bytes) const noexcept
+  {
+    return bytes.size();
+  }
+
+  /**
+   * @brief Append a sequence of bytes
+   */
+  constexpr size_t
+  appendBytes(span<const uint8_t> bytes) const noexcept
+  {
+    return bytes.size();
+  }
+
+  /**
+   * @brief Prepend a single byte
+   * @deprecated
+   */
+  [[deprecated("use prependBytes()")]]
+  constexpr size_t
   prependByte(uint8_t) const noexcept
   {
     return 1;
@@ -48,7 +68,9 @@
 
   /**
    * @brief Append a single byte
+   * @deprecated
    */
+  [[deprecated("use appendBytes()")]]
   constexpr size_t
   appendByte(uint8_t) const noexcept
   {
@@ -57,7 +79,9 @@
 
   /**
    * @brief Prepend a byte array @p array of length @p length
+   * @deprecated
    */
+  [[deprecated("use prependBytes()")]]
   constexpr size_t
   prependByteArray(const uint8_t*, size_t length) const noexcept
   {
@@ -66,7 +90,9 @@
 
   /**
    * @brief Append a byte array @p array of length @p length
+   * @deprecated
    */
+  [[deprecated("use appendBytes()")]]
   constexpr size_t
   appendByteArray(const uint8_t*, size_t length) const noexcept
   {
@@ -131,7 +157,9 @@
 
   /**
    * @brief Prepend TLV block of type @p type and value from buffer @p array of size @p arraySize
+   * @deprecated
    */
+  [[deprecated("use encoding::prependBinaryBlock()")]]
   constexpr size_t
   prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize) const noexcept
   {
@@ -140,7 +168,9 @@
 
   /**
    * @brief Append TLV block of type @p type and value from buffer @p array of size @p arraySize
+   * @deprecated
    */
+  [[deprecated]]
   constexpr size_t
   appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize) const noexcept
   {
@@ -149,18 +179,19 @@
 
   /**
    * @brief Prepend TLV block @p block
+   * @deprecated
    */
+  [[deprecated("use encoding::prependBlock()")]]
   size_t
   prependBlock(const Block& block) const;
 
   /**
    * @brief Append TLV block @p block
+   * @deprecated
    */
+  [[deprecated]]
   size_t
-  appendBlock(const Block& block) const
-  {
-    return prependBlock(block);
-  }
+  appendBlock(const Block& block) const;
 };
 
 } // namespace encoding
diff --git a/ndn-cxx/face.cpp b/ndn-cxx/face.cpp
index db4d196..48f1095 100644
--- a/ndn-cxx/face.cpp
+++ b/ndn-cxx/face.cpp
@@ -314,9 +314,8 @@
   lp::Packet lpPacket(blockFromDaemon); // bare Interest/Data is a valid lp::Packet,
                                         // no need to distinguish
 
-  Buffer::const_iterator begin, end;
-  std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
-  Block netPacket(&*begin, std::distance(begin, end));
+  auto frag = lpPacket.get<lp::FragmentField>();
+  Block netPacket({frag.first, frag.second});
   switch (netPacket.type()) {
     case tlv::Interest: {
       auto interest = make_shared<Interest>(netPacket);
diff --git a/ndn-cxx/impl/name-component-types.hpp b/ndn-cxx/impl/name-component-types.hpp
index 5f224ae..0ca8bdf 100644
--- a/ndn-cxx/impl/name-component-types.hpp
+++ b/ndn-cxx/impl/name-component-types.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -55,10 +55,10 @@
    *  If \p comp is the maximum possible value of this component type, return true to indicate
    *  that the successor should have a greater TLV-TYPE.
    */
-  virtual std::pair<bool, Component>
+  virtual std::tuple<bool, Component>
   getSuccessor(const Component& comp) const
   {
-    return {false, getSuccessorImpl(comp).second};
+    return {false, std::get<Block>(getSuccessorImpl(comp))};
   }
 
   /** \brief Return the minimum allowable TLV-VALUE of this component type.
@@ -112,7 +112,7 @@
   /** \brief Calculate the successor of \p comp, extending TLV-LENGTH if value overflows.
    *  \return whether TLV-LENGTH was extended, and the successor
    */
-  std::pair<bool, Block>
+  std::tuple<bool, Block>
   getSuccessorImpl(const Component& comp) const
   {
     EncodingBuffer encoder(comp.size() + 9, 9);
@@ -122,14 +122,14 @@
     size_t i = comp.value_size();
     for (; isOverflow && i > 0; i--) {
       uint8_t newValue = static_cast<uint8_t>((comp.value()[i - 1] + 1) & 0xFF);
-      encoder.prependByte(newValue);
+      encoder.prependBytes({newValue});
       isOverflow = (newValue == 0);
     }
-    encoder.prependByteArray(comp.value(), i);
+    encoder.prependBytes({comp.value(), i});
 
     if (isOverflow) {
       // new name component has to be extended
-      encoder.appendByte(0);
+      encoder.appendBytes({0});
     }
 
     encoder.prependVarNumber(encoder.size());
@@ -206,7 +206,7 @@
     return makeBinaryBlock(m_type, value);
   }
 
-  std::pair<bool, Component>
+  std::tuple<bool, Component>
   getSuccessor(const Component& comp) const final
   {
     bool isExtended = false;
diff --git a/ndn-cxx/interest.cpp b/ndn-cxx/interest.cpp
index 66e240a..8edb092 100644
--- a/ndn-cxx/interest.cpp
+++ b/ndn-cxx/interest.cpp
@@ -90,12 +90,12 @@
 
   // ApplicationParameters and following elements (in reverse order)
   for (const auto& block : m_parameters | boost::adaptors::reversed) {
-    totalLength += encoder.prependBlock(block);
+    totalLength += prependBlock(encoder, block);
   }
 
   // HopLimit
   if (getHopLimit()) {
-    totalLength += encoder.prependByteArrayBlock(tlv::HopLimit, &*m_hopLimit, 1);
+    totalLength += prependBinaryBlock(encoder, tlv::HopLimit, {*m_hopLimit});
   }
 
   // InterestLifetime
@@ -107,7 +107,7 @@
   // Nonce
   getNonce(); // if nonce was unset, this generates a fresh nonce
   BOOST_ASSERT(hasNonce());
-  totalLength += encoder.prependByteArrayBlock(tlv::Nonce, m_nonce->data(), m_nonce->size());
+  totalLength += prependBinaryBlock(encoder, tlv::Nonce, *m_nonce);
 
   // ForwardingHint
   if (!m_forwardingHint.empty()) {
@@ -494,7 +494,7 @@
 Interest&
 Interest::setApplicationParameters(span<const uint8_t> value)
 {
-  setApplicationParametersInternal(makeBinaryBlock(tlv::ApplicationParameters, value.data(), value.size()));
+  setApplicationParametersInternal(makeBinaryBlock(tlv::ApplicationParameters, value));
   addOrReplaceParametersDigestComponent();
   m_wire.reset();
   return *this;
diff --git a/ndn-cxx/key-locator.cpp b/ndn-cxx/key-locator.cpp
index 6cf24ac..0d35dc9 100644
--- a/ndn-cxx/key-locator.cpp
+++ b/ndn-cxx/key-locator.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -59,7 +59,7 @@
   auto visitor = overload(
     []  (monostate)           {}, // nothing to encode, TLV-VALUE is empty
     [&] (const Name& name)    { totalLength += name.wireEncode(encoder); },
-    [&] (const Block& digest) { totalLength += encoder.prependBlock(digest); },
+    [&] (const Block& digest) { totalLength += prependBlock(encoder, digest); },
     []  (uint32_t type)       { NDN_THROW(Error("Unsupported KeyLocator type " + to_string(type))); });
   visit(visitor, m_locator);
 
diff --git a/ndn-cxx/lp/cache-policy.cpp b/ndn-cxx/lp/cache-policy.cpp
index b4f4d82..c64bd04 100644
--- a/ndn-cxx/lp/cache-policy.cpp
+++ b/ndn-cxx/lp/cache-policy.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -57,7 +57,7 @@
   }
 
   size_t length = 0;
-  length += prependNonNegativeIntegerBlock(encoder, tlv::CachePolicyType, static_cast<uint32_t>(m_policy));
+  length += prependNonNegativeIntegerBlock(encoder, tlv::CachePolicyType, static_cast<uint64_t>(m_policy));
   length += encoder.prependVarNumber(length);
   length += encoder.prependVarNumber(tlv::CachePolicy);
   return length;
@@ -103,8 +103,8 @@
   }
 
   if (it->type() == tlv::CachePolicyType) {
-    m_policy = static_cast<CachePolicyType>(readNonNegativeInteger(*it));
-    if (this->getPolicy() == CachePolicyType::NONE) {
+    m_policy = readNonNegativeIntegerAs<CachePolicyType>(*it);
+    if (getPolicy() == CachePolicyType::NONE) {
       NDN_THROW(Error("Unknown CachePolicyType"));
     }
   }
diff --git a/ndn-cxx/lp/field-decl.hpp b/ndn-cxx/lp/field-decl.hpp
index 627ae13..1cb74ef 100644
--- a/ndn-cxx/lp/field-decl.hpp
+++ b/ndn-cxx/lp/field-decl.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -121,12 +121,9 @@
 struct EncodeHelper<TAG, TlvType, EmptyValue>
 {
   static size_t
-  encode(EncodingImpl<TAG>& encoder, const EmptyValue value)
+  encode(EncodingImpl<TAG>& encoder, EmptyValue)
   {
-    size_t length = 0;
-    length += encoder.prependVarNumber(0);
-    length += encoder.prependVarNumber(TlvType::value);
-    return length;
+    return prependEmptyBlock(encoder, TlvType::value);
   }
 };
 
@@ -147,8 +144,8 @@
   encode(EncodingImpl<TAG>& encoder, uint64_t value)
   {
     boost::endian::native_to_big_inplace(value);
-    return encoder.prependByteArrayBlock(TlvType::value,
-                                         reinterpret_cast<const uint8_t*>(&value), sizeof(value));
+    return prependBinaryBlock(encoder, TlvType::value,
+                              {reinterpret_cast<const uint8_t*>(&value), sizeof(value)});
   }
 };
 
diff --git a/ndn-cxx/lp/nack-header.cpp b/ndn-cxx/lp/nack-header.cpp
index b3053be..ab1cc86 100644
--- a/ndn-cxx/lp/nack-header.cpp
+++ b/ndn-cxx/lp/nack-header.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -69,7 +69,7 @@
 NackHeader::wireEncode(EncodingImpl<TAG>& encoder) const
 {
   size_t length = 0;
-  length += prependNonNegativeIntegerBlock(encoder, tlv::NackReason, static_cast<uint32_t>(m_reason));
+  length += prependNonNegativeIntegerBlock(encoder, tlv::NackReason, static_cast<uint64_t>(m_reason));
   length += encoder.prependVarNumber(length);
   length += encoder.prependVarNumber(tlv::Nack);
   return length;
@@ -107,10 +107,9 @@
   m_reason = NackReason::NONE;
 
   if (m_wire.elements_size() > 0) {
-    Block::element_const_iterator it = m_wire.elements_begin();
-
+    auto it = m_wire.elements_begin();
     if (it->type() == tlv::NackReason) {
-      m_reason = static_cast<NackReason>(readNonNegativeInteger(*it));
+      m_reason = readNonNegativeIntegerAs<NackReason>(*it);
     }
     else {
       NDN_THROW(ndn::tlv::Error("NackReason", it->type()));
diff --git a/ndn-cxx/meta-info.cpp b/ndn-cxx/meta-info.cpp
index 4315fc8..2d64691 100644
--- a/ndn-cxx/meta-info.cpp
+++ b/ndn-cxx/meta-info.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -21,7 +21,8 @@
 
 #include "ndn-cxx/meta-info.hpp"
 #include "ndn-cxx/encoding/block-helpers.hpp"
-#include "ndn-cxx/encoding/encoding-buffer.hpp"
+
+#include <boost/range/adaptor/reversed.hpp>
 
 namespace ndn {
 
@@ -132,8 +133,9 @@
 
   size_t totalLength = 0;
 
-  for (auto it = m_appMetaInfo.rbegin(); it != m_appMetaInfo.rend(); ++it) {
-    totalLength += encoder.prependBlock(*it);
+  // AppMetaInfo (in reverse order)
+  for (const auto& block : m_appMetaInfo | boost::adaptors::reversed) {
+    totalLength += prependBlock(encoder, block);
   }
 
   // FinalBlockId
@@ -181,11 +183,11 @@
   m_wire = wire;
   m_wire.parse();
 
-  // MetaInfo ::= META-INFO-TYPE TLV-LENGTH
-  //                ContentType?
-  //                FreshnessPeriod?
-  //                FinalBlockId?
-  //                AppMetaInfo*
+  // MetaInfo = META-INFO-TYPE TLV-LENGTH
+  //              [ContentType]
+  //              [FreshnessPeriod]
+  //              [FinalBlockId]
+  //              *AppMetaInfo
 
   auto val = m_wire.elements_begin();
 
diff --git a/ndn-cxx/name-component.cpp b/ndn-cxx/name-component.cpp
index 23f0060..61c3afe 100644
--- a/ndn-cxx/name-component.cpp
+++ b/ndn-cxx/name-component.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -366,16 +366,15 @@
 Component::fromNumberWithMarker(uint8_t marker, uint64_t number)
 {
   EncodingEstimator estimator;
-
   size_t valueLength = estimator.prependNonNegativeInteger(number);
-  valueLength += estimator.prependByteArray(&marker, 1);
+  valueLength += estimator.prependBytes({marker});
   size_t totalLength = valueLength;
   totalLength += estimator.prependVarNumber(valueLength);
   totalLength += estimator.prependVarNumber(tlv::GenericNameComponent);
 
   EncodingBuffer encoder(totalLength, 0);
   encoder.prependNonNegativeInteger(number);
-  encoder.prependByteArray(&marker, 1);
+  encoder.prependBytes({marker});
   encoder.prependVarNumber(valueLength);
   encoder.prependVarNumber(tlv::GenericNameComponent);
 
@@ -523,7 +522,7 @@
 {
   size_t totalLength = 0;
   if (value_size() > 0)
-    totalLength += encoder.prependByteArray(value(), value_size());
+    totalLength += encoder.prependBytes({value(), value_size()});
   totalLength += encoder.prependVarNumber(value_size());
   totalLength += encoder.prependVarNumber(type());
   return totalLength;
diff --git a/ndn-cxx/security/detail/certificate-bundle-decoder.cpp b/ndn-cxx/security/detail/certificate-bundle-decoder.cpp
index 19fba7f..83f94e1 100644
--- a/ndn-cxx/security/detail/certificate-bundle-decoder.cpp
+++ b/ndn-cxx/security/detail/certificate-bundle-decoder.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -45,7 +45,7 @@
   while (!m_bufferedData.empty()) {
     bool isOk;
     Block element;
-    std::tie(isOk, element) = Block::fromBuffer(m_bufferedData.data(), m_bufferedData.size());
+    std::tie(isOk, element) = Block::fromBuffer(m_bufferedData);
     if (!isOk) {
       return;
     }
diff --git a/ndn-cxx/security/key-chain.cpp b/ndn-cxx/security/key-chain.cpp
index 0b55c91..07828cb 100644
--- a/ndn-cxx/security/key-chain.cpp
+++ b/ndn-cxx/security/key-chain.cpp
@@ -450,10 +450,8 @@
   EncodingBuffer encoder;
   data.wireEncode(encoder, true);
 
-  Block sigValue(tlv::SignatureValue,
-                 sign({{encoder.buf(), encoder.size()}}, keyName, params.getDigestAlgorithm()));
-
-  data.wireEncode(encoder, sigValue);
+  auto sigValue = sign({encoder}, keyName, params.getDigestAlgorithm());
+  data.wireEncode(encoder, *sigValue);
 }
 
 void
diff --git a/ndn-cxx/security/safe-bag.cpp b/ndn-cxx/security/safe-bag.cpp
index 7612e45..b538d02 100644
--- a/ndn-cxx/security/safe-bag.cpp
+++ b/ndn-cxx/security/safe-bag.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -60,16 +60,13 @@
   size_t totalLength = 0;
 
   // EncryptedKey
-  totalLength += encoder.prependByteArrayBlock(tlv::security::EncryptedKey,
-                                               m_encryptedKey.data(),
-                                               m_encryptedKey.size());
+  totalLength += prependBinaryBlock(encoder, tlv::security::EncryptedKey, m_encryptedKey);
 
   // Certificate
-  totalLength += this->m_certificate.wireEncode(encoder);
+  totalLength += m_certificate.wireEncode(encoder);
 
   totalLength += encoder.prependVarNumber(totalLength);
   totalLength += encoder.prependVarNumber(tlv::security::SafeBag);
-
   return totalLength;
 }
 
diff --git a/ndn-cxx/signature-info.cpp b/ndn-cxx/signature-info.cpp
index 7c84ae3..fb062d4 100644
--- a/ndn-cxx/signature-info.cpp
+++ b/ndn-cxx/signature-info.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -75,7 +75,7 @@
   // m_otherTlvs contains (if set) SignatureNonce, SignatureTime, SignatureSeqNum, ValidityPeriod,
   // and AdditionalDescription, as well as any custom elements added by the user
   for (const auto& block : m_otherTlvs | boost::adaptors::reversed) {
-    totalLength += encoder.prependBlock(block);
+    totalLength += prependBlock(encoder, block);
   }
 
   if (m_keyLocator) {
@@ -92,10 +92,10 @@
 }
 
 template size_t
-SignatureInfo::wireEncode<encoding::EncoderTag>(encoding::EncodingBuffer&, SignatureInfo::Type) const;
+SignatureInfo::wireEncode<encoding::EncoderTag>(EncodingBuffer&, SignatureInfo::Type) const;
 
 template size_t
-SignatureInfo::wireEncode<encoding::EstimatorTag>(encoding::EncodingEstimator&, SignatureInfo::Type) const;
+SignatureInfo::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, SignatureInfo::Type) const;
 
 const Block&
 SignatureInfo::wireEncode(SignatureInfo::Type type) const
@@ -266,7 +266,8 @@
     removeCustomTlv(tlv::SignatureTime);
   }
   else {
-    addCustomTlv(makeNonNegativeIntegerBlock(tlv::SignatureTime, time::toUnixTimestamp(*time).count()));
+    addCustomTlv(makeNonNegativeIntegerBlock(tlv::SignatureTime,
+                                             static_cast<uint64_t>(time::toUnixTimestamp(*time).count())));
   }
   return *this;
 }
@@ -366,7 +367,7 @@
         case tlv::SignatureNonce: {
           os << "Nonce=";
           auto nonce = *info.getNonce();
-          printHex(os, nonce.data(), nonce.size(), false);
+          printHex(os, nonce, false);
           os << " ";
           break;
         }
diff --git a/ndn-cxx/signature-info.hpp b/ndn-cxx/signature-info.hpp
index b1dfecc..87f5531 100644
--- a/ndn-cxx/signature-info.hpp
+++ b/ndn-cxx/signature-info.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -237,11 +237,13 @@
   operator<<(std::ostream& os, const SignatureInfo& info);
 };
 
+#ifndef DOXYGEN
 extern template size_t
 SignatureInfo::wireEncode<encoding::EncoderTag>(EncodingBuffer&, SignatureInfo::Type) const;
 
 extern template size_t
 SignatureInfo::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, SignatureInfo::Type) const;
+#endif
 
 bool
 operator==(const SignatureInfo& lhs, const SignatureInfo& rhs);
diff --git a/ndn-cxx/transport/detail/stream-transport-impl.hpp b/ndn-cxx/transport/detail/stream-transport-impl.hpp
index 68646d6..f11a622 100644
--- a/ndn-cxx/transport/detail/stream-transport-impl.hpp
+++ b/ndn-cxx/transport/detail/stream-transport-impl.hpp
@@ -231,7 +231,7 @@
     while (offset < nBytesAvailable) {
       bool isOk = false;
       Block element;
-      std::tie(isOk, element) = Block::fromBuffer(buffer + offset, nBytesAvailable - offset);
+      std::tie(isOk, element) = Block::fromBuffer({buffer + offset, nBytesAvailable - offset});
       if (!isOk)
         return false;
 
diff --git a/ndn-cxx/util/dummy-client-face.cpp b/ndn-cxx/util/dummy-client-face.cpp
index 017bb76..8079353 100644
--- a/ndn-cxx/util/dummy-client-face.cpp
+++ b/ndn-cxx/util/dummy-client-face.cpp
@@ -117,19 +117,16 @@
 void
 DummyClientFace::construct(const Options& options)
 {
-  static_pointer_cast<Transport>(getTransport())->onSendBlock.connect([this] (const Block& blockFromDaemon) {
-    Block packet(blockFromDaemon);
+  static_pointer_cast<Transport>(getTransport())->onSendBlock.connect([this] (Block packet) {
     packet.encode();
     lp::Packet lpPacket(packet);
-
-    Buffer::const_iterator begin, end;
-    std::tie(begin, end) = lpPacket.get<lp::FragmentField>();
-    Block block(&*begin, std::distance(begin, end));
+    auto frag = lpPacket.get<lp::FragmentField>();
+    Block block({frag.first, frag.second});
 
     if (block.type() == tlv::Interest) {
-      shared_ptr<Interest> interest = make_shared<Interest>(block);
+      auto interest = make_shared<Interest>(block);
       if (lpPacket.has<lp::NackField>()) {
-        shared_ptr<lp::Nack> nack = make_shared<lp::Nack>(std::move(*interest));
+        auto nack = make_shared<lp::Nack>(std::move(*interest));
         nack->setHeader(lpPacket.get<lp::NackField>());
         addTagFromField<lp::CongestionMarkTag, lp::CongestionMarkField>(*nack, lpPacket);
         onSendNack(*nack);
@@ -141,7 +138,7 @@
       }
     }
     else if (block.type() == tlv::Data) {
-      shared_ptr<Data> data = make_shared<Data>(block);
+      auto data = make_shared<Data>(block);
       addTagFromField<lp::CachePolicyTag, lp::CachePolicyField>(*data, lpPacket);
       addTagFromField<lp::CongestionMarkTag, lp::CongestionMarkField>(*data, lpPacket);
       onSendData(*data);
diff --git a/ndn-cxx/util/io.cpp b/ndn-cxx/util/io.cpp
index e3277fe..663c4e0 100644
--- a/ndn-cxx/util/io.cpp
+++ b/ndn-cxx/util/io.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -60,21 +60,20 @@
 }
 
 void
-saveBuffer(const uint8_t* buf, size_t size, std::ostream& os, IoEncoding encoding)
+saveBuffer(span<const uint8_t> buf, std::ostream& os, IoEncoding encoding)
 {
   namespace t = ndn::security::transform;
 
-  auto src = make_span(buf, size);
   try {
     switch (encoding) {
       case NO_ENCODING:
-        t::bufferSource(src) >> t::streamSink(os);
+        t::bufferSource(buf) >> t::streamSink(os);
         return;
       case BASE64:
-        t::bufferSource(src) >> t::base64Encode() >> t::streamSink(os);
+        t::bufferSource(buf) >> t::base64Encode() >> t::streamSink(os);
         return;
       case HEX:
-        t::bufferSource(src) >> t::hexEncode(true) >> t::streamSink(os);
+        t::bufferSource(buf) >> t::hexEncode(true) >> t::streamSink(os);
         return;
     }
   }
diff --git a/ndn-cxx/util/io.hpp b/ndn-cxx/util/io.hpp
index 7a2afd6..5d80ede 100644
--- a/ndn-cxx/util/io.hpp
+++ b/ndn-cxx/util/io.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -156,12 +156,13 @@
   return load<T>(is, encoding);
 }
 
-/** \brief Writes a byte buffer to a stream.
- *  \throw Error error during saving
- *  \throw std::invalid_argument the specified encoding is not supported
+/**
+ * \brief Writes a sequence of bytes to a stream.
+ * \throw Error error during saving
+ * \throw std::invalid_argument the specified encoding is not supported
  */
 void
-saveBuffer(const uint8_t* buf, size_t size, std::ostream& os, IoEncoding encoding = BASE64);
+saveBuffer(span<const uint8_t> buf, std::ostream& os, IoEncoding encoding = BASE64);
 
 /** \brief Writes a TLV element to a stream.
  *  \tparam T type of TLV element; `T` must be WireEncodable and the nested type
@@ -184,7 +185,7 @@
     NDN_THROW_NESTED(Error("Encode error during save: "s + e.what()));
   }
 
-  saveBuffer(block.wire(), block.size(), os, encoding);
+  saveBuffer({block.wire(), block.size()}, os, encoding);
 }
 
 /** \brief Writes a TLV element to a file.
diff --git a/ndn-cxx/util/sqlite3-statement.cpp b/ndn-cxx/util/sqlite3-statement.cpp
index 4426a02..709ea51 100644
--- a/ndn-cxx/util/sqlite3-statement.cpp
+++ b/ndn-cxx/util/sqlite3-statement.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -47,7 +47,7 @@
 int
 Sqlite3Statement::bind(int index, const std::string& value, void(*destructor)(void*))
 {
-  return sqlite3_bind_text(m_stmt, index, value.c_str(), value.size(), destructor);
+  return sqlite3_bind_text(m_stmt, index, value.data(), value.size(), destructor);
 }
 
 int
@@ -78,8 +78,8 @@
 Block
 Sqlite3Statement::getBlock(int column)
 {
-  return Block(reinterpret_cast<const uint8_t*>(sqlite3_column_blob(m_stmt, column)),
-               sqlite3_column_bytes(m_stmt, column));
+  return Block(make_span(reinterpret_cast<const uint8_t*>(sqlite3_column_blob(m_stmt, column)),
+                         sqlite3_column_bytes(m_stmt, column)));
 }
 
 int
@@ -88,7 +88,6 @@
   return sqlite3_column_int(m_stmt, column);
 }
 
-
 const uint8_t*
 Sqlite3Statement::getBlob(int column)
 {
diff --git a/tests/unit/data.t.cpp b/tests/unit/data.t.cpp
index 2ab660e..153c471 100644
--- a/tests/unit/data.t.cpp
+++ b/tests/unit/data.t.cpp
@@ -284,7 +284,7 @@
 
 BOOST_AUTO_TEST_CASE(Full)
 {
-  d.wireDecode(Block(DATA1, sizeof(DATA1)));
+  d.wireDecode(Block(DATA1));
   BOOST_CHECK_EQUAL(d.getName(), "/local/ndn/prefix");
   BOOST_CHECK_EQUAL(d.getContentType(), tlv::ContentType_Blob);
   BOOST_CHECK_EQUAL(d.getFreshnessPeriod(), 10_s);
@@ -415,7 +415,7 @@
   d.setFreshnessPeriod(100_s); // invalidates FullName
   BOOST_CHECK_THROW(d.getFullName(), Data::Error);
 
-  Data d1(Block(DATA1, sizeof(DATA1)));
+  Data d1(Block{DATA1});
   BOOST_CHECK_EQUAL(d1.getFullName(),
     "/local/ndn/prefix/"
     "sha256digest=28bad4b5275bd392dbb670c75cf0b66f13f7942b21e80f55c0e86b374753a548");
@@ -518,7 +518,7 @@
 
   // Block overload, nested inside Content element
   const uint8_t nested[] = {0x99, 0x02, 0xca, 0xfe};
-  d.setContent(Block(nested, sizeof(nested)));
+  d.setContent(Block(nested));
   BOOST_CHECK_EQUAL(d.hasContent(), true);
   BOOST_CHECK_EQUAL(d.getContent().type(), tlv::Content);
   BOOST_CHECK_EQUAL_COLLECTIONS(d.getContent().value_begin(), d.getContent().value_end(),
@@ -597,8 +597,7 @@
           0x17, 0x00, // SignatureValue
           0xAA, 0x00 // Unrecognized non-critical element
   };
-  Block wire2(WIRE, sizeof(WIRE));
-  Data d2(wire2);
+  Data d2(Block{WIRE});
   auto ranges2 = d2.extractSignedRanges();
   BOOST_REQUIRE_EQUAL(ranges2.size(), 1);
   BOOST_CHECK_EQUAL_COLLECTIONS(ranges2.front().begin(), ranges2.front().end(), &WIRE[2], &WIRE[9]);
@@ -651,7 +650,7 @@
 
 BOOST_AUTO_TEST_CASE(Print)
 {
-  Data d1(Block(DATA1, sizeof(DATA1)));
+  Data d1(Block{DATA1});
   BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(d1),
                     "Name: /local/ndn/prefix\n"
                     "MetaInfo: [ContentType: 0, FreshnessPeriod: 10000 milliseconds]\n"
diff --git a/tests/unit/encoding/block-helpers.t.cpp b/tests/unit/encoding/block-helpers.t.cpp
index 2ca1e02..9325851 100644
--- a/tests/unit/encoding/block-helpers.t.cpp
+++ b/tests/unit/encoding/block-helpers.t.cpp
@@ -108,18 +108,43 @@
   std::list<uint8_t> buf3{1, 1, 1, 1};
 
   Block b1 = makeBinaryBlock(100, buf1.data(), buf1.size()); // char* overload
-  Block b2 = makeBinaryBlock(100, buf2, sizeof(buf2));       // uint8_t* overload
-  Block b3 = makeBinaryBlock(100, buf2);                     // span overload
-  Block b4 = makeBinaryBlock(100, buf1.begin(), buf1.end()); // fast encoding (random access iterator)
-  Block b5 = makeBinaryBlock(100, buf3.begin(), buf3.end()); // slow encoding (general iterator)
+  Block b2 = makeBinaryBlock(100, buf2);                     // span overload
+  Block b3 = makeBinaryBlock(100, buf1.begin(), buf1.end()); // fast encoding (random access iterator)
+  Block b4 = makeBinaryBlock(100, buf3.begin(), buf3.end()); // slow encoding (general iterator)
 
   BOOST_CHECK_EQUAL(b1, b2);
   BOOST_CHECK_EQUAL(b1, b3);
   BOOST_CHECK_EQUAL(b1, b4);
-  BOOST_CHECK_EQUAL(b1, b5);
   BOOST_CHECK_EQUAL(b1.type(), 100);
   BOOST_CHECK_EQUAL(b1.value_size(), buf1.size());
   BOOST_CHECK_EQUAL_COLLECTIONS(b1.value_begin(), b1.value_end(), buf2, buf2 + sizeof(buf2));
+
+  EncodingEstimator estimator;
+  size_t length = prependBinaryBlock(estimator, 100, buf2);
+  BOOST_CHECK_EQUAL(length, 6);
+
+  EncodingBuffer encoder(length, 0);
+  BOOST_CHECK_EQUAL(prependBinaryBlock(encoder, 100, buf2), 6);
+  BOOST_CHECK_EQUAL(encoder.block(), b1);
+}
+
+BOOST_AUTO_TEST_CASE(PrependBlock)
+{
+  EncodingEstimator estimator;
+  Block b1({0x01, 0x03, 0x00, 0x00, 0x00});
+  size_t length = prependBlock(estimator, b1);
+  BOOST_CHECK_EQUAL(length, 5);
+  Block b2(100, b1);
+  length += prependBlock(estimator, b2);
+  BOOST_CHECK_EQUAL(length, 12);
+
+  EncodingBuffer encoder(length, 0);
+  BOOST_CHECK_EQUAL(prependBlock(encoder, b1), 5);
+  BOOST_CHECK_EQUAL(prependBlock(encoder, b2), 7);
+  BOOST_CHECK_EQUAL(encoder.size(), 12);
+  encoder.prependVarNumber(encoder.size());
+  encoder.prependVarNumber(200);
+  BOOST_CHECK_EQUAL(encoder.block(), "C80C 64050103000000 0103000000"_block);
 }
 
 BOOST_AUTO_TEST_CASE(Nested)
diff --git a/tests/unit/encoding/block.t.cpp b/tests/unit/encoding/block.t.cpp
index b6a841b..a39df87 100644
--- a/tests/unit/encoding/block.t.cpp
+++ b/tests/unit/encoding/block.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -68,7 +68,7 @@
   BOOST_CHECK_THROW(Block{encoder}, tlv::Error);
 
   const uint8_t VALUE[] = {0x11, 0x12, 0x13, 0x14};
-  size_t length = encoder.prependByteArray(VALUE, sizeof(VALUE));
+  size_t length = encoder.prependBytes(VALUE);
   encoder.prependVarNumber(length);
   encoder.prependVarNumber(0xe0);
 
@@ -87,18 +87,18 @@
 
 BOOST_AUTO_TEST_CASE(FromBlock)
 {
-  const uint8_t BUFFER[] = {0x80, 0x06, 0x81, 0x01, 0x01, 0x82, 0x01, 0x01};
-  Block block(BUFFER, sizeof(BUFFER));
+  const uint8_t buf[] = {0x80, 0x06, 0x81, 0x01, 0x01, 0x82, 0x01, 0x01};
+  Block block(buf);
 
   Block derivedBlock(block, block.begin(), block.end());
   BOOST_CHECK_EQUAL(derivedBlock.wire(), block.wire()); // pointers should match
-  BOOST_CHECK(derivedBlock == block); // blocks should match
+  BOOST_CHECK_EQUAL(derivedBlock, block); // blocks should match
 
   derivedBlock = Block(block, block.begin() + 2, block.begin() + 5);
   BOOST_CHECK(derivedBlock.begin() == block.begin() + 2);
-  BOOST_CHECK(derivedBlock == Block(BUFFER + 2, 3));
+  BOOST_CHECK_EQUAL(derivedBlock, Block(make_span(buf + 2, 3)));
 
-  Buffer otherBuffer(BUFFER, sizeof(BUFFER));
+  Buffer otherBuffer(buf, sizeof(buf));
   BOOST_CHECK_THROW(Block(block, otherBuffer.begin(), block.end()), std::invalid_argument);
   BOOST_CHECK_THROW(Block(block, block.begin(), otherBuffer.end()), std::invalid_argument);
   BOOST_CHECK_THROW(Block(block, otherBuffer.begin(), otherBuffer.end()), std::invalid_argument);
@@ -106,11 +106,11 @@
 
 BOOST_AUTO_TEST_CASE(FromBlockCopyOnWriteModifyOriginal)
 {
-  const uint8_t BUFFER[] = {
+  const uint8_t buf[] = {
     0x05, 0x0b, 0x07, 0x03, 0x01, 0x02, 0x03, 0x0a, 0x04, 0x04, 0x05, 0x06, 0x07,
   };
 
-  Block b1(BUFFER, sizeof(BUFFER));
+  Block b1(buf);
 
   Block b2(b1, b1.begin(), b1.end());
   auto buf2 = b2.getBuffer();
@@ -121,17 +121,17 @@
 
   b2.parse();
 
-  BOOST_CHECK_EQUAL_COLLECTIONS(b2.begin(), b2.end(), BUFFER, BUFFER + sizeof(BUFFER));
+  BOOST_CHECK_EQUAL_COLLECTIONS(b2.begin(), b2.end(), buf, buf + sizeof(buf));
   BOOST_CHECK_EQUAL(buf2, b2.getBuffer());
 }
 
 BOOST_AUTO_TEST_CASE(FromBlockCopyOnWriteModifyCopy)
 {
-  const uint8_t BUFFER[] = {
+  const uint8_t buf[] = {
     0x05, 0x0b, 0x07, 0x03, 0x01, 0x02, 0x03, 0x0a, 0x04, 0x04, 0x05, 0x06, 0x07,
   };
 
-  Block b1(BUFFER, sizeof(BUFFER));
+  Block b1(buf);
   auto buf1 = b1.getBuffer();
 
   Block b2(b1, b1.begin(), b1.end());
@@ -141,7 +141,7 @@
   b2.encode();
 
   b1.parse();
-  BOOST_CHECK_EQUAL_COLLECTIONS(b1.begin(), b1.end(), BUFFER, BUFFER + sizeof(BUFFER));
+  BOOST_CHECK_EQUAL_COLLECTIONS(b1.begin(), b1.end(), buf, buf + sizeof(buf));
   BOOST_CHECK_EQUAL(buf1, b1.getBuffer());
 }
 
@@ -177,7 +177,7 @@
 BOOST_AUTO_TEST_CASE(FromTypeAndBuffer)
 {
   const uint8_t VALUE[] = {0x11, 0x12, 0x13, 0x14};
-  auto bufferPtr = make_shared<Buffer>(VALUE, sizeof(VALUE));
+  auto bufferPtr = std::make_shared<Buffer>(VALUE, sizeof(VALUE));
 
   Block b1(42, std::move(bufferPtr));
   BOOST_CHECK_EQUAL(b1.isValid(), true);
@@ -188,7 +188,7 @@
   BOOST_CHECK(b1.value() != nullptr);
 
   // empty buffer as TLV-VALUE
-  Block b2(63, make_shared<Buffer>());
+  Block b2(63, std::make_shared<Buffer>());
   BOOST_CHECK_EQUAL(b2.isValid(), true);
   BOOST_CHECK_EQUAL(b2.type(), 63);
   BOOST_CHECK_EQUAL(b2.size(), 2);
@@ -199,15 +199,15 @@
 
 BOOST_AUTO_TEST_CASE(FromTypeAndBlock)
 {
-  const uint8_t BUFFER[] = {0x80, 0x06, 0x81, 0x01, 0x01, 0x82, 0x01, 0x01};
-  Block nested(BUFFER, sizeof(BUFFER));
+  const uint8_t buf[] = {0x80, 0x06, 0x81, 0x01, 0x01, 0x82, 0x01, 0x01};
+  Block nested(buf);
 
   Block b(84, nested);
   BOOST_CHECK_EQUAL(b.isValid(), true);
   BOOST_CHECK_EQUAL(b.type(), 84);
   BOOST_CHECK_EQUAL(b.size(), 10);
   BOOST_CHECK_EQUAL(b.hasValue(), true);
-  BOOST_CHECK_EQUAL(b.value_size(), sizeof(BUFFER));
+  BOOST_CHECK_EQUAL(b.value_size(), sizeof(buf));
   BOOST_CHECK(b.value() != nullptr);
 }
 
@@ -322,19 +322,18 @@
 
 BOOST_AUTO_TEST_CASE(FromWireBuffer)
 {
-  auto buffer = make_shared<Buffer>(TEST_BUFFER, sizeof(TEST_BUFFER));
+  auto buffer = std::make_shared<Buffer>(TEST_BUFFER, sizeof(TEST_BUFFER));
 
-  size_t offset = 0;
   bool isOk = false;
   Block b;
-  std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
+  std::tie(isOk, b) = Block::fromBuffer(buffer);
   BOOST_CHECK(isOk);
   BOOST_CHECK_EQUAL(b.type(), 66);
   BOOST_CHECK_EQUAL(b.size(), 3);
   BOOST_CHECK_EQUAL(b.value_size(), 1);
   BOOST_CHECK_EQUAL(*b.wire(),  0x42);
   BOOST_CHECK_EQUAL(*b.value(), 0xfa);
-  offset += b.size();
+  size_t offset = b.size();
 
   std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
   BOOST_CHECK(isOk);
@@ -356,19 +355,18 @@
 
 BOOST_AUTO_TEST_CASE(FromRawBuffer)
 {
-  size_t offset = 0;
   bool isOk = false;
   Block b;
-  std::tie(isOk, b) = Block::fromBuffer(TEST_BUFFER + offset, sizeof(TEST_BUFFER) - offset);
+  std::tie(isOk, b) = Block::fromBuffer(TEST_BUFFER);
   BOOST_CHECK(isOk);
   BOOST_CHECK_EQUAL(b.type(), 66);
   BOOST_CHECK_EQUAL(b.size(), 3);
   BOOST_CHECK_EQUAL(b.value_size(), 1);
   BOOST_CHECK_EQUAL(*b.wire(),  0x42);
   BOOST_CHECK_EQUAL(*b.value(), 0xfa);
-  offset += b.size();
+  auto offset = b.size();
 
-  std::tie(isOk, b) = Block::fromBuffer(TEST_BUFFER + offset, sizeof(TEST_BUFFER) - offset);
+  std::tie(isOk, b) = Block::fromBuffer(make_span(TEST_BUFFER).subspan(offset));
   BOOST_CHECK(isOk);
   BOOST_CHECK_EQUAL(b.type(), 1);
   BOOST_CHECK_EQUAL(b.size(), 3);
@@ -377,7 +375,7 @@
   BOOST_CHECK_EQUAL(*b.value(), 0xfb);
   offset += b.size();
 
-  std::tie(isOk, b) = Block::fromBuffer(TEST_BUFFER + offset, sizeof(TEST_BUFFER) - offset);
+  std::tie(isOk, b) = Block::fromBuffer(make_span(TEST_BUFFER).subspan(offset));
   BOOST_CHECK(isOk);
   BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
   BOOST_CHECK_EQUAL(b.size(), 6);
@@ -395,8 +393,8 @@
 
 BOOST_DATA_TEST_CASE(Malformed, MalformedInputs)
 {
-  // constructor from raw buffer
-  BOOST_CHECK_THROW(Block(sample.data(), sample.size()), tlv::Error);
+  // constructor from span
+  BOOST_CHECK_THROW(Block{sample}, tlv::Error);
 
   // fromStream()
   std::stringstream stream;
@@ -405,15 +403,15 @@
   BOOST_CHECK_THROW(Block::fromStream(stream), tlv::Error);
 
   // fromBuffer(), ConstBufferPtr overload
-  auto buf = make_shared<Buffer>(sample.begin(), sample.end());
+  auto buf = std::make_shared<Buffer>(sample.begin(), sample.end());
   bool isOk;
   Block b;
-  std::tie(isOk, b) = Block::fromBuffer(buf, 0);
+  std::tie(isOk, b) = Block::fromBuffer(buf);
   BOOST_CHECK(!isOk);
   BOOST_CHECK(!b.isValid());
 
-  // fromBuffer(), raw buffer overload
-  std::tie(isOk, b) = Block::fromBuffer(sample.data(), sample.size());
+  // fromBuffer(), span overload
+  std::tie(isOk, b) = Block::fromBuffer(sample);
   BOOST_CHECK(!isOk);
   BOOST_CHECK(!b.isValid());
 }
@@ -427,7 +425,7 @@
     return e.what() == "Cannot construct block from empty TLV-VALUE"s;
   });
 
-  Block b2(302, make_shared<Buffer>());
+  Block b2(302, std::make_shared<Buffer>());
   BOOST_CHECK_EXCEPTION(b2.blockFromValue(), Block::Error, [] (const auto& e) {
     return e.what() == "Cannot construct block from empty TLV-VALUE"s;
   });
@@ -459,7 +457,7 @@
                 0x1c, 0x00, // KeyLocator empty
           0x17, 0x00 // SignatureValue empty
   };
-  Block data(PACKET, sizeof(PACKET));
+  Block data(PACKET);
   data.parse();
 
   BOOST_CHECK_EQUAL(data.elements_size(), 5);
@@ -478,7 +476,7 @@
     // TLV-LENGTH of nested element is greater than TLV-LENGTH of enclosing element
     0x05, 0x05, 0x07, 0x07, 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f
   };
-  Block bad(MALFORMED, sizeof(MALFORMED));
+  Block bad(MALFORMED);
   BOOST_CHECK_EXCEPTION(bad.parse(), Block::Error, [] (const auto& e) {
     return e.what() == "TLV-LENGTH of sub-element of type 7 exceeds TLV-VALUE boundary of parent block"s;
   });
@@ -634,20 +632,20 @@
 BOOST_AUTO_TEST_CASE(Equality)
 {
   const uint8_t one[] = {0x08, 0x00};
-  Block a(one, sizeof(one));
-  Block b(one, sizeof(one));
+  Block a(one);
+  Block b(one);
   BOOST_CHECK_EQUAL(a == b, true);
   BOOST_CHECK_EQUAL(a != b, false);
 
   const uint8_t two[] = {0x06, 0x00};
-  Block c(two, sizeof(two));
-  Block d(one, sizeof(one));
+  Block c(two);
+  Block d(one);
   BOOST_CHECK_EQUAL(c == d, false);
   BOOST_CHECK_EQUAL(c != d, true);
 
   const uint8_t three[] = {0x06, 0x01, 0xcc};
-  Block e(two, sizeof(two));
-  Block f(three, sizeof(three));
+  Block e(two);
+  Block f(three);
   BOOST_CHECK_EQUAL(e == f, false);
   BOOST_CHECK_EQUAL(e != f, true);
 }
diff --git a/tests/unit/encoding/encoder.t.cpp b/tests/unit/encoding/encoder.t.cpp
index 3f5fe8e..57a1f3d 100644
--- a/tests/unit/encoding/encoder.t.cpp
+++ b/tests/unit/encoding/encoder.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -41,14 +41,16 @@
   Encoder e2(100, 100);
   BOOST_CHECK_EQUAL(e2.capacity(), 100);
 
-  BOOST_CHECK_EQUAL(e.prependByte(1), 1);
-  BOOST_CHECK_EQUAL(e.appendByte(1), 1);
+  BOOST_CHECK_EQUAL(e.prependBytes({1}), 1);
+  BOOST_CHECK_EQUAL(e.appendBytes({1}), 1);
 
-  uint8_t buf1[] = {'t', 'e', 's', 't', '1'};
-  BOOST_CHECK_EQUAL(e1.prependByteArray(buf1, sizeof(buf1)), 5);
-  BOOST_CHECK_EQUAL(e1.appendByteArray(buf1, sizeof(buf1)), 5);
+  const uint8_t buf1[] = {'t', 'e', 's', 't', '1'};
+  BOOST_CHECK_EQUAL(e1.prependBytes(buf1), 5);
+  BOOST_CHECK_EQUAL(e1.appendBytes(buf1), 5);
 
   std::vector<uint8_t> buf2 = {'t', 'e', 's', 't', '2'};
+  BOOST_CHECK_EQUAL(e2.prependBytes(buf2), 5);
+  BOOST_CHECK_EQUAL(e2.appendBytes(buf2), 5);
   BOOST_CHECK_EQUAL(e1.prependRange(buf2.begin(), buf2.end()), 5);
   BOOST_CHECK_EQUAL(e1.appendRange(buf2.begin(), buf2.end()), 5);
 
@@ -56,17 +58,16 @@
   BOOST_CHECK_EQUAL(e2.prependRange(buf3.begin(), buf3.end()), 5);
   BOOST_CHECK_EQUAL(e2.appendRange(buf3.begin(), buf3.end()), 5);
 
-  uint8_t expected1[] = {1, 1};
-  BOOST_CHECK_EQUAL_COLLECTIONS(e.buf(), e.buf() + e.size(),
+  const uint8_t expected1[] = {1, 1};
+  BOOST_CHECK_EQUAL_COLLECTIONS(e.data(), e.data() + e.size(),
                                 expected1, expected1 + sizeof(expected1));
 
   const Encoder& constE = e;
-  BOOST_CHECK_EQUAL_COLLECTIONS(constE.buf(), constE.buf() + constE.size(),
+  BOOST_CHECK_EQUAL_COLLECTIONS(constE.data(), constE.data() + constE.size(),
                                 expected1, expected1 + sizeof(expected1));
 
-  uint8_t expected2[] = {'t', 'e', 's', 't', '2',
-                           't', 'e', 's', 't', '1', 't', 'e', 's', 't', '1',
-                         't', 'e', 's', 't', '2'};
+  const uint8_t expected2[] = {'t', 'e', 's', 't', '2', 't', 'e', 's', 't', '1',
+                               't', 'e', 's', 't', '1', 't', 'e', 's', 't', '2'};
   BOOST_CHECK_EQUAL_COLLECTIONS(e1.begin(), e1.end(),
                                 expected2, expected2 + sizeof(expected2));
   const Encoder& constE1 = e1;
@@ -129,19 +130,16 @@
 
   //
 
-  uint8_t buf[] = {0x01, 0x03, 0x00, 0x00, 0x00};
-  Block block1(buf, sizeof(buf));
-
-  BOOST_CHECK_EQUAL(e.prependByteArrayBlock(100, buf, sizeof(buf)), 7);
-  BOOST_CHECK_EQUAL(e.appendByteArrayBlock(100, buf, sizeof(buf)), 7);
-
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+  Block block1({0x01, 0x03, 0x00, 0x00, 0x00});
   BOOST_CHECK_EQUAL(e.prependBlock(block1), 5);
   BOOST_CHECK_EQUAL(e.appendBlock(block1), 5);
 
   Block block2(100, block1);
-
   BOOST_CHECK_EQUAL(e.prependBlock(block2), 7);
   BOOST_CHECK_EQUAL(e.appendBlock(block2), 7);
+#pragma GCC diagnostic pop
 }
 
 BOOST_AUTO_TEST_CASE(Reserve)
diff --git a/tests/unit/encoding/estimator.t.cpp b/tests/unit/encoding/estimator.t.cpp
index f5e4392..d4ecbaf 100644
--- a/tests/unit/encoding/estimator.t.cpp
+++ b/tests/unit/encoding/estimator.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -34,14 +34,16 @@
 {
   Estimator e;
 
-  BOOST_CHECK_EQUAL(e.prependByte(1), 1);
-  BOOST_CHECK_EQUAL(e.appendByte(1), 1);
+  BOOST_CHECK_EQUAL(e.prependBytes({1}), 1);
+  BOOST_CHECK_EQUAL(e.appendBytes({1}), 1);
 
-  uint8_t buf1[] = {'t', 'e', 's', 't', '1'};
-  BOOST_CHECK_EQUAL(e.prependByteArray(buf1, sizeof(buf1)), 5);
-  BOOST_CHECK_EQUAL(e.appendByteArray(buf1, sizeof(buf1)), 5);
+  const uint8_t buf1[] = {'t', 'e', 's', 't', '1'};
+  BOOST_CHECK_EQUAL(e.prependBytes(buf1), 5);
+  BOOST_CHECK_EQUAL(e.appendBytes(buf1), 5);
 
   std::vector<uint8_t> buf2 = {'t', 'e', 's', 't', '2'};
+  BOOST_CHECK_EQUAL(e.prependBytes(buf2), 5);
+  BOOST_CHECK_EQUAL(e.appendBytes(buf2), 5);
   BOOST_CHECK_EQUAL(e.prependRange(buf2.begin(), buf2.end()), 5);
   BOOST_CHECK_EQUAL(e.appendRange(buf2.begin(), buf2.end()), 5);
 
@@ -97,19 +99,16 @@
 
   //
 
-  uint8_t buf[] = {0x01, 0x03, 0x00, 0x00, 0x00};
-  Block block1(buf, sizeof(buf));
-
-  BOOST_CHECK_EQUAL(e.prependByteArrayBlock(100, buf, sizeof(buf)), 7);
-  BOOST_CHECK_EQUAL(e.appendByteArrayBlock(100, buf, sizeof(buf)), 7);
-
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+  Block block1({0x01, 0x03, 0x00, 0x00, 0x00});
   BOOST_CHECK_EQUAL(e.prependBlock(block1), 5);
   BOOST_CHECK_EQUAL(e.appendBlock(block1), 5);
 
   Block block2(100, block1);
-
   BOOST_CHECK_EQUAL(e.prependBlock(block2), 7);
   BOOST_CHECK_EQUAL(e.appendBlock(block2), 7);
+#pragma GCC diagnostic pop
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestEstimator
diff --git a/tests/unit/interest.t.cpp b/tests/unit/interest.t.cpp
index d36e0a9..ff50e8a 100644
--- a/tests/unit/interest.t.cpp
+++ b/tests/unit/interest.t.cpp
@@ -241,7 +241,7 @@
   si.setNonce(nonce);
   Block sv("2E20 12471AE0F8723AC1156C370A38711EBEBF2817DE9B2DD94E9B7E62F117B876C1"_block);
 
-  Interest i1(Block(WIRE, sizeof(WIRE)));
+  Interest i1(Block{WIRE});
   BOOST_CHECK_EQUAL(i1.getName(),
                     "/local/ndn/prefix/params-sha256=6f29586053ee9fccd8a422122925287c0a18435f4074c40abb0d5b30e4aa6220");
   BOOST_CHECK_EQUAL(i1.getCanBePrefix(), false);
@@ -319,7 +319,7 @@
   si.setNonce(nonce);
   Block sv("2E20 12471AE0F8723AC1156C370A38711EBEBF2817DE9B2DD94E9B7E62F117B876C1"_block);
 
-  Interest i1(Block(WIRE, sizeof(WIRE)));
+  Interest i1(Block{WIRE});
   BOOST_CHECK_EQUAL(i1.getName(),
                     "/local/ndn/prefix/params-sha256=bc3630a4d65e0db5483dfa0d28b3312fcac1d441ec8961d4175e61751778108e");
   BOOST_CHECK_EQUAL(i1.getCanBePrefix(), false);
@@ -1125,7 +1125,7 @@
                 0xbf, 0x28, 0x17, 0xde, 0x9b, 0x2d, 0xd9, 0x4e,
                 0x9b, 0x7e, 0x62, 0xf1, 0x17, 0xb8, 0x76, 0xc1,
   };
-  Block wire3(WIRE, sizeof(WIRE));
+  Block wire3(WIRE);
   Interest i2(wire3);
   auto ranges3 = i2.extractSignedRanges();
   BOOST_REQUIRE_EQUAL(ranges3.size(), 2);
diff --git a/tests/unit/link.t.cpp b/tests/unit/link.t.cpp
index 2d7fa9c..fe4b45c 100644
--- a/tests/unit/link.t.cpp
+++ b/tests/unit/link.t.cpp
@@ -77,7 +77,7 @@
 
 BOOST_AUTO_TEST_CASE(Decode)
 {
-  Link link(Block(GOOD_LINK, sizeof(GOOD_LINK)));
+  Link link(Block{GOOD_LINK});
   BOOST_CHECK_EQUAL(link.getName(), Name("/local/ndn/prefix"));
   BOOST_TEST(link.getDelegationList() == std::vector<Name>({"/local", "/ndn"}),
              boost::test_tools::per_element());
@@ -85,11 +85,11 @@
 
 BOOST_AUTO_TEST_CASE(DecodeBadContentType)
 {
-  Data linkData(Block(GOOD_LINK, sizeof(GOOD_LINK)));
+  Data linkData(Block{GOOD_LINK});
   linkData.setContentType(tlv::ContentType_Key);
   Block badLink = linkData.wireEncode();
 
-  BOOST_CHECK_THROW((Link(badLink)), Link::Error);
+  BOOST_CHECK_THROW(Link{badLink}, Link::Error);
   Link link;
   BOOST_CHECK_THROW(link.wireDecode(badLink), Link::Error);
 }
diff --git a/tests/unit/lp/cache-policy.t.cpp b/tests/unit/lp/cache-policy.t.cpp
index 78c1548..8b27a6c 100644
--- a/tests/unit/lp/cache-policy.t.cpp
+++ b/tests/unit/lp/cache-policy.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -38,10 +38,10 @@
   policy.setPolicy(CachePolicyType::NO_CACHE);
 
   Block wire;
-  BOOST_REQUIRE_NO_THROW(wire = policy.wireEncode());
+  BOOST_CHECK_NO_THROW(wire = policy.wireEncode());
 
   // Sample encoded value obtained with:
-  // for (Buffer::const_iterator it = wire.begin(); it != wire.end(); ++it) {
+  // for (auto it = wire.begin(); it != wire.end(); ++it) {
   //   printf("0x%02x, ", *it);
   // }
 
@@ -53,40 +53,31 @@
   BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
                                 wire.begin(), wire.end());
 
-  BOOST_REQUIRE_NO_THROW(policy.wireDecode(wire));
+  BOOST_CHECK_NO_THROW(policy.wireDecode(wire));
 }
 
 BOOST_AUTO_TEST_CASE(DecodeUnknownPolicyError)
 {
-  static const uint8_t expectedBlock[] = {
-    0xfd, 0x03, 0x34, 0x08, 0xfd, 0x03, 0x35, 0x04, 0xff, 0xff, 0xff, 0xff
-  };
+  const Block wire({0xfd, 0x03, 0x34, 0x08, 0xfd, 0x03, 0x35, 0x04, 0x1f, 0xff, 0xff, 0xff});
 
   CachePolicy policy;
-  Block wire(expectedBlock, sizeof(expectedBlock));
-  BOOST_REQUIRE_THROW(policy.wireDecode(wire), CachePolicy::Error);
+  BOOST_CHECK_THROW(policy.wireDecode(wire), CachePolicy::Error);
 }
 
 BOOST_AUTO_TEST_CASE(DecodeMissingPolicyError)
 {
-  static const uint8_t inputBlock[] = {
-    0xfd, 0x03, 0x34, 0x00
-  };
+  const Block wire({0xfd, 0x03, 0x34, 0x00});
 
   CachePolicy policy;
-  Block wire(inputBlock, sizeof(inputBlock));
-  BOOST_REQUIRE_THROW(policy.wireDecode(wire), CachePolicy::Error);
+  BOOST_CHECK_THROW(policy.wireDecode(wire), CachePolicy::Error);
 }
 
 BOOST_AUTO_TEST_CASE(DecodeInvalidPolicyError)
 {
-  static const uint8_t inputBlock[] = {
-    0xfd, 0x03, 0x34, 0x05, 0xfd, 0x03, 0x35, 0x01, 0x00
-  };
+  const Block wire({0xfd, 0x03, 0x34, 0x05, 0xfd, 0x03, 0x35, 0x01, 0x00});
 
   CachePolicy policy;
-  Block wire(inputBlock, sizeof(inputBlock));
-  BOOST_REQUIRE_THROW(policy.wireDecode(wire), CachePolicy::Error);
+  BOOST_CHECK_THROW(policy.wireDecode(wire), CachePolicy::Error);
 }
 
 BOOST_AUTO_TEST_CASE(Policy)
diff --git a/tests/unit/lp/nack-header.t.cpp b/tests/unit/lp/nack-header.t.cpp
index 4670608..c914eb0 100644
--- a/tests/unit/lp/nack-header.t.cpp
+++ b/tests/unit/lp/nack-header.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -50,10 +50,10 @@
   header.setReason(NackReason::DUPLICATE);
 
   Block wire;
-  BOOST_REQUIRE_NO_THROW(wire = header.wireEncode());
+  BOOST_CHECK_NO_THROW(wire = header.wireEncode());
 
   // Sample encoded value obtained with:
-  // for (Buffer::const_iterator it = wire.begin(); it != wire.end(); ++it) {
+  // for (auto it = wire.begin(); it != wire.end(); ++it) {
   //   printf("0x%02x, ", *it);
   // }
 
@@ -65,20 +65,20 @@
   BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
                                 wire.begin(), wire.end());
 
-  BOOST_REQUIRE_NO_THROW(header.wireDecode(wire));
+  BOOST_CHECK_NO_THROW(header.wireDecode(wire));
 }
 
 BOOST_AUTO_TEST_CASE(DecodeUnknownReasonCode)
 {
   static const uint8_t expectedBlock[] = {
-    0xfd, 0x03, 0x20, 0x08, 0xfd, 0x03, 0x21, 0x04, 0xff, 0xff, 0xff, 0xff,
+    0xfd, 0x03, 0x20, 0x08, 0xfd, 0x03, 0x21, 0x04, 0x1f, 0xff, 0xff, 0xff,
   };
 
   NackHeader header;
-  Block wire(expectedBlock, sizeof(expectedBlock));
-  BOOST_REQUIRE_NO_THROW(header.wireDecode(wire));
+  Block wire(expectedBlock);
+  BOOST_CHECK_NO_THROW(header.wireDecode(wire));
   Block wireEncoded;
-  BOOST_REQUIRE_NO_THROW(wireEncoded = header.wireEncode());
+  BOOST_CHECK_NO_THROW(wireEncoded = header.wireEncode());
   BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
                                 wireEncoded.begin(), wireEncoded.end());
   BOOST_CHECK_EQUAL(header.getReason(), NackReason::NONE);
@@ -91,10 +91,10 @@
   };
 
   NackHeader header;
-  Block wire(expectedBlock, sizeof(expectedBlock));
-  BOOST_REQUIRE_NO_THROW(header.wireDecode(wire));
+  Block wire(expectedBlock);
+  BOOST_CHECK_NO_THROW(header.wireDecode(wire));
   Block wireEncoded;
-  BOOST_REQUIRE_NO_THROW(wireEncoded = header.wireEncode());
+  BOOST_CHECK_NO_THROW(wireEncoded = header.wireEncode());
   BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
                                 wireEncoded.begin(), wireEncoded.end());
   BOOST_CHECK_EQUAL(header.getReason(), NackReason::NONE);
diff --git a/tests/unit/lp/packet.t.cpp b/tests/unit/lp/packet.t.cpp
index 5f750c3..7763f06 100644
--- a/tests/unit/lp/packet.t.cpp
+++ b/tests/unit/lp/packet.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -197,7 +197,7 @@
   };
 
   Packet packet;
-  Block wire(inputBlock, sizeof(inputBlock));
+  Block wire(inputBlock);
   packet.wireDecode(wire);
 
   BOOST_CHECK_EQUAL(packet.count<FragIndexField>(), 1);
@@ -231,7 +231,7 @@
   };
 
   Packet packet;
-  Block wire(inputBlock, sizeof(inputBlock));
+  Block wire(inputBlock);
   packet.wireDecode(wire);
   BOOST_CHECK_EQUAL(0, packet.count<FragmentField>());
   BOOST_CHECK_EQUAL(1, packet.count<FragIndexField>());
@@ -249,7 +249,7 @@
   };
 
   Packet packet;
-  Block wire(inputBlock, sizeof(inputBlock));
+  Block wire(inputBlock);
   packet.wireDecode(wire);
   BOOST_CHECK_EQUAL(1, packet.count<FragmentField>());
   BOOST_CHECK_EQUAL(0, packet.count<FragIndexField>());
@@ -268,7 +268,7 @@
   };
 
   Packet packet;
-  Block wire(inputBlock, sizeof(inputBlock));
+  Block wire(inputBlock);
   packet.wireDecode(wire);
   BOOST_CHECK_EQUAL(true, packet.has<NonDiscoveryField>());
   packet.get<NonDiscoveryField>();
@@ -281,7 +281,7 @@
   };
 
   Packet packet;
-  Block wire(inputBlock, sizeof(inputBlock));
+  Block wire(inputBlock);
   packet.wireDecode(wire);
   BOOST_CHECK_EQUAL(0, packet.count<FragmentField>());
   BOOST_CHECK_EQUAL(0, packet.count<FragIndexField>());
@@ -299,7 +299,7 @@
   };
 
   Packet packet;
-  Block wire(inputBlock, sizeof(inputBlock));
+  Block wire(inputBlock);
   BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
 }
 
@@ -314,7 +314,7 @@
   };
 
   Packet packet;
-  Block wire(inputBlock, sizeof(inputBlock));
+  Block wire(inputBlock);
   BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
 }
 
@@ -331,7 +331,7 @@
   };
 
   Packet packet;
-  Block wire(inputBlock, sizeof(inputBlock));
+  Block wire(inputBlock);
   BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
 }
 
@@ -348,7 +348,7 @@
   };
 
   Packet packet;
-  Block wire(inputBlock, sizeof(inputBlock));
+  Block wire(inputBlock);
   BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
 }
 
@@ -365,7 +365,7 @@
   };
 
   Packet packet;
-  Block wire(inputBlock, sizeof(inputBlock));
+  Block wire(inputBlock);
   packet.wireDecode(wire);
   BOOST_CHECK_EQUAL(1, packet.count<FragmentField>());
   BOOST_CHECK_EQUAL(1, packet.count<FragIndexField>());
@@ -384,7 +384,7 @@
   };
 
   Packet packet;
-  Block wire(inputBlock, sizeof(inputBlock));
+  Block wire(inputBlock);
   BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
 }
 
@@ -399,7 +399,7 @@
   };
 
   Packet packet;
-  Block wire(inputBlock, sizeof(inputBlock));
+  Block wire(inputBlock);
   packet.wireDecode(wire);
   BOOST_CHECK_EQUAL(1, packet.count<FragmentField>());
 
@@ -423,7 +423,7 @@
 BOOST_AUTO_TEST_CASE(DecodeUnrecognizedTlvType)
 {
   Packet packet;
-  Block wire = encoding::makeEmptyBlock(ndn::tlv::Name);
+  Block wire = makeEmptyBlock(ndn::tlv::Name);
   BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
 }
 
diff --git a/tests/unit/meta-info.t.cpp b/tests/unit/meta-info.t.cpp
index e5229bf..87add29 100644
--- a/tests/unit/meta-info.t.cpp
+++ b/tests/unit/meta-info.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -124,11 +124,11 @@
                               0x6c, 0x65, 0x78, 0x2c, 0x20, 0x49, 0x20, 0x61, 0x6d, 0x20, 0x58,
                               0x69, 0x61, 0x6f, 0x6b, 0x65, 0x20, 0x4a, 0x69, 0x61, 0x6e, 0x67};
 
-  BOOST_REQUIRE_EQUAL_COLLECTIONS(info1.wireEncode().begin(), info1.wireEncode().end(),
-                                  METAINFO, METAINFO + sizeof(METAINFO));
+  BOOST_CHECK_EQUAL_COLLECTIONS(info1.wireEncode().begin(), info1.wireEncode().end(),
+                                METAINFO, METAINFO + sizeof(METAINFO));
 
   MetaInfo info2;
-  info2.wireDecode(Block(METAINFO, sizeof(METAINFO)));
+  info2.wireDecode(Block(METAINFO));
 
   for (size_t i = 0; i < 5; i++) {
     uint32_t tlvType = 128 + i * 10;
diff --git a/tests/unit/mgmt/control-response.t.cpp b/tests/unit/mgmt/control-response.t.cpp
index 74b1b03..c23f7f0 100644
--- a/tests/unit/mgmt/control-response.t.cpp
+++ b/tests/unit/mgmt/control-response.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -48,7 +48,7 @@
 
 BOOST_AUTO_TEST_CASE(Decode)
 {
-  ControlResponse cr(Block(WIRE, sizeof(WIRE)));
+  ControlResponse cr(Block{WIRE});
   BOOST_CHECK_EQUAL(cr.getCode(), 404);
   BOOST_CHECK_EQUAL(cr.getText(), "Nothing not found");
 }
diff --git a/tests/unit/mgmt/dispatcher.t.cpp b/tests/unit/mgmt/dispatcher.t.cpp
index 7827516..30b5853 100644
--- a/tests/unit/mgmt/dispatcher.t.cpp
+++ b/tests/unit/mgmt/dispatcher.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -245,7 +245,7 @@
   Block
   wireEncode() const final
   {
-    return Block();
+    return {};
   }
 
   void
@@ -298,8 +298,7 @@
 
 BOOST_AUTO_TEST_CASE(StatusDataset)
 {
-  const uint8_t smallBuf[] = {0x81, 0x01, 0x01};
-  const Block smallBlock(smallBuf, sizeof(smallBuf));
+  const Block smallBlock({0x81, 0x01, 0x01});
   const Block largeBlock = [] {
     Block b(129, std::make_shared<const Buffer>(3000));
     b.encode();
@@ -399,10 +398,10 @@
 
   content = [&dataInStorage] () -> Block {
     EncodingBuffer encoder;
-    size_t valueLength = encoder.prependByteArray(dataInStorage[1].getContent().value(),
-                                                  dataInStorage[1].getContent().value_size());
-    valueLength += encoder.prependByteArray(dataInStorage[0].getContent().value(),
-                                            dataInStorage[0].getContent().value_size());
+    size_t valueLength = encoder.prependBytes({dataInStorage[1].getContent().value(),
+                                               dataInStorage[1].getContent().value_size()});
+    valueLength += encoder.prependBytes({dataInStorage[0].getContent().value(),
+                                         dataInStorage[0].getContent().value_size()});
     encoder.prependVarNumber(valueLength);
     encoder.prependVarNumber(tlv::Content);
     return encoder.block();
@@ -427,8 +426,7 @@
 
 BOOST_AUTO_TEST_CASE(NotificationStream)
 {
-  const uint8_t buf[] = {0x82, 0x01, 0x02};
-  const Block block(buf, sizeof(buf));
+  const Block block({0x82, 0x01, 0x02});
   auto post = dispatcher.addNotificationStream("test");
 
   post(block);
diff --git a/tests/unit/mgmt/nfd/status-dataset.t.cpp b/tests/unit/mgmt/nfd/status-dataset.t.cpp
index 21fb288..2c8c7f7 100644
--- a/tests/unit/mgmt/nfd/status-dataset.t.cpp
+++ b/tests/unit/mgmt/nfd/status-dataset.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -70,12 +70,12 @@
     BOOST_CONCEPT_ASSERT((WireEncodable<T1>));
     BOOST_CONCEPT_ASSERT((WireEncodable<T2>));
 
-    ndn::encoding::EncodingBuffer buffer;
+    EncodingBuffer buffer;
     payload2.wireEncode(buffer);
     payload1.wireEncode(buffer);
 
     auto data = this->prepareDatasetReply(prefix);
-    data->setContent(buffer.buf(), buffer.size());
+    data->setContent(buffer);
     face.receive(*signData(data));
   }
 
diff --git a/tests/unit/mgmt/status-dataset-context.t.cpp b/tests/unit/mgmt/status-dataset-context.t.cpp
index 6d1e0b9..4192337 100644
--- a/tests/unit/mgmt/status-dataset-context.t.cpp
+++ b/tests/unit/mgmt/status-dataset-context.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -67,7 +67,7 @@
     size_t valueLength = 0;
     for (const auto& args : sendDataHistory) {
       const auto& content = args.content;
-      valueLength += encoder.appendByteArray(content.value(), content.value_size());
+      valueLength += encoder.appendBytes({content.value(), content.value_size()});
     }
     encoder.prependVarNumber(valueLength);
     encoder.prependVarNumber(tlv::Content);
@@ -237,7 +237,7 @@
 BOOST_AUTO_TEST_CASE(AppendReject)
 {
   const uint8_t buf[] = {0x82, 0x01, 0x02};
-  BOOST_CHECK_NO_THROW(context.append(Block(buf, sizeof(buf))));
+  BOOST_CHECK_NO_THROW(context.append(Block(buf)));
   BOOST_CHECK_EXCEPTION(context.reject(), std::logic_error, [] (const auto& e) {
     return e.what() == "cannot call reject() after append/end"s;
   });
@@ -246,7 +246,7 @@
 BOOST_AUTO_TEST_CASE(AppendEndReject)
 {
   const uint8_t buf[] = {0x82, 0x01, 0x02};
-  BOOST_CHECK_NO_THROW(context.append(Block(buf, sizeof(buf))));
+  BOOST_CHECK_NO_THROW(context.append(Block(buf)));
   BOOST_CHECK_NO_THROW(context.end());
   BOOST_CHECK_EXCEPTION(context.reject(), std::logic_error, [] (const auto& e) {
     return e.what() == "cannot call reject() after append/end"s;
@@ -257,7 +257,7 @@
 {
   BOOST_CHECK_NO_THROW(context.end());
   const uint8_t buf[] = {0x82, 0x01, 0x02};
-  BOOST_CHECK_EXCEPTION(context.append(Block(buf, sizeof(buf))), std::logic_error, [] (const auto& e) {
+  BOOST_CHECK_EXCEPTION(context.append(Block(buf)), std::logic_error, [] (const auto& e) {
     return e.what() == "cannot call append() on a finalized context"s;
   });
 }
@@ -282,7 +282,7 @@
 {
   BOOST_CHECK_NO_THROW(context.reject());
   const uint8_t buf[] = {0x82, 0x01, 0x02};
-  BOOST_CHECK_EXCEPTION(context.append(Block(buf, sizeof(buf))), std::logic_error, [] (const auto& e) {
+  BOOST_CHECK_EXCEPTION(context.append(Block(buf)), std::logic_error, [] (const auto& e) {
     return e.what() == "cannot call append() on a finalized context"s;
   });
 }
diff --git a/tests/unit/name.t.cpp b/tests/unit/name.t.cpp
index fccb838..4e8d104 100644
--- a/tests/unit/name.t.cpp
+++ b/tests/unit/name.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -257,11 +257,14 @@
   name.append("xKh");
   BOOST_CHECK_EQUAL(name.wireEncode(), "070B 080428F0A36B 0803784B68"_block);
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
   name.append("0100"_block);
   BOOST_CHECK_EQUAL(name.wireEncode(), "070F 080428F0A36B 0803784B68 08020100"_block);
 
   name.append("080109"_block);
   BOOST_CHECK_EQUAL(name.wireEncode(), "0712 080428F0A36B 0803784B68 08020100 080109"_block);
+#pragma GCC diagnostic pop
 }
 
 BOOST_AUTO_TEST_CASE(AppendPartialName)
diff --git a/tests/unit/security/additional-description.t.cpp b/tests/unit/security/additional-description.t.cpp
index 657870f..56a9090 100644
--- a/tests/unit/security/additional-description.t.cpp
+++ b/tests/unit/security/additional-description.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -30,7 +30,7 @@
 BOOST_AUTO_TEST_SUITE(Security)
 BOOST_AUTO_TEST_SUITE(TestAdditionalDescription)
 
-const uint8_t description[] = {
+const uint8_t DESC[] = {
   0xfd, 0x01, 0x02, 0x28,
     0xfd, 0x02, 0x00, 0x10, // DescriptionEntry
       0xfd, 0x02, 0x01, 0x04, // DescriptionKey
@@ -44,8 +44,6 @@
         0x76, 0x61, 0x6c, 0x32, // "val2"
 };
 
-const std::string text = "[(key1:val1), (key2:val2)]";
-
 BOOST_AUTO_TEST_CASE(Basic)
 {
   AdditionalDescription aDescription;
@@ -76,12 +74,10 @@
 
   BOOST_CHECK_EQUAL_COLLECTIONS(aDescription.wireEncode().wire(),
                                 aDescription.wireEncode().wire() + aDescription.wireEncode().size(),
-                                description,
-                                description + sizeof(description));
+                                DESC,
+                                DESC + sizeof(DESC));
 
-  BOOST_REQUIRE_NO_THROW(AdditionalDescription(Block(description, sizeof(description))));
-  AdditionalDescription aDescription2(Block(description, sizeof(description)));
-
+  AdditionalDescription aDescription2(Block{DESC});
   BOOST_CHECK_EQUAL(aDescription2, aDescription);
 
   AdditionalDescription aDescription3;
@@ -92,7 +88,7 @@
 
   std::ostringstream os;
   os << aDescription;
-  BOOST_CHECK_EQUAL(os.str(), text);
+  BOOST_CHECK_EQUAL(os.str(), "[(key1:val1), (key2:val2)]");
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestAdditionalDescription
diff --git a/tests/unit/security/certificate.t.cpp b/tests/unit/security/certificate.t.cpp
index 7626e04..63b29a6 100644
--- a/tests/unit/security/certificate.t.cpp
+++ b/tests/unit/security/certificate.t.cpp
@@ -126,7 +126,7 @@
 static void
 generateFakeSignature(Data& data)
 {
-  SignatureInfo signatureInfo(Block(SIG_INFO, sizeof(SIG_INFO)));
+  SignatureInfo signatureInfo(Block{SIG_INFO});
   signatureInfo.setKeyLocator(KeyLocator(Name("/ndn/site1/KEY/ksk-2516425377094")));
   signatureInfo.setValidityPeriod(ValidityPeriod(time::fromIsoString("20141111T050000"),
                                                  time::fromIsoString("20141111T060000")));
@@ -137,7 +137,7 @@
 
 BOOST_AUTO_TEST_CASE(Construction)
 {
-  Block block(CERT, sizeof(CERT));
+  Block block(CERT);
   Certificate certificate(block);
 
   BOOST_CHECK_EQUAL(certificate.getName(), "/ndn/site1/KEY/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B");
@@ -201,7 +201,7 @@
 public:
   InvalidCertFixture()
   {
-    Certificate certBase(Block(CERT, sizeof(CERT)));
+    Certificate certBase(Block{CERT});
     BOOST_CHECK_NO_THROW((Certificate(certBase)));
 
     m_certBase = Data(certBase);
@@ -267,7 +267,7 @@
   Key Locator: Name=/ndn/site1/KEY/ksk-2516425377094
 )INFO").substr(1);
 
-  Certificate certificate(Block(CERT, sizeof(CERT)));
+  Certificate certificate(Block{CERT});
   BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(certificate), expectedCertificateInfo);
 
   // TODO: Check output formats of other certificates
diff --git a/tests/unit/security/detail/certificate-bundle-decoder.t.cpp b/tests/unit/security/detail/certificate-bundle-decoder.t.cpp
index ae81c82..630aaec 100644
--- a/tests/unit/security/detail/certificate-bundle-decoder.t.cpp
+++ b/tests/unit/security/detail/certificate-bundle-decoder.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -99,7 +99,7 @@
 {
   // First segment contains first 250 bytes of cert1
   Data d;
-  d.setContent(certBlock1.wire(), 250);
+  d.setContent(make_span(certBlock1.wire(), 250));
 
   // Second segment contains the rest of cert1 and the first 100 bytes of cert2
   auto buf = std::make_shared<Buffer>(certBlock1.begin() + 250, certBlock1.end());
@@ -145,7 +145,7 @@
   };
   // Second segment contains non-Certificate data
   Data d2;
-  d2.setContent(buf, sizeof(buf));
+  d2.setContent(buf);
 
   // Third segment contains all of cert2
   Data d3;
diff --git a/tests/unit/security/pib/pib-data-fixture.cpp b/tests/unit/security/pib/pib-data-fixture.cpp
index d27c742..37e1e6d 100644
--- a/tests/unit/security/pib/pib-data-fixture.cpp
+++ b/tests/unit/security/pib/pib-data-fixture.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -360,15 +360,15 @@
 };
 
 PibDataFixture::PibDataFixture()
-  : id1Key1Cert1(Block(ID1_KEY1_CERT1, sizeof(ID1_KEY1_CERT1)))
-  , id1Key1Cert2(Block(ID1_KEY1_CERT2, sizeof(ID1_KEY1_CERT2)))
-  , id1Key2Cert1(Block(ID1_KEY2_CERT1, sizeof(ID1_KEY2_CERT1)))
-  , id1Key2Cert2(Block(ID1_KEY2_CERT2, sizeof(ID1_KEY2_CERT2)))
+  : id1Key1Cert1(Block(ID1_KEY1_CERT1))
+  , id1Key1Cert2(Block(ID1_KEY1_CERT2))
+  , id1Key2Cert1(Block(ID1_KEY2_CERT1))
+  , id1Key2Cert2(Block(ID1_KEY2_CERT2))
 
-  , id2Key1Cert1(Block(ID2_KEY1_CERT1, sizeof(ID2_KEY1_CERT1)))
-  , id2Key1Cert2(Block(ID2_KEY1_CERT2, sizeof(ID2_KEY1_CERT2)))
-  , id2Key2Cert1(Block(ID2_KEY2_CERT1, sizeof(ID2_KEY2_CERT1)))
-  , id2Key2Cert2(Block(ID2_KEY2_CERT2, sizeof(ID2_KEY2_CERT2)))
+  , id2Key1Cert1(Block(ID2_KEY1_CERT1))
+  , id2Key1Cert2(Block(ID2_KEY1_CERT2))
+  , id2Key2Cert1(Block(ID2_KEY2_CERT1))
+  , id2Key2Cert2(Block(ID2_KEY2_CERT2))
 
   , id1(id1Key1Cert1.getIdentity())
   , id2(id2Key1Cert1.getIdentity())
diff --git a/tests/unit/security/safe-bag.t.cpp b/tests/unit/security/safe-bag.t.cpp
index c3cc7c2..5d24112 100644
--- a/tests/unit/security/safe-bag.t.cpp
+++ b/tests/unit/security/safe-bag.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -121,10 +121,10 @@
 
 BOOST_AUTO_TEST_CASE(Constructor)
 {
-  Data data(Block(CERT, sizeof(CERT)));
-  SafeBag safeBag1(data, ENCRYPTED_KEY);
-  SafeBag safeBag2(Block(SAFE_BAG, sizeof(SAFE_BAG)));
+  Data data(Block{CERT});
   auto encKey = make_span(ENCRYPTED_KEY);
+  SafeBag safeBag1(data, encKey);
+  SafeBag safeBag2(Block{SAFE_BAG});
 
   BOOST_CHECK(safeBag1.getCertificate() == data);
   BOOST_CHECK_EQUAL_COLLECTIONS(safeBag1.getEncryptedKey().begin(), safeBag1.getEncryptedKey().end(),
@@ -136,13 +136,12 @@
 
 BOOST_AUTO_TEST_CASE(EncoderAndDecoder)
 {
-  Block dataBlock(CERT, sizeof(CERT));
-  Data data(dataBlock);
+  Data data(Block{CERT});
   SafeBag safeBag(data, ENCRYPTED_KEY);
 
   // wire encode
-  Block wireBlock = safeBag.wireEncode();
-  Block block(SAFE_BAG, sizeof(SAFE_BAG));
+  const auto& wireBlock = safeBag.wireEncode();
+  Block block(SAFE_BAG);
 
   // check safe bag block
   BOOST_CHECK_EQUAL(wireBlock, block);
diff --git a/tests/unit/security/validation-policy-command-interest.t.cpp b/tests/unit/security/validation-policy-command-interest.t.cpp
index 478b2d5..4fe05b7 100644
--- a/tests/unit/security/validation-policy-command-interest.t.cpp
+++ b/tests/unit/security/validation-policy-command-interest.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -176,7 +176,7 @@
 {
   auto i1 = makeCommandInterest(identity);
   KeyLocator kl;
-  kl.setKeyDigest(makeBinaryBlock(tlv::KeyDigest, "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD", 8));
+  kl.setKeyDigest(makeBinaryBlock(tlv::KeyDigest, {0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD}));
   SignatureInfo sigInfo(tlv::SignatureSha256WithRsa);
   sigInfo.setKeyLocator(kl);
   setNameComponent(i1, command_interest::POS_SIG_INFO,
diff --git a/tests/unit/security/validity-period.t.cpp b/tests/unit/security/validity-period.t.cpp
index 1dc7740..5dc8d9d 100644
--- a/tests/unit/security/validity-period.t.cpp
+++ b/tests/unit/security/validity-period.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -87,15 +87,11 @@
 {
   time::system_clock::TimePoint notBefore = time::getUnixEpoch();
   time::system_clock::TimePoint notAfter = notBefore + 1_day;
-
   ValidityPeriod v1(notBefore, notAfter);
-
   BOOST_CHECK_EQUAL_COLLECTIONS(v1.wireEncode().begin(), v1.wireEncode().end(),
                                 VP1, VP1 + sizeof(VP1));
 
-  BOOST_REQUIRE_NO_THROW(ValidityPeriod(Block(VP1, sizeof(VP1))));
-  Block block(VP1, sizeof(VP1));
-  ValidityPeriod v2(block);
+  ValidityPeriod v2(Block{VP1});
   BOOST_CHECK(v1.getPeriod() == v2.getPeriod());
 }
 
@@ -159,21 +155,17 @@
       0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30
 };
 
-
 BOOST_AUTO_TEST_CASE(DecodingError)
 {
-  BOOST_CHECK_THROW(ValidityPeriod(Block(VP_E1, sizeof(VP_E1))), ValidityPeriod::Error);
-
-  BOOST_CHECK_THROW(ValidityPeriod(Block(VP_E2, sizeof(VP_E2))), ValidityPeriod::Error);
-  BOOST_CHECK_THROW(ValidityPeriod(Block(VP_E3, sizeof(VP_E3))), ValidityPeriod::Error);
-
-  BOOST_CHECK_THROW(ValidityPeriod(Block(VP_E4, sizeof(VP_E4))), ValidityPeriod::Error);
-  BOOST_CHECK_THROW(ValidityPeriod(Block(VP_E5, sizeof(VP_E5))), ValidityPeriod::Error);
+  BOOST_CHECK_THROW(ValidityPeriod(Block{VP_E1}), ValidityPeriod::Error);
+  BOOST_CHECK_THROW(ValidityPeriod(Block{VP_E2}), ValidityPeriod::Error);
+  BOOST_CHECK_THROW(ValidityPeriod(Block{VP_E3}), ValidityPeriod::Error);
+  BOOST_CHECK_THROW(ValidityPeriod(Block{VP_E4}), ValidityPeriod::Error);
+  BOOST_CHECK_THROW(ValidityPeriod(Block{VP_E5}), ValidityPeriod::Error);
+  BOOST_CHECK_THROW(ValidityPeriod(Block{VP_E6}), ValidityPeriod::Error);
 
   Block emptyBlock;
-  BOOST_CHECK_THROW((ValidityPeriod(emptyBlock)), ValidityPeriod::Error);
-
-  BOOST_CHECK_THROW(ValidityPeriod(Block(VP_E6, sizeof(VP_E6))), ValidityPeriod::Error);
+  BOOST_CHECK_THROW(ValidityPeriod{emptyBlock}, ValidityPeriod::Error);
 }
 
 BOOST_AUTO_TEST_CASE(Comparison)
diff --git a/tests/unit/security/verification-helpers.t.cpp b/tests/unit/security/verification-helpers.t.cpp
index 479a655..5e313ec 100644
--- a/tests/unit/security/verification-helpers.t.cpp
+++ b/tests/unit/security/verification-helpers.t.cpp
@@ -49,7 +49,7 @@
 //   };
 
 //   auto print = [] (const std::string& name, const uint8_t* buf, size_t size) {
-//     std::cout << "  std::vector<uint8_t> " + name + " = {\n    ";
+//     std::cout << "  const Block " + name + "{{\n    ";
 
 //     std::string hex = toHex(buf, size);
 
@@ -63,7 +63,7 @@
 //       if ((i + 1) != hex.size())
 //         std::cout << ", ";
 //     }
-//     std::cout << "\n  };";
+//     std::cout << "\n  }};";
 //   };
 
 //   for (const auto& i : identities) {
@@ -130,7 +130,7 @@
 struct EcdsaDataset
 {
   const std::string name = "Ecdsa";
-  std::vector<uint8_t> cert = {
+  const Block cert{{
     0x06, 0xFD, 0x01, 0x62, 0x07, 0x47, 0x08, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
     0x08, 0x17, 0x54, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
     0x6F, 0x6E, 0x48, 0x65, 0x6C, 0x70, 0x65, 0x72, 0x73, 0x08, 0x02, 0x45, 0x43, 0x08, 0x03, 0x4B,
@@ -154,8 +154,8 @@
     0x6B, 0x24, 0xF5, 0x7F, 0x02, 0x20, 0x1C, 0x88, 0xDE, 0x32, 0x3F, 0x1A, 0xE6, 0x60, 0xA2, 0x29,
     0x94, 0xD9, 0x05, 0x8F, 0x57, 0x14, 0xD6, 0x17, 0x3C, 0x78, 0xBF, 0x85, 0xF5, 0x1D, 0xCC, 0x03,
     0x35, 0x9E, 0xC9, 0xA9, 0x6B, 0x09
-  };
-  std::vector<uint8_t> goodData = {
+  }};
+  const Block goodData{{
     0x06, 0xA2, 0x07, 0x13, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x04, 0x64, 0x61, 0x74, 0x61,
     0x08, 0x05, 0x45, 0x63, 0x64, 0x73, 0x61, 0x14, 0x00, 0x15, 0x00, 0x16, 0x3D, 0x1B, 0x01, 0x03,
     0x1C, 0x38, 0x07, 0x36, 0x08, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x08, 0x17,
@@ -167,8 +167,8 @@
     0xC3, 0x02, 0x21, 0x00, 0xB5, 0xA3, 0x87, 0xD8, 0x9B, 0xB6, 0x92, 0xAD, 0x19, 0x84, 0xAE, 0x4D,
     0xF5, 0x64, 0xEC, 0x1C, 0xF2, 0xA0, 0xB7, 0x4D, 0x6B, 0x74, 0xFF, 0x39, 0x38, 0xFD, 0x5D, 0x9D,
     0x46, 0xE0, 0xD2, 0xB4
-  };
-  std::vector<uint8_t> badSigData = {
+  }};
+  const Block badSigData{{
     0x06, 0xA5, 0x07, 0x13, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x04, 0x64, 0x61, 0x74, 0x61,
     0x08, 0x05, 0x45, 0x63, 0x64, 0x73, 0x61, 0x14, 0x00, 0x15, 0x00, 0x16, 0x40, 0x1B, 0x01, 0x03,
     0x1C, 0x3B, 0x07, 0x39, 0x08, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x08, 0x17,
@@ -180,8 +180,8 @@
     0x13, 0xB4, 0xB8, 0x95, 0x02, 0x21, 0x00, 0xDA, 0x54, 0x99, 0xF8, 0xE5, 0xC1, 0x74, 0xAC, 0xE0,
     0xF2, 0xDF, 0x0D, 0xC5, 0xE1, 0xCF, 0x99, 0x28, 0x6C, 0xB0, 0x2D, 0x55, 0xC8, 0x74, 0x63, 0x56,
     0x2A, 0x1A, 0xB0, 0x00, 0xBD, 0xFF, 0xC5
-  };
-  std::vector<uint8_t> goodInterest = {
+  }};
+  const Block goodInterest{{
     0x05, 0xCA, 0x07, 0x39, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x08, 0x69, 0x6E, 0x74, 0x65,
     0x72, 0x65, 0x73, 0x74, 0x08, 0x05, 0x45, 0x63, 0x64, 0x73, 0x61, 0x02, 0x20, 0x8F, 0x41, 0x49,
     0x40, 0xDA, 0x38, 0xC1, 0x0E, 0x75, 0x5A, 0x6D, 0x4A, 0xD4, 0xFC, 0xE2, 0xDF, 0xBA, 0x52, 0xAF,
@@ -195,8 +195,8 @@
     0xDB, 0xEA, 0x3A, 0x71, 0x83, 0x0D, 0xC4, 0x26, 0xB7, 0x24, 0x02, 0x20, 0x0F, 0x14, 0x10, 0xDB,
     0xDB, 0x24, 0xCB, 0xB3, 0xD2, 0x4B, 0x45, 0x6D, 0xA0, 0xBB, 0x4B, 0x87, 0xC1, 0x59, 0x9F, 0xC8,
     0xBE, 0x75, 0xF5, 0xCC, 0xCB, 0xD2, 0x4F, 0xD8, 0x87, 0x26, 0x51, 0xBF
-  };
-  std::vector<uint8_t> badSigInterest = {
+  }};
+  const Block badSigInterest{{
     0x05, 0xCF, 0x07, 0x39, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x08, 0x69, 0x6E, 0x74, 0x65,
     0x72, 0x65, 0x73, 0x74, 0x08, 0x05, 0x45, 0x63, 0x64, 0x73, 0x61, 0x02, 0x20, 0x53, 0x14, 0x5E,
     0xA3, 0x31, 0x41, 0xD8, 0xA1, 0x10, 0x06, 0x3C, 0x8E, 0xF3, 0x51, 0xA0, 0xC2, 0x8A, 0xBC, 0xFC,
@@ -211,8 +211,8 @@
     0x00, 0xC7, 0x23, 0x25, 0xF7, 0xFA, 0x6A, 0x2D, 0x3D, 0xF4, 0xD8, 0xDB, 0xE9, 0x76, 0x6A, 0x63,
     0xD4, 0x11, 0x17, 0x4A, 0xDB, 0x7F, 0x85, 0x52, 0x97, 0xFC, 0x5B, 0x0B, 0x1B, 0xBA, 0xE5, 0xED,
     0x9A
-  };
-  std::vector<uint8_t> goodInterestOldFormat = {
+  }};
+  const Block goodInterestOldFormat{{
     0x05, 0xCB, 0x07, 0x39, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x08, 0x69, 0x6E, 0x74, 0x65,
     0x72, 0x65, 0x73, 0x74, 0x08, 0x05, 0x45, 0x63, 0x64, 0x73, 0x61, 0x02, 0x20, 0xDB, 0x6D, 0x5E,
     0xA7, 0xBF, 0xAF, 0xEC, 0xA0, 0xC6, 0x20, 0x4E, 0xF2, 0x04, 0xF8, 0xFF, 0x39, 0x2A, 0x5F, 0xE6,
@@ -226,8 +226,8 @@
     0x60, 0x63, 0x51, 0xB3, 0x52, 0xBC, 0x6D, 0x24, 0x0C, 0x6D, 0x38, 0x02, 0x20, 0x0E, 0x21, 0xF1,
     0x51, 0x39, 0x2D, 0x4A, 0x45, 0x05, 0x45, 0xFA, 0x85, 0xA7, 0xCC, 0x00, 0xFE, 0x89, 0x8A, 0xD6,
     0xD7, 0x34, 0x0D, 0x31, 0x6A, 0x94, 0xAE, 0x1F, 0xD8, 0x07, 0xF1, 0xDF, 0x80
-  };
-  std::vector<uint8_t> badSigInterestOldFormat = {
+  }};
+  const Block badSigInterestOldFormat{{
     0x05, 0xFD, 0x01, 0x5B, 0x07, 0xC9, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x08, 0x69, 0x6E,
     0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x08, 0x05, 0x45, 0x63, 0x64, 0x73, 0x61, 0x02, 0x20, 0xDB,
     0x6D, 0x5E, 0xA7, 0xBF, 0xAF, 0xEC, 0xA0, 0xC6, 0x20, 0x4E, 0xF2, 0x04, 0xF8, 0xFF, 0x39, 0x2A,
@@ -250,13 +250,13 @@
     0x64, 0xAA, 0x60, 0x63, 0x51, 0xB3, 0x52, 0xBC, 0x6D, 0x24, 0x0C, 0x6D, 0x38, 0x02, 0x20, 0x0E,
     0x21, 0xF1, 0x51, 0x39, 0x2D, 0x4A, 0x45, 0x05, 0x45, 0xFA, 0x85, 0xA7, 0xCC, 0x00, 0xFE, 0x89,
     0x8A, 0xD6, 0xD7, 0x34, 0x0D, 0x31, 0x6A, 0x94, 0xAE, 0x1F, 0xD8, 0x07, 0xF1, 0xDF, 0x80
-  };
+  }};
 };
 
 struct RsaDataset
 {
   const std::string name = "Rsa";
-  std::vector<uint8_t> cert = {
+  const Block cert{{
     0x06, 0xFD, 0x02, 0xED, 0x07, 0x48, 0x08, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
     0x08, 0x17, 0x54, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
     0x6F, 0x6E, 0x48, 0x65, 0x6C, 0x70, 0x65, 0x72, 0x73, 0x08, 0x03, 0x52, 0x53, 0x41, 0x08, 0x03,
@@ -305,8 +305,8 @@
     0x3E, 0xFA, 0xE6, 0xB9, 0x8E, 0x08, 0x82, 0x50, 0xCA, 0xEE, 0x7F, 0x5D, 0x80, 0x65, 0xBA, 0x10,
     0x1F, 0x24, 0xC1, 0x15, 0x78, 0xB7, 0x90, 0xE5, 0x3D, 0xDA, 0x0F, 0x0E, 0x03, 0x20, 0xC1, 0xEA,
     0x85
-  };
-  std::vector<uint8_t> goodData = {
+  }};
+  const Block goodData{{
     0x06, 0xFD, 0x01, 0x5B, 0x07, 0x11, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x04, 0x64, 0x61,
     0x74, 0x61, 0x08, 0x03, 0x52, 0x73, 0x61, 0x14, 0x00, 0x15, 0x00, 0x16, 0x3E, 0x1B, 0x01, 0x01,
     0x1C, 0x39, 0x07, 0x37, 0x08, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x08, 0x17,
@@ -329,8 +329,8 @@
     0x4F, 0xD9, 0xEB, 0xC1, 0x5D, 0x53, 0x15, 0xBF, 0x8C, 0x7C, 0x6B, 0x22, 0xB9, 0x24, 0x70, 0xAE,
     0x63, 0x13, 0x96, 0x3B, 0x2A, 0xDA, 0x7F, 0x64, 0x0D, 0x9E, 0xA7, 0x90, 0x20, 0x2A, 0x2A, 0xAB,
     0xA9, 0xA6, 0xC9, 0xB2, 0x37, 0x8E, 0xE3, 0x09, 0xFD, 0xA3, 0x68, 0x06, 0xCB, 0x96, 0x80
-  };
-  std::vector<uint8_t> badSigData = {
+  }};
+  const Block badSigData{{
     0x06, 0xA2, 0x07, 0x11, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x04, 0x64, 0x61, 0x74, 0x61,
     0x08, 0x03, 0x52, 0x73, 0x61, 0x14, 0x00, 0x15, 0x00, 0x16, 0x40, 0x1B, 0x01, 0x03, 0x1C, 0x3B,
     0x07, 0x39, 0x08, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x08, 0x17, 0x54, 0x65,
@@ -342,8 +342,8 @@
     0x1E, 0x02, 0x21, 0x00, 0xA5, 0x62, 0xA5, 0x04, 0x60, 0xBC, 0x96, 0x54, 0x2C, 0x9E, 0x6F, 0xA8,
     0x1B, 0xDB, 0xF9, 0xF0, 0x7E, 0xFF, 0xED, 0x92, 0x3A, 0x4B, 0xDE, 0x3D, 0x20, 0x02, 0x7B, 0xD7,
     0x1C, 0xD0, 0xAA, 0xAB
-  };
-  std::vector<uint8_t> goodInterest = {
+  }};
+  const Block goodInterest{{
     0x05, 0xFD, 0x01, 0x85, 0x07, 0x37, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x08, 0x69, 0x6E,
     0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x08, 0x03, 0x52, 0x73, 0x61, 0x02, 0x20, 0x08, 0x39, 0xEE,
     0x12, 0xF1, 0x10, 0xB7, 0x8B, 0x49, 0xF2, 0xE2, 0x54, 0x23, 0xFF, 0x66, 0xB3, 0x0F, 0xC6, 0x91,
@@ -369,8 +369,8 @@
     0xE3, 0x11, 0x85, 0xCC, 0x0E, 0xAF, 0x56, 0x6B, 0xE1, 0xAC, 0xB3, 0x20, 0xF2, 0x47, 0xFE, 0x95,
     0xC8, 0x71, 0x99, 0xCC, 0x52, 0x8A, 0x6F, 0xF1, 0x01, 0xD6, 0xE9, 0x2E, 0x6C, 0x27, 0xC3, 0xED,
     0xE3, 0xF2, 0xDD, 0x78, 0xB4, 0x7F, 0xFA, 0xD0, 0xC2
-  };
-  std::vector<uint8_t> badSigInterest = {
+  }};
+  const Block badSigInterest{{
     0x05, 0xCC, 0x07, 0x37, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x08, 0x69, 0x6E, 0x74, 0x65,
     0x72, 0x65, 0x73, 0x74, 0x08, 0x03, 0x52, 0x73, 0x61, 0x02, 0x20, 0x64, 0xE3, 0x6F, 0xD5, 0x73,
     0x21, 0xBC, 0xAB, 0xDE, 0xDE, 0x0F, 0x99, 0xCB, 0x49, 0x7F, 0x46, 0xE7, 0xF0, 0x7A, 0xF1, 0x2C,
@@ -384,8 +384,8 @@
     0x4A, 0xBF, 0xC0, 0x5B, 0xA8, 0x05, 0xA2, 0xC8, 0x61, 0xC4, 0x2E, 0x64, 0x02, 0x20, 0x1F, 0x5E,
     0xF5, 0x8E, 0xC9, 0xDC, 0x9E, 0x15, 0x1C, 0xFA, 0x58, 0x5F, 0xDF, 0xAE, 0xA0, 0xFD, 0xDA, 0x34,
     0x21, 0xE0, 0xA8, 0x2D, 0x32, 0x47, 0x9E, 0x44, 0x83, 0x79, 0x23, 0x5F, 0xBE, 0x16
-  };
-  std::vector<uint8_t> goodInterestOldFormat = {
+  }};
+  const Block goodInterestOldFormat{{
     0x05, 0xFD, 0x01, 0x85, 0x07, 0x37, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x08, 0x69, 0x6E,
     0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x08, 0x03, 0x52, 0x73, 0x61, 0x02, 0x20, 0x08, 0x39, 0xEE,
     0x12, 0xF1, 0x10, 0xB7, 0x8B, 0x49, 0xF2, 0xE2, 0x54, 0x23, 0xFF, 0x66, 0xB3, 0x0F, 0xC6, 0x91,
@@ -411,8 +411,8 @@
     0xE3, 0x11, 0x85, 0xCC, 0x0E, 0xAF, 0x56, 0x6B, 0xE1, 0xAC, 0xB3, 0x20, 0xF2, 0x47, 0xFE, 0x95,
     0xC8, 0x71, 0x99, 0xCC, 0x52, 0x8A, 0x6F, 0xF1, 0x01, 0xD6, 0xE9, 0x2E, 0x6C, 0x27, 0xC3, 0xED,
     0xE3, 0xF2, 0xDD, 0x78, 0xB4, 0x7F, 0xFA, 0xD0, 0xC2
-  };
-  std::vector<uint8_t> badSigInterestOldFormat = {
+  }};
+  const Block badSigInterestOldFormat{{
     0x05, 0xFD, 0x02, 0x15, 0x07, 0xC7, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x08, 0x69, 0x6E,
     0x74, 0x65, 0x72, 0x65, 0x73, 0x74, 0x08, 0x03, 0x52, 0x73, 0x61, 0x02, 0x20, 0x08, 0x39, 0xEE,
     0x12, 0xF1, 0x10, 0xB7, 0x8B, 0x49, 0xF2, 0xE2, 0x54, 0x23, 0xFF, 0x66, 0xB3, 0x0F, 0xC6, 0x91,
@@ -447,23 +447,22 @@
     0xE3, 0x11, 0x85, 0xCC, 0x0E, 0xAF, 0x56, 0x6B, 0xE1, 0xAC, 0xB3, 0x20, 0xF2, 0x47, 0xFE, 0x95,
     0xC8, 0x71, 0x99, 0xCC, 0x52, 0x8A, 0x6F, 0xF1, 0x01, 0xD6, 0xE9, 0x2E, 0x6C, 0x27, 0xC3, 0xED,
     0xE3, 0xF2, 0xDD, 0x78, 0xB4, 0x7F, 0xFA, 0xD0, 0xC2
-  };
+  }};
 };
 
 struct Sha256Dataset
 {
   const std::string name = "Sha256";
-  std::vector<uint8_t> cert = {
-
-  };
-  std::vector<uint8_t> goodData = {
+  const Block cert{{
+  }};
+  const Block goodData{{
     0x06, 0x41, 0x07, 0x14, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x04, 0x64, 0x61, 0x74, 0x61,
     0x08, 0x06, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x14, 0x00, 0x15, 0x00, 0x16, 0x03, 0x1B, 0x01,
     0x00, 0x17, 0x20, 0xE2, 0xE2, 0x2F, 0x02, 0x70, 0xA7, 0xF7, 0x48, 0x70, 0x45, 0x29, 0x46, 0xBD,
     0xD2, 0x62, 0x24, 0xA6, 0x1E, 0x1D, 0x75, 0x2A, 0x26, 0x98, 0x04, 0xAD, 0x9C, 0x47, 0x63, 0xF8,
     0x98, 0x5A, 0x49
-  };
-  std::vector<uint8_t> badSigData = {
+  }};
+  const Block badSigData{{
     0x06, 0xA6, 0x07, 0x14, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x04, 0x64, 0x61, 0x74, 0x61,
     0x08, 0x06, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x14, 0x00, 0x15, 0x00, 0x16, 0x40, 0x1B, 0x01,
     0x03, 0x1C, 0x3B, 0x07, 0x39, 0x08, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x08,
@@ -475,8 +474,8 @@
     0x28, 0x19, 0x6C, 0x5C, 0xD6, 0x02, 0x21, 0x00, 0xF0, 0xD2, 0x23, 0xEA, 0xD9, 0x43, 0x6D, 0x8A,
     0xD2, 0x02, 0x3F, 0xF1, 0x41, 0x12, 0xA6, 0xED, 0x87, 0xB3, 0xD5, 0x5A, 0x27, 0x5D, 0x4E, 0xEB,
     0x13, 0x29, 0x01, 0xBC, 0x3C, 0xCC, 0x50, 0x61
-  };
-  std::vector<uint8_t> goodInterest = {
+  }};
+  const Block goodInterest{{
     0x05, 0x6B, 0x07, 0x3A, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x08, 0x69, 0x6E, 0x74, 0x65,
     0x72, 0x65, 0x73, 0x74, 0x08, 0x06, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x02, 0x20, 0x8F, 0x03,
     0x0B, 0x85, 0xA7, 0x05, 0xD8, 0x05, 0x31, 0x8E, 0x80, 0x81, 0xD3, 0xE2, 0xA8, 0x5E, 0x74, 0xD7,
@@ -484,8 +483,8 @@
     0xF7, 0x2C, 0x8A, 0x4B, 0x24, 0x00, 0x2C, 0x03, 0x1B, 0x01, 0x00, 0x2E, 0x20, 0xEF, 0x45, 0x55,
     0x75, 0xC8, 0x18, 0x5E, 0xE9, 0x2A, 0xAE, 0x52, 0x61, 0x0A, 0x94, 0x41, 0x03, 0x36, 0x4C, 0x13,
     0x59, 0xD4, 0xC7, 0xA4, 0x3A, 0xA0, 0x40, 0x61, 0x44, 0x33, 0x93, 0x5E, 0x99
-  };
-  std::vector<uint8_t> badSigInterest = {
+  }};
+  const Block badSigInterest{{
     0x05, 0xCE, 0x07, 0x3A, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x08, 0x69, 0x6E, 0x74, 0x65,
     0x72, 0x65, 0x73, 0x74, 0x08, 0x06, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x02, 0x20, 0x32, 0x3F,
     0x2F, 0xA3, 0xDC, 0x15, 0x7E, 0x8C, 0xA9, 0x75, 0xF7, 0x66, 0xFF, 0xFD, 0x13, 0x42, 0x1B, 0xE1,
@@ -499,8 +498,8 @@
     0x73, 0xB3, 0xA6, 0xD2, 0x99, 0x32, 0x26, 0xE2, 0x46, 0x3A, 0xE0, 0x69, 0xDF, 0xB2, 0x02, 0x20,
     0x6A, 0x03, 0xCE, 0xB6, 0x85, 0x1E, 0x01, 0x5E, 0xF8, 0x48, 0xDE, 0x65, 0xB9, 0xE1, 0xEB, 0x9A,
     0xF8, 0x47, 0x43, 0x5B, 0xBA, 0x63, 0xCB, 0xBA, 0xFB, 0x62, 0x1C, 0x38, 0xE8, 0x53, 0xF7, 0x29
-  };
-  std::vector<uint8_t> goodInterestOldFormat = {
+  }};
+  const Block goodInterestOldFormat{{
     0x05, 0x6B, 0x07, 0x3A, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x08, 0x69, 0x6E, 0x74, 0x65,
     0x72, 0x65, 0x73, 0x74, 0x08, 0x06, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x02, 0x20, 0x8F, 0x03,
     0x0B, 0x85, 0xA7, 0x05, 0xD8, 0x05, 0x31, 0x8E, 0x80, 0x81, 0xD3, 0xE2, 0xA8, 0x5E, 0x74, 0xD7,
@@ -508,8 +507,8 @@
     0xF7, 0x2C, 0x8A, 0x4B, 0x24, 0x00, 0x2C, 0x03, 0x1B, 0x01, 0x00, 0x2E, 0x20, 0xEF, 0x45, 0x55,
     0x75, 0xC8, 0x18, 0x5E, 0xE9, 0x2A, 0xAE, 0x52, 0x61, 0x0A, 0x94, 0x41, 0x03, 0x36, 0x4C, 0x13,
     0x59, 0xD4, 0xC7, 0xA4, 0x3A, 0xA0, 0x40, 0x61, 0x44, 0x33, 0x93, 0x5E, 0x99
-  };
-  std::vector<uint8_t> badSigInterestOldFormat = {
+  }};
+  const Block badSigInterestOldFormat{{
     0x05, 0xFA, 0x07, 0xC9, 0x08, 0x04, 0x74, 0x65, 0x73, 0x74, 0x08, 0x08, 0x69, 0x6E, 0x74, 0x65,
     0x72, 0x65, 0x73, 0x74, 0x08, 0x06, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x02, 0x20, 0x8F, 0x03,
     0x0B, 0x85, 0xA7, 0x05, 0xD8, 0x05, 0x31, 0x8E, 0x80, 0x81, 0xD3, 0xE2, 0xA8, 0x5E, 0x74, 0xD7,
@@ -526,7 +525,7 @@
     0x2C, 0x8A, 0x4B, 0x24, 0x00, 0x2C, 0x03, 0x1B, 0x01, 0x00, 0x2E, 0x20, 0xEF, 0x45, 0x55, 0x75,
     0xC8, 0x18, 0x5E, 0xE9, 0x2A, 0xAE, 0x52, 0x61, 0x0A, 0x94, 0x41, 0x03, 0x36, 0x4C, 0x13, 0x59,
     0xD4, 0xC7, 0xA4, 0x3A, 0xA0, 0x40, 0x61, 0x44, 0x33, 0x93, 0x5E, 0x99
-  };
+  }};
 };
 
 // Note about the datasets:
@@ -547,18 +546,17 @@
 BOOST_AUTO_TEST_CASE_TEMPLATE(VerifySignature, Dataset, SignatureDatasets)
 {
   const Dataset dataset;
-  Certificate cert(Block(dataset.cert.data(), dataset.cert.size()));
-  Buffer keyRaw = cert.getPublicKey();
+  Certificate cert(dataset.cert);
+  auto keyRaw = cert.getPublicKey();
   transform::PublicKey key;
   key.loadPkcs8(keyRaw);
-  Data data(Block(dataset.goodData.data(), dataset.goodData.size()));
-  Data badSigData(Block(dataset.badSigData.data(), dataset.badSigData.size()));
-  Interest interest(Block(dataset.goodInterest.data(), dataset.goodInterest.size()));
-  Interest badSigInterest(Block(dataset.badSigInterest.data(), dataset.badSigInterest.size()));
-  Interest interestOldFormat(Block(dataset.goodInterestOldFormat.data(),
-                                   dataset.goodInterestOldFormat.size()));
-  Interest badSigInterestOldFormat(Block(dataset.badSigInterestOldFormat.data(),
-                                         dataset.badSigInterestOldFormat.size()));
+
+  Data data(dataset.goodData);
+  Data badSigData(dataset.badSigData);
+  Interest interest(dataset.goodInterest);
+  Interest badSigInterest(dataset.badSigInterest);
+  Interest interestOldFormat(dataset.goodInterestOldFormat);
+  Interest badSigInterestOldFormat(dataset.badSigInterestOldFormat);
 
   BOOST_CHECK(verifySignature(data, key));
   BOOST_CHECK(verifySignature(data, keyRaw));
@@ -634,14 +632,12 @@
 BOOST_AUTO_TEST_CASE_TEMPLATE(VerifyDigest, Dataset, DigestDatasets)
 {
   const Dataset dataset;
-  Data data(Block(dataset.goodData.data(), dataset.goodData.size()));
-  Data badSigData(Block(dataset.badSigData.data(), dataset.badSigData.size()));
-  Interest interest(Block(dataset.goodInterest.data(), dataset.goodInterest.size()));
-  Interest badSigInterest(Block(dataset.badSigInterest.data(), dataset.badSigInterest.size()));
-  Interest interestOldFormat(Block(dataset.goodInterestOldFormat.data(),
-                                   dataset.goodInterestOldFormat.size()));
-  Interest badSigInterestOldFormat(Block(dataset.badSigInterestOldFormat.data(),
-                                         dataset.badSigInterestOldFormat.size()));
+  Data data(dataset.goodData);
+  Data badSigData(dataset.badSigData);
+  Interest interest(dataset.goodInterest);
+  Interest badSigInterest(dataset.badSigInterest);
+  Interest interestOldFormat(dataset.goodInterestOldFormat);
+  Interest badSigInterestOldFormat(dataset.badSigInterestOldFormat);
 
   BOOST_CHECK(verifySignature(data, nullopt));
   BOOST_CHECK(verifySignature(interest, nullopt));
@@ -683,8 +679,8 @@
 
 BOOST_AUTO_TEST_CASE(VerifyWithUnrecognizedElements) // Bug #4583
 {
-  Data data(Block(sha256DataUnrecognizedElements, sizeof(sha256DataUnrecognizedElements)));
-  Interest interest(Block(sha256InterestUnrecognizedElements, sizeof(sha256InterestUnrecognizedElements)));
+  Data data(Block{sha256DataUnrecognizedElements});
+  Interest interest(Block{sha256InterestUnrecognizedElements});
 
   BOOST_CHECK(verifySignature(data, nullopt));
   BOOST_CHECK(verifySignature(interest, nullopt));
diff --git a/tests/unit/signature-info.t.cpp b/tests/unit/signature-info.t.cpp
index eb08285..11fdff1 100644
--- a/tests/unit/signature-info.t.cpp
+++ b/tests/unit/signature-info.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2020 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -243,8 +243,7 @@
                                 encodedData.begin(), encodedData.end());
 
   // Decode as (Data)SignatureInfo
-  info = SignatureInfo(Block(sigInfoDataRsa, sizeof(sigInfoDataRsa)),
-                       SignatureInfo::Type::Data);
+  info = SignatureInfo(Block(sigInfoDataRsa), SignatureInfo::Type::Data);
 
   BOOST_CHECK_EQUAL(info.getSignatureType(), tlv::SignatureSha256WithRsa);
   BOOST_CHECK_EQUAL(info.hasKeyLocator(), true);
@@ -265,8 +264,7 @@
                                 encodedInterest.begin(), encodedInterest.end());
 
   // Decode as InterestSignatureInfo
-  info = SignatureInfo(Block(sigInfoInterestRsa, sizeof(sigInfoInterestRsa)),
-                       SignatureInfo::Type::Interest);
+  info = SignatureInfo(Block(sigInfoInterestRsa), SignatureInfo::Type::Interest);
 
   BOOST_CHECK_EQUAL(info.getSignatureType(), tlv::SignatureSha256WithRsa);
   BOOST_CHECK_EQUAL(info.hasKeyLocator(), true);
@@ -285,8 +283,7 @@
                                 encodedDataEcdsa.begin(), encodedDataEcdsa.end());
 
   // Decode as (Data)SignatureInfo
-  info = SignatureInfo(Block(sigInfoDataEcdsa, sizeof(sigInfoDataEcdsa)),
-                       SignatureInfo::Type::Data);
+  info = SignatureInfo(Block(sigInfoDataEcdsa), SignatureInfo::Type::Data);
 
   BOOST_CHECK_EQUAL(info.getSignatureType(), tlv::SignatureSha256WithEcdsa);
   BOOST_CHECK_EQUAL(info.hasKeyLocator(), true);
@@ -311,7 +308,7 @@
           0x08, 0x07,
             0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72
   };
-  Block errorBlock1(error1, sizeof(error1));
+  Block errorBlock1(error1);
   BOOST_CHECK_THROW(SignatureInfo(errorBlock1, SignatureInfo::Type::Data), tlv::Error);
 
   const uint8_t error2[] = {
@@ -320,13 +317,13 @@
         0x01, // Sha256WithRsa
       0x83, 0x00, // Unrecognized critical TLV
   };
-  Block errorBlock2(error2, sizeof(error2));
+  Block errorBlock2(error2);
   BOOST_CHECK_THROW(SignatureInfo(errorBlock2, SignatureInfo::Type::Data), tlv::Error);
 
   const uint8_t error3[] = {
     0x16, 0x00 // Empty SignatureInfo
   };
-  Block errorBlock3(error3, sizeof(error3));
+  Block errorBlock3(error3);
   BOOST_CHECK_THROW(SignatureInfo(errorBlock3, SignatureInfo::Type::Data), tlv::Error);
 
   // Encoding is correct for SignatureInfo, but decoder is expecting InterestSignatureInfo
@@ -343,7 +340,7 @@
           0x08, 0x07,
             0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72
   };
-  Block errorBlock4(error4, sizeof(error4));
+  Block errorBlock4(error4);
   BOOST_CHECK_THROW(SignatureInfo(errorBlock4, SignatureInfo::Type::Interest), tlv::Error);
 
   // SignatureType and KeyLocator out-of-order
@@ -360,7 +357,7 @@
       0x1b, 0x01, // SignatureType
         0x01, // Sha256WithRsa
   };
-  Block errorBlock5(error5, sizeof(error5));
+  Block errorBlock5(error5);
   BOOST_CHECK_THROW(SignatureInfo(errorBlock5, SignatureInfo::Type::Interest), tlv::Error);
 
   // Repeated KeyLocator
@@ -385,7 +382,7 @@
           0x08, 0x07,
             0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72
   };
-  Block errorBlock6(error6, sizeof(error6));
+  Block errorBlock6(error6);
   BOOST_CHECK_THROW(SignatureInfo(errorBlock6, SignatureInfo::Type::Interest), tlv::Error);
 
   // Zero-length SignatureNonce
@@ -395,7 +392,7 @@
         0x01, // Sha256WithRsa
       0x26, 0x00 // SignatureNonce
   };
-  Block errorBlock7(error7, sizeof(error7));
+  Block errorBlock7(error7);
   BOOST_CHECK_THROW(SignatureInfo(errorBlock7, SignatureInfo::Type::Interest), tlv::Error);
 }
 
@@ -444,7 +441,7 @@
   BOOST_CHECK_EQUAL(info.hasWire(), true);
 
   // decode
-  Block block(sigInfo, sizeof(sigInfo));
+  Block block(sigInfo);
   SignatureInfo info2(block, SignatureInfo::Type::Data);
   BOOST_CHECK_EQUAL(info2.getValidityPeriod(), vp1);
   BOOST_CHECK_EQUAL(info2.hasWire(), true);
@@ -503,7 +500,7 @@
           0x6a, 0x05, 0x54, 0x68, 0x69, 0x72, 0x64 // 106 "Third"
   };
 
-  SignatureInfo info3(Block(infoBytes, sizeof(infoBytes)), SignatureInfo::Type::Data);
+  SignatureInfo info3(Block(infoBytes), SignatureInfo::Type::Data);
   BOOST_CHECK_EQUAL(info3, info1);
   BOOST_CHECK_EQUAL_COLLECTIONS(infoBytes, infoBytes + sizeof(infoBytes),
                                 info1.wireEncode().begin(), info1.wireEncode().end());
diff --git a/tests/unit/util/io.t.cpp b/tests/unit/util/io.t.cpp
index 8b19fe3..ebe5799 100644
--- a/tests/unit/util/io.t.cpp
+++ b/tests/unit/util/io.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -67,7 +67,7 @@
 {
   T t;
   std::ostringstream os(std::ios_base::binary);
-  io::saveBuffer(t.blob.data(), t.blob.size(), os, t.encoding);
+  io::saveBuffer(t.blob, os, t.encoding);
   BOOST_CHECK_EQUAL(os.str(), t.stream.str());
 }
 
@@ -86,7 +86,7 @@
   NullStreambuf nullbuf;
   std::ostream out(&nullbuf);
   const Buffer buffer(1);
-  BOOST_CHECK_THROW(io::saveBuffer(buffer.data(), buffer.size(), out, io::NO_ENCODING), io::Error);
+  BOOST_CHECK_THROW(io::saveBuffer(buffer, out, io::NO_ENCODING), io::Error);
 }
 
 BOOST_AUTO_TEST_CASE(UnknownIoEncoding)
@@ -94,7 +94,7 @@
   std::stringstream ss;
   BOOST_CHECK_THROW(io::loadTlv<Name>(ss, static_cast<io::IoEncoding>(5)), std::invalid_argument);
   BOOST_CHECK_THROW(io::loadBuffer(ss, static_cast<io::IoEncoding>(5)), std::invalid_argument);
-  BOOST_CHECK_THROW(io::saveBuffer(nullptr, 0, ss, static_cast<io::IoEncoding>(5)), std::invalid_argument);
+  BOOST_CHECK_THROW(io::saveBuffer({}, ss, static_cast<io::IoEncoding>(5)), std::invalid_argument);
 }
 
 class FileIoFixture
diff --git a/tests/unit/util/sha256.t.cpp b/tests/unit/util/sha256.t.cpp
index 501a015..3340204 100644
--- a/tests/unit/util/sha256.t.cpp
+++ b/tests/unit/util/sha256.t.cpp
@@ -134,7 +134,7 @@
   auto expected = fromHex("b372edfd4d6a4db2cfeaeead6c34fdee9b9e759f7b8d799cf8067e39e7f2886c");
 
   Sha256 statefulSha256;
-  statefulSha256 << Block{input, sizeof(input)};
+  statefulSha256 << Block{input};
   ConstBufferPtr digest = statefulSha256.computeDigest();
 
   BOOST_CHECK_EQUAL(statefulSha256.empty(), false);
diff --git a/tests/unit/util/simple-notification.hpp b/tests/unit/util/simple-notification.hpp
index 280045a..acfa172 100644
--- a/tests/unit/util/simple-notification.hpp
+++ b/tests/unit/util/simple-notification.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2021 Regents of the University of California,
+ * Copyright (c) 2014-2022 Regents of the University of California,
  *                         Arizona Board of Regents,
  *                         Colorado State University,
  *                         University Pierre & Marie Curie, Sorbonne University,
@@ -28,7 +28,7 @@
 #ifndef NDN_CXX_TESTS_UNIT_UTIL_SIMPLE_NOTIFICATION_HPP
 #define NDN_CXX_TESTS_UNIT_UTIL_SIMPLE_NOTIFICATION_HPP
 
-#include "ndn-cxx/encoding/encoding-buffer.hpp"
+#include "ndn-cxx/encoding/block-helpers.hpp"
 
 namespace ndn {
 namespace util {
@@ -53,11 +53,7 @@
   Block
   wireEncode() const
   {
-    ndn::EncodingBuffer buffer;
-    buffer.prependByteArrayBlock(0x8888,
-                                 reinterpret_cast<const uint8_t*>(m_message.c_str()),
-                                 m_message.size());
-    return buffer.block();
+    return makeStringBlock(0x8888, m_message);
   }
 
   void