encoding: make Block convertible to span

Change-Id: Idb501467d1c56b95e7fdb76acda63b919fe98f85
diff --git a/ndn-cxx/data.cpp b/ndn-cxx/data.cpp
index 35031ac..9b4b488 100644
--- a/ndn-cxx/data.cpp
+++ b/ndn-cxx/data.cpp
@@ -211,7 +211,7 @@
       NDN_THROW(Error("Cannot compute full name because Data has no wire encoding (not signed)"));
     }
     m_fullName = m_name;
-    m_fullName.appendImplicitSha256Digest(util::Sha256::computeDigest({m_wire.wire(), m_wire.size()}));
+    m_fullName.appendImplicitSha256Digest(util::Sha256::computeDigest(m_wire));
   }
 
   return m_fullName;
diff --git a/ndn-cxx/data.hpp b/ndn-cxx/data.hpp
index 040774a..29be126 100644
--- a/ndn-cxx/data.hpp
+++ b/ndn-cxx/data.hpp
@@ -164,10 +164,12 @@
    * If the element is not present (hasContent() == false), an invalid Block will be returned.
    *
    * The value of the returned Content Block (if valid) can be accessed through
-   * Block::value() / Block::value_size() or Block::value_begin() / Block::value_end().
+   *   - Block::value_bytes(), or
+   *   - Block::value() and Block::value_size(), or
+   *   - Block::value_begin() and Block::value_end().
    *
    * @sa hasContent()
-   * @sa Block::blockFromValue(), Block::parse()
+   * @sa Block::value_bytes(), Block::blockFromValue(), Block::parse()
    */
   const Block&
   getContent() const noexcept
diff --git a/ndn-cxx/encoding/block-helpers.cpp b/ndn-cxx/encoding/block-helpers.cpp
index 99ada84..c3037c8 100644
--- a/ndn-cxx/encoding/block-helpers.cpp
+++ b/ndn-cxx/encoding/block-helpers.cpp
@@ -212,11 +212,11 @@
 prependBlock(EncodingImpl<TAG>& encoder, const Block& block)
 {
   if (block.hasWire()) {
-    return encoder.prependBytes({block.wire(), block.size()});
+    return encoder.prependBytes(block);
   }
   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()});
+    // FIXME: blindly calling Block::value_bytes() is not safe if the value is not wire-encoded
+    return prependBinaryBlock(encoder, block.type(), block.value_bytes());
   }
 }
 
diff --git a/ndn-cxx/encoding/block.cpp b/ndn-cxx/encoding/block.cpp
index 4b2992a..30cab98 100644
--- a/ndn-cxx/encoding/block.cpp
+++ b/ndn-cxx/encoding/block.cpp
@@ -293,7 +293,7 @@
 }
 
 const uint8_t*
-Block::wire() const
+Block::data() const
 {
   if (!hasWire())
     NDN_THROW(Error("Underlying wire buffer is empty"));
@@ -319,12 +319,6 @@
   return value_size() > 0 ? &*m_valueBegin : nullptr;
 }
 
-size_t
-Block::value_size() const noexcept
-{
-  return hasValue() ? static_cast<size_t>(m_valueEnd - m_valueBegin) : 0;
-}
-
 Block
 Block::blockFromValue() const
 {
@@ -493,7 +487,7 @@
 
 Block::operator boost::asio::const_buffer() const
 {
-  return {wire(), size()};
+  return {data(), size()};
 }
 
 bool
@@ -522,7 +516,7 @@
   }
   else if (block.value_size() > 0) {
     os << block.type() << '[' << block.value_size() << "]=";
-    printHex(os, {block.value(), block.value_size()}, true);
+    printHex(os, block.value_bytes(), true);
   }
   else {
     os << block.type() << "[empty]";
@@ -533,7 +527,7 @@
 }
 
 Block
-operator "" _block(const char* input, std::size_t len)
+operator ""_block(const char* input, std::size_t len)
 {
   namespace t = security::transform;
   t::StepSource ss;
diff --git a/ndn-cxx/encoding/block.hpp b/ndn-cxx/encoding/block.hpp
index 34b9619..2b79030 100644
--- a/ndn-cxx/encoding/block.hpp
+++ b/ndn-cxx/encoding/block.hpp
@@ -257,16 +257,27 @@
   const_iterator
   end() const;
 
-  /** @brief Return a raw pointer to the beginning of the encoded wire
-   *  @pre `hasWire() == true`
-   *  @sa value()
+  /**
+   * @brief Return a raw pointer to the beginning of the encoded wire
+   * @pre `hasWire() == true`
+   * @sa value()
    */
   const uint8_t*
-  wire() const;
+  data() const;
 
-  /** @brief Return the size of the encoded wire, i.e. of the whole TLV
-   *  @pre `isValid() == true`
-   *  @sa value_size()
+  /**
+   * @deprecated Use data()
+   */
+  const uint8_t*
+  wire() const
+  {
+    return data();
+  }
+
+  /**
+   * @brief Return the size of the encoded wire, i.e., of the whole TLV
+   * @pre `isValid() == true`
+   * @sa value_size()
    */
   size_t
   size() const;
@@ -280,21 +291,23 @@
   }
 
 public: // type and value
-  /** @brief Return the TLV-TYPE of the Block
-   *  @note This will return tlv::Invalid if isValid() is false.
+  /**
+   * @brief Return the TLV-TYPE of the Block
+   * @note This will return tlv::Invalid if isValid() is false.
    */
   uint32_t
-  type() const
+  type() const noexcept
   {
     return m_type;
   }
 
-  /** @brief Check if the Block has a non-empty TLV-VALUE
+  /**
+   * @brief Check if the Block has a non-empty TLV-VALUE
    *
-   *  This property reflects whether the underlying buffer contains a TLV-VALUE. If this is false,
-   *  TLV-VALUE has zero-length. If this is true, TLV-VALUE may be zero-length.
+   * This property reflects whether the underlying buffer contains a TLV-VALUE. If this is false,
+   * TLV-VALUE has zero-length. If this is true, TLV-VALUE may be zero-length.
    *
-   *  @sa value_size()
+   * @sa value_size()
    */
   bool
   hasValue() const noexcept
@@ -302,36 +315,59 @@
     return m_buffer != nullptr;
   }
 
-  /** @brief Get begin iterator of TLV-VALUE
-   *  @pre `hasValue() == true`
+  /**
+   * @brief Get begin iterator of TLV-VALUE
+   * @pre `hasValue() == true`
    */
   const_iterator
-  value_begin() const
+  value_begin() const noexcept
   {
     return m_valueBegin;
   }
 
-  /** @brief Get end iterator of TLV-VALUE
-   *  @pre `hasValue() == true`
+  /**
+   * @brief Get end iterator of TLV-VALUE
+   * @pre `hasValue() == true`
    */
   const_iterator
-  value_end() const
+  value_end() const noexcept
   {
     return m_valueEnd;
   }
 
-  /** @brief Return a raw pointer to the beginning of TLV-VALUE
-   *  @sa wire()
+  /**
+   * @brief Return the size of TLV-VALUE, i.e., the TLV-LENGTH
+   * @sa size()
+   */
+  size_t
+  value_size() const noexcept
+  {
+    return hasValue() ? static_cast<size_t>(m_valueEnd - m_valueBegin) : 0;
+  }
+
+  /**
+   * @brief Return a read-only view of TLV-VALUE as a contiguous range of bytes
+   */
+  span<const uint8_t>
+  value_bytes() const noexcept
+  {
+    if (hasValue())
+      return {m_valueBegin, m_valueEnd};
+    else
+      return {};
+  }
+
+  /**
+   * @brief Return a raw pointer to the beginning of TLV-VALUE
+   * @sa value_bytes(), data()
    */
   const uint8_t*
   value() const noexcept;
 
-  /** @brief Return the size of TLV-VALUE, aka TLV-LENGTH
-   *  @sa size()
+  /**
+   * @brief Return a new Block constructed from the TLV-VALUE of this Block
+   * @pre `value_size() > 0`
    */
-  size_t
-  value_size() const noexcept;
-
   Block
   blockFromValue() const;
 
@@ -527,14 +563,14 @@
  *  @throw std::invalid_argument input is empty or has an odd number of hexadecimal digits.
  *  @throw tlv::Error @p input cannot be parsed into a valid Block.
  *
- *  Example
+ *  Example:
  *  @code
  *  Block nameBlock = "0706 080141 080142"_block;
  *  Block nackBlock = "FD032005 reason(no-route)=FD03210196"_block;
  *  @endcode
  */
 Block
-operator "" _block(const char* input, std::size_t len);
+operator ""_block(const char* input, std::size_t len);
 
 } // namespace ndn
 
diff --git a/ndn-cxx/encoding/encoder.cpp b/ndn-cxx/encoding/encoder.cpp
index 7cc9e17..c2964f4 100644
--- a/ndn-cxx/encoding/encoder.cpp
+++ b/ndn-cxx/encoding/encoder.cpp
@@ -226,7 +226,7 @@
 Encoder::prependBlock(const Block& block)
 {
   if (block.hasWire()) {
-    return prependBytes({block.wire(), block.size()});
+    return prependBytes(block);
   }
   else {
     return prependByteArrayBlock(block.type(), block.value(), block.value_size());
@@ -237,7 +237,7 @@
 Encoder::appendBlock(const Block& block)
 {
   if (block.hasWire()) {
-    return appendBytes({block.wire(), block.size()});
+    return appendBytes(block);
   }
   else {
     return appendByteArrayBlock(block.type(), block.value(), block.value_size());
diff --git a/ndn-cxx/impl/face-impl.hpp b/ndn-cxx/impl/face-impl.hpp
index b5065d1..d2e2ae8 100644
--- a/ndn-cxx/impl/face-impl.hpp
+++ b/ndn-cxx/impl/face-impl.hpp
@@ -333,7 +333,7 @@
   finishEncoding(lp::Packet&& lpPacket, Block wire, char pktType, const Name& name)
   {
     if (!lpPacket.empty()) {
-      lpPacket.add<lp::FragmentField>(std::make_pair(wire.begin(), wire.end()));
+      lpPacket.add<lp::FragmentField>({wire.begin(), wire.end()});
       wire = lpPacket.wireEncode();
     }
 
diff --git a/ndn-cxx/impl/name-component-types.hpp b/ndn-cxx/impl/name-component-types.hpp
index 81b8b8e..d6aab5c 100644
--- a/ndn-cxx/impl/name-component-types.hpp
+++ b/ndn-cxx/impl/name-component-types.hpp
@@ -250,7 +250,7 @@
   writeUri(std::ostream& os, const Component& comp) const final
   {
     os << m_uriPrefix << '=';
-    printHex(os, {comp.value(), comp.value_size()}, false);
+    printHex(os, comp.value_bytes(), false);
   }
 
 private:
diff --git a/ndn-cxx/interest.cpp b/ndn-cxx/interest.cpp
index ad4b40e..c69d3c0 100644
--- a/ndn-cxx/interest.cpp
+++ b/ndn-cxx/interest.cpp
@@ -649,7 +649,7 @@
     NDN_THROW(Error("Interest Name must end with a ParametersSha256DigestComponent"));
   }
 
-  bufs.emplace_back(m_name[0].wire(), m_name[-1].wire());
+  bufs.emplace_back(m_name[0].data(), m_name[-1].data());
 
   // Ensure InterestSignatureInfo element is present
   auto sigInfoIt = findFirstParameter(tlv::InterestSignatureInfo);
@@ -700,7 +700,7 @@
   in >> digestFilter(DigestAlgorithm::SHA256) >> streamSink(out);
 
   for (const auto& block : m_parameters) {
-    in.write({block.wire(), block.size()});
+    in.write(block);
   }
   in.end();
 
diff --git a/ndn-cxx/lp/field-decl.hpp b/ndn-cxx/lp/field-decl.hpp
index 1cb74ef..245859f 100644
--- a/ndn-cxx/lp/field-decl.hpp
+++ b/ndn-cxx/lp/field-decl.hpp
@@ -102,7 +102,7 @@
       NDN_THROW(ndn::tlv::Error("NDNLP field of TLV-TYPE " + to_string(wire.type()) +
                                 " cannot be empty"));
     }
-    return std::make_pair(wire.value_begin(), wire.value_end());
+    return {wire.value_begin(), wire.value_end()};
   }
 };
 
diff --git a/ndn-cxx/lp/packet.cpp b/ndn-cxx/lp/packet.cpp
index 235a37a..abe8f0c 100644
--- a/ndn-cxx/lp/packet.cpp
+++ b/ndn-cxx/lp/packet.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).
  *
@@ -134,7 +134,7 @@
 {
   if (wire.type() == ndn::tlv::Interest || wire.type() == ndn::tlv::Data) {
     m_wire = Block(tlv::LpPacket);
-    add<FragmentField>(make_pair(wire.begin(), wire.end()));
+    add<FragmentField>({wire.begin(), wire.end()});
     return;
   }
 
diff --git a/ndn-cxx/lp/pit-token.hpp b/ndn-cxx/lp/pit-token.hpp
index fa61593..413bf7c 100644
--- a/ndn-cxx/lp/pit-token.hpp
+++ b/ndn-cxx/lp/pit-token.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).
  *
@@ -56,7 +56,7 @@
   operator std::pair<Buffer::const_iterator, Buffer::const_iterator>() const
   {
     validate();
-    return std::make_pair(begin(), end());
+    return {begin(), end()};
   }
 
 private:
diff --git a/ndn-cxx/mgmt/nfd/control-command.cpp b/ndn-cxx/mgmt/nfd/control-command.cpp
index df3c95b..794856d 100644
--- a/ndn-cxx/mgmt/nfd/control-command.cpp
+++ b/ndn-cxx/mgmt/nfd/control-command.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,11 +60,10 @@
 {
   this->validateRequest(parameters);
 
-  const auto& paramBlock = parameters.wireEncode();
   return Name(commandPrefix)
          .append(m_module)
          .append(m_verb)
-         .append(paramBlock.begin(), paramBlock.end());
+         .append(tlv::GenericNameComponent, parameters.wireEncode());
 }
 
 ControlCommand::FieldValidator::FieldValidator()
@@ -329,7 +328,7 @@
 {
   this->ControlCommand::validateRequest(parameters);
 
-  if (parameters.getName().size() == 0) {
+  if (parameters.getName().empty()) {
     NDN_THROW(ArgumentError("Name must not be ndn:/"));
   }
 }
diff --git a/ndn-cxx/mgmt/nfd/status-dataset.cpp b/ndn-cxx/mgmt/nfd/status-dataset.cpp
index 1c550af..616f16e 100644
--- a/ndn-cxx/mgmt/nfd/status-dataset.cpp
+++ b/ndn-cxx/mgmt/nfd/status-dataset.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).
  *
@@ -55,7 +55,7 @@
  */
 template<typename T>
 static std::vector<T>
-parseDatasetVector(ConstBufferPtr payload)
+parseDatasetVector(const ConstBufferPtr& payload)
 {
   BOOST_CONCEPT_ASSERT((WireDecodable<T>));
 
@@ -96,7 +96,7 @@
 FaceDatasetBase::ResultType
 FaceDatasetBase::parseResult(ConstBufferPtr payload) const
 {
-  return parseDatasetVector<FaceStatus>(std::move(payload));
+  return parseDatasetVector<FaceStatus>(payload);
 }
 
 FaceDataset::FaceDataset()
@@ -113,8 +113,7 @@
 void
 FaceQueryDataset::addParameters(Name& name) const
 {
-  const auto& filterBlock = m_filter.wireEncode();
-  name.append(filterBlock.begin(), filterBlock.end());
+  name.append(tlv::GenericNameComponent, m_filter.wireEncode());
 }
 
 ChannelDataset::ChannelDataset()
@@ -125,7 +124,7 @@
 ChannelDataset::ResultType
 ChannelDataset::parseResult(ConstBufferPtr payload) const
 {
-  return parseDatasetVector<ChannelStatus>(std::move(payload));
+  return parseDatasetVector<ChannelStatus>(payload);
 }
 
 FibDataset::FibDataset()
@@ -136,7 +135,7 @@
 FibDataset::ResultType
 FibDataset::parseResult(ConstBufferPtr payload) const
 {
-  return parseDatasetVector<FibEntry>(std::move(payload));
+  return parseDatasetVector<FibEntry>(payload);
 }
 
 CsInfoDataset::CsInfoDataset()
@@ -147,7 +146,7 @@
 CsInfoDataset::ResultType
 CsInfoDataset::parseResult(ConstBufferPtr payload) const
 {
-  return CsInfo(Block(std::move(payload)));
+  return CsInfo(Block(payload));
 }
 
 StrategyChoiceDataset::StrategyChoiceDataset()
@@ -158,7 +157,7 @@
 StrategyChoiceDataset::ResultType
 StrategyChoiceDataset::parseResult(ConstBufferPtr payload) const
 {
-  return parseDatasetVector<StrategyChoice>(std::move(payload));
+  return parseDatasetVector<StrategyChoice>(payload);
 }
 
 RibDataset::RibDataset()
@@ -169,7 +168,7 @@
 RibDataset::ResultType
 RibDataset::parseResult(ConstBufferPtr payload) const
 {
-  return parseDatasetVector<RibEntry>(std::move(payload));
+  return parseDatasetVector<RibEntry>(payload);
 }
 
 } // namespace nfd
diff --git a/ndn-cxx/mgmt/status-dataset-context.cpp b/ndn-cxx/mgmt/status-dataset-context.cpp
index 3ada4e6..ebb505b 100644
--- a/ndn-cxx/mgmt/status-dataset-context.cpp
+++ b/ndn-cxx/mgmt/status-dataset-context.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,7 +60,7 @@
 }
 
 void
-StatusDatasetContext::append(const Block& block)
+StatusDatasetContext::append(span<const uint8_t> bytes)
 {
   if (m_state == State::FINALIZED) {
     NDN_THROW(std::logic_error("cannot call append() on a finalized context"));
@@ -68,21 +68,16 @@
 
   m_state = State::RESPONDED;
 
-  auto cur = block.begin();
-  while (cur != block.end()) {
-    auto nBytesToAppend = std::min<std::ptrdiff_t>(std::distance(cur, block.end()),
-                                                   MAX_PAYLOAD_LENGTH - m_buffer.size());
-    auto next = std::next(cur, nBytesToAppend);
-    m_buffer.insert(m_buffer.end(), cur, next);
-    cur = next;
-
-    if (cur != block.end()) {
-      BOOST_ASSERT(m_buffer.size() == MAX_PAYLOAD_LENGTH);
+  while (!bytes.empty()) {
+    if (m_buffer.size() == MAX_PAYLOAD_LENGTH) {
       m_dataSender(Name(m_prefix).appendSegment(m_segmentNo++),
-                   makeBinaryBlock(tlv::Content, m_buffer),
-                   false);
+                   makeBinaryBlock(tlv::Content, m_buffer), false);
       m_buffer.clear();
     }
+
+    auto chunk = bytes.first(std::min(bytes.size(), MAX_PAYLOAD_LENGTH - m_buffer.size()));
+    m_buffer.insert(m_buffer.end(), chunk.begin(), chunk.end());
+    bytes = bytes.subspan(chunk.size());
   }
 }
 
@@ -94,9 +89,10 @@
   }
 
   m_state = State::FINALIZED;
+
+  BOOST_ASSERT(m_buffer.size() <= MAX_PAYLOAD_LENGTH);
   m_dataSender(Name(m_prefix).appendSegment(m_segmentNo),
-               makeBinaryBlock(tlv::Content, m_buffer),
-               true);
+               makeBinaryBlock(tlv::Content, m_buffer), true);
 }
 
 void
diff --git a/ndn-cxx/mgmt/status-dataset-context.hpp b/ndn-cxx/mgmt/status-dataset-context.hpp
index 5f911df..7eb5dcb 100644
--- a/ndn-cxx/mgmt/status-dataset-context.hpp
+++ b/ndn-cxx/mgmt/status-dataset-context.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).
  *
@@ -60,11 +60,11 @@
   setPrefix(const Name& prefix);
 
   /**
-   * \brief Appends a Block to the response.
+   * \brief Appends a sequence of bytes to the response.
    * \throw std::logic_error end() or reject() has already been invoked
    */
   void
-  append(const Block& block);
+  append(span<const uint8_t> bytes);
 
   /**
    * \brief Finalizes the response successfully after appending zero or more blocks.
diff --git a/ndn-cxx/name-component.cpp b/ndn-cxx/name-component.cpp
index 6fb973d..e6eb609 100644
--- a/ndn-cxx/name-component.cpp
+++ b/ndn-cxx/name-component.cpp
@@ -484,7 +484,7 @@
     // it's more efficient to simply compare the wire encoding.
     // This works because lexical order of TLV encoding happens to be
     // the same as canonical order of the value.
-    return std::memcmp(wire(), other.wire(), std::min(size(), other.size()));
+    return std::memcmp(data(), other.data(), std::min(size(), other.size()));
   }
 
   int cmpType = type() - other.type();
@@ -521,8 +521,9 @@
 Component::wireEncode(EncodingImpl<TAG>& encoder) const
 {
   size_t totalLength = 0;
-  if (value_size() > 0)
-    totalLength += encoder.prependBytes({value(), value_size()});
+  if (value_size() > 0) {
+    totalLength += encoder.prependBytes(value_bytes());
+  }
   totalLength += encoder.prependVarNumber(value_size());
   totalLength += encoder.prependVarNumber(type());
   return totalLength;
diff --git a/ndn-cxx/name.cpp b/ndn-cxx/name.cpp
index ec64e14..b8c808b 100644
--- a/ndn-cxx/name.cpp
+++ b/ndn-cxx/name.cpp
@@ -382,8 +382,7 @@
 size_t
 hash<ndn::Name>::operator()(const ndn::Name& name) const
 {
-  return boost::hash_range(name.wireEncode().wire(),
-                           name.wireEncode().wire() + name.wireEncode().size());
+  return boost::hash_range(name.wireEncode().begin(), name.wireEncode().end());
 }
 
 } // namespace std
diff --git a/ndn-cxx/security/certificate.cpp b/ndn-cxx/security/certificate.cpp
index b033282..de46a44 100644
--- a/ndn-cxx/security/certificate.cpp
+++ b/ndn-cxx/security/certificate.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).
  *
@@ -105,8 +105,9 @@
 Certificate::getPublicKey() const
 {
   if (getContent().value_size() == 0)
-    NDN_THROW(Data::Error("Content is empty"));
-  return Buffer(getContent().value(), getContent().value_size());
+    NDN_THROW(Data::Error("Certificate Content is empty"));
+
+  return {getContent().value_begin(), getContent().value_end()};
 }
 
 ValidityPeriod
diff --git a/ndn-cxx/security/key-chain.cpp b/ndn-cxx/security/key-chain.cpp
index 07828cb..2cc22ed 100644
--- a/ndn-cxx/security/key-chain.cpp
+++ b/ndn-cxx/security/key-chain.cpp
@@ -476,8 +476,7 @@
     signedName.append(sigInfoBlock.begin(), sigInfoBlock.end()); // SignatureInfo
 
     Block sigValue(tlv::SignatureValue,
-                   sign({{signedName.wireEncode().value(), signedName.wireEncode().value_size()}},
-                        keyName, params.getDigestAlgorithm()));
+                   sign({signedName.wireEncode().value_bytes()}, keyName, params.getDigestAlgorithm()));
     sigValue.encode();
     signedName.append(sigValue.begin(), sigValue.end()); // SignatureValue
 
diff --git a/ndn-cxx/security/pib/impl/pib-memory.cpp b/ndn-cxx/security/pib/impl/pib-memory.cpp
index 65f729f..3abade7 100644
--- a/ndn-cxx/security/pib/impl/pib-memory.cpp
+++ b/ndn-cxx/security/pib/impl/pib-memory.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).
  *
@@ -126,7 +126,7 @@
 bool
 PibMemory::hasKey(const Name& keyName) const
 {
-  return (m_keys.count(keyName) > 0);
+  return m_keys.count(keyName) > 0;
 }
 
 void
@@ -212,8 +212,7 @@
   const Name& certName = certificate.getName();
   const Name& keyName = certificate.getKeyName();
 
-  const auto& content = certificate.getContent();
-  addKey(certificate.getIdentity(), keyName, {content.value(), content.value_size()});
+  addKey(certificate.getIdentity(), keyName, certificate.getContent().value_bytes());
 
   m_certs[certName] = certificate;
   if (m_defaultCerts.count(keyName) == 0) {
diff --git a/ndn-cxx/security/pib/impl/pib-sqlite3.cpp b/ndn-cxx/security/pib/impl/pib-sqlite3.cpp
index 7b00591..c994eae 100644
--- a/ndn-cxx/security/pib/impl/pib-sqlite3.cpp
+++ b/ndn-cxx/security/pib/impl/pib-sqlite3.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).
  *
@@ -485,9 +485,7 @@
 PibSqlite3::addCertificate(const Certificate& certificate)
 {
   // ensure key exists
-  const auto& content = certificate.getContent();
-  addKey(certificate.getIdentity(), certificate.getKeyName(),
-         {content.value(), content.value_size()});
+  addKey(certificate.getIdentity(), certificate.getKeyName(), certificate.getContent().value_bytes());
 
   if (!hasCertificate(certificate.getName())) {
     Sqlite3Statement statement(m_database,
diff --git a/ndn-cxx/security/tpm/impl/back-end-file.cpp b/ndn-cxx/security/tpm/impl/back-end-file.cpp
index b1914b7..67d23ab 100644
--- a/ndn-cxx/security/tpm/impl/back-end-file.cpp
+++ b/ndn-cxx/security/tpm/impl/back-end-file.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).
  *
@@ -74,7 +74,7 @@
     std::ostringstream os;
     {
       using namespace transform;
-      bufferSource(make_span(keyName.wireEncode().wire(), keyName.wireEncode().size()))
+      bufferSource(keyName.wireEncode())
         >> digestFilter(DigestAlgorithm::SHA256)
         >> hexEncode()
         >> streamSink(os);
diff --git a/ndn-cxx/security/validity-period.cpp b/ndn-cxx/security/validity-period.cpp
index 554d2c1..fbe0430 100644
--- a/ndn-cxx/security/validity-period.cpp
+++ b/ndn-cxx/security/validity-period.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).
  *
@@ -140,7 +140,7 @@
 std::pair<time::system_clock::TimePoint, time::system_clock::TimePoint>
 ValidityPeriod::getPeriod() const
 {
-  return std::make_pair(m_notBefore, m_notAfter);
+  return {m_notBefore, m_notAfter};
 }
 
 bool
diff --git a/ndn-cxx/security/verification-helpers.cpp b/ndn-cxx/security/verification-helpers.cpp
index 2a8cd29..8e342ac 100644
--- a/ndn-cxx/security/verification-helpers.cpp
+++ b/ndn-cxx/security/verification-helpers.cpp
@@ -94,12 +94,11 @@
 parse(const Data& data)
 {
   try {
-    return ParseResult(data.getSignatureInfo(),
-                       data.extractSignedRanges(),
-                       {data.getSignatureValue().value(), data.getSignatureValue().value_size()});
+    return {data.getSignatureInfo(), data.extractSignedRanges(),
+            data.getSignatureValue().value_bytes()};
   }
   catch (const tlv::Error&) {
-    return ParseResult();
+    return {};
   }
 }
 
@@ -111,30 +110,27 @@
 
     if (interest.getSignatureInfo() && interest.getSignatureValue().isValid()) {
       // Verify using v0.3 Signed Interest semantics
-      Block sigValue = interest.getSignatureValue();
-      return ParseResult(*interest.getSignatureInfo(),
-                         interest.extractSignedRanges(),
-                         {sigValue.value(), sigValue.value_size()});
+      return {*interest.getSignatureInfo(), interest.extractSignedRanges(),
+              interest.getSignatureValue().value_bytes()};
     }
     else {
       // Verify using older Signed Interest semantics
       const Name& interestName = interest.getName();
       if (interestName.size() < signed_interest::MIN_SIZE) {
-        return ParseResult();
+        return {};
       }
 
       const Block& nameBlock = interestName.wireEncode();
       SignatureInfo info(interestName[signed_interest::POS_SIG_INFO].blockFromValue());
       Block sigValue(interestName[signed_interest::POS_SIG_VALUE].blockFromValue());
-      return ParseResult(info,
-                         {{nameBlock.value(),
-                           nameBlock.value_size() - interestName[signed_interest::POS_SIG_VALUE].size()}},
-                         {sigValue.value(),
-                          sigValue.value_size()});
+      return {info,
+              {{nameBlock.value(),
+                nameBlock.value_size() - interestName[signed_interest::POS_SIG_VALUE].size()}},
+              sigValue.value_bytes()};
     }
   }
   catch (const tlv::Error&) {
-    return ParseResult();
+    return {};
   }
 }
 
@@ -223,7 +219,7 @@
 {
   auto parsed = parse(data);
   if (cert) {
-    return verifySignature(parsed, {cert->getContent().value(), cert->getContent().value_size()});
+    return verifySignature(parsed, cert->getContent().value_bytes());
   }
   else if (parsed.info.getSignatureType() == tlv::SignatureTypeValue::DigestSha256) {
     return verifyDigest(parsed, DigestAlgorithm::SHA256);
@@ -239,7 +235,7 @@
 {
   auto parsed = parse(interest);
   if (cert) {
-    return verifySignature(parsed, {cert->getContent().value(), cert->getContent().value_size()});
+    return verifySignature(parsed, cert->getContent().value_bytes());
   }
   else if (parsed.info.getSignatureType() == tlv::SignatureTypeValue::DigestSha256) {
     return verifyDigest(parsed, DigestAlgorithm::SHA256);
diff --git a/ndn-cxx/util/dummy-client-face.cpp b/ndn-cxx/util/dummy-client-face.cpp
index 69e6dc5..f187b12 100644
--- a/ndn-cxx/util/dummy-client-face.cpp
+++ b/ndn-cxx/util/dummy-client-face.cpp
@@ -263,7 +263,7 @@
   lp::Packet lpPacket;
   lpPacket.add<lp::NackField>(nack.getHeader());
   Block interest = nack.getInterest().wireEncode();
-  lpPacket.add<lp::FragmentField>(make_pair(interest.begin(), interest.end()));
+  lpPacket.add<lp::FragmentField>({interest.begin(), interest.end()});
 
   addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, nack);
   addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, nack);
diff --git a/ndn-cxx/util/io.hpp b/ndn-cxx/util/io.hpp
index 5d80ede..576f3f8 100644
--- a/ndn-cxx/util/io.hpp
+++ b/ndn-cxx/util/io.hpp
@@ -185,7 +185,7 @@
     NDN_THROW_NESTED(Error("Encode error during save: "s + e.what()));
   }
 
-  saveBuffer({block.wire(), block.size()}, os, encoding);
+  saveBuffer(block, os, encoding);
 }
 
 /** \brief Writes a TLV element to a file.
diff --git a/ndn-cxx/util/sha256.cpp b/ndn-cxx/util/sha256.cpp
index d24e8d1..7af7e58 100644
--- a/ndn-cxx/util/sha256.cpp
+++ b/ndn-cxx/util/sha256.cpp
@@ -100,16 +100,16 @@
 }
 
 Sha256&
-Sha256::operator<<(const Block& block)
+Sha256::operator<<(uint64_t value)
 {
-  update({block.wire(), block.size()});
+  update({reinterpret_cast<const uint8_t*>(&value), sizeof(uint64_t)});
   return *this;
 }
 
 Sha256&
-Sha256::operator<<(uint64_t value)
+Sha256::operator<<(span<const uint8_t> bytes)
 {
-  update({reinterpret_cast<const uint8_t*>(&value), sizeof(uint64_t)});
+  update(bytes);
   return *this;
 }
 
diff --git a/ndn-cxx/util/sha256.hpp b/ndn-cxx/util/sha256.hpp
index 745e706..e86d5ce 100644
--- a/ndn-cxx/util/sha256.hpp
+++ b/ndn-cxx/util/sha256.hpp
@@ -126,13 +126,6 @@
   operator<<(const std::string& str);
 
   /**
-   * @brief Add a block to the digest calculation.
-   * @throw Error the digest has already been finalized
-   */
-  Sha256&
-  operator<<(const Block& block);
-
-  /**
    * @brief Add a uint64_t value to the digest calculation.
    * @throw Error the digest has already been finalized
    */
@@ -140,6 +133,13 @@
   operator<<(uint64_t value);
 
   /**
+   * @brief Add a contiguous range of arbitrary bytes to the digest calculation.
+   * @throw Error the digest has already been finalized
+   */
+  Sha256&
+  operator<<(span<const uint8_t> bytes);
+
+  /**
    * @brief Add a byte buffer to the digest calculation.
    * @throw Error the digest has already been finalized
    */
diff --git a/ndn-cxx/util/sqlite3-statement.cpp b/ndn-cxx/util/sqlite3-statement.cpp
index 709ea51..c7f7354 100644
--- a/ndn-cxx/util/sqlite3-statement.cpp
+++ b/ndn-cxx/util/sqlite3-statement.cpp
@@ -59,7 +59,7 @@
 int
 Sqlite3Statement::bind(int index, const Block& block, void(*destructor)(void*))
 {
-  return sqlite3_bind_blob(m_stmt, index, block.wire(), block.size(), destructor);
+  return sqlite3_bind_blob(m_stmt, index, block.data(), block.size(), destructor);
 }
 
 int
diff --git a/tests/unit/data.t.cpp b/tests/unit/data.t.cpp
index 0a4c9b7..6ee1708 100644
--- a/tests/unit/data.t.cpp
+++ b/tests/unit/data.t.cpp
@@ -196,10 +196,10 @@
     tr::StepSource input;
     input >> tr::signerFilter(DigestAlgorithm::SHA256, m_privKey) >> tr::streamSink(sig);
 
-    input.write({d.getName().    wireEncode().wire(), d.getName().    wireEncode().size()});
-    input.write({d.getMetaInfo().wireEncode().wire(), d.getMetaInfo().wireEncode().size()});
-    input.write({d.getContent().              wire(), d.getContent().              size()});
-    input.write({signatureInfo.  wireEncode().wire(), signatureInfo.  wireEncode().size()});
+    input.write(d.getName().wireEncode());
+    input.write(d.getMetaInfo().wireEncode());
+    input.write(d.getContent());
+    input.write(signatureInfo.wireEncode());
     input.end();
   }
   d.setSignatureValue(sig.buf());
@@ -288,8 +288,7 @@
   BOOST_CHECK_EQUAL(d.getFreshnessPeriod(), 10_s);
   BOOST_CHECK_EQUAL(d.getFinalBlock().has_value(), false);
   BOOST_CHECK_EQUAL(d.hasContent(), true);
-  BOOST_CHECK_EQUAL(std::string(reinterpret_cast<const char*>(d.getContent().value()),
-                                d.getContent().value_size()), "SUCCESS!");
+  BOOST_CHECK_EQUAL(readString(d.getContent()), "SUCCESS!");
   BOOST_CHECK_EQUAL(d.getSignatureType(), tlv::SignatureSha256WithRsa);
   BOOST_REQUIRE(d.getKeyLocator().has_value());
   BOOST_CHECK_EQUAL(d.getKeyLocator()->getName(), "/test/key/locator");
diff --git a/tests/unit/encoding/block.t.cpp b/tests/unit/encoding/block.t.cpp
index e7c8bac..2c75944 100644
--- a/tests/unit/encoding/block.t.cpp
+++ b/tests/unit/encoding/block.t.cpp
@@ -53,12 +53,13 @@
   BOOST_CHECK_EQUAL(b.type(), tlv::Invalid);
   BOOST_CHECK_EQUAL(b.hasValue(), false);
   BOOST_CHECK_EQUAL(b.value_size(), 0);
+  BOOST_CHECK_EQUAL(b.value_bytes().empty(), true);
   BOOST_CHECK(b.value() == nullptr);
 
-  BOOST_CHECK_THROW(b.size(), Block::Error);
   BOOST_CHECK_THROW(b.begin(), Block::Error);
   BOOST_CHECK_THROW(b.end(), Block::Error);
-  BOOST_CHECK_THROW(b.wire(), Block::Error);
+  BOOST_CHECK_THROW(b.data(), Block::Error);
+  BOOST_CHECK_THROW(b.size(), Block::Error);
   BOOST_CHECK_THROW(b.blockFromValue(), Block::Error);
 }
 
@@ -91,7 +92,7 @@
   Block block(buf);
 
   Block derivedBlock(block, block.begin(), block.end());
-  BOOST_CHECK_EQUAL(derivedBlock.wire(), block.wire()); // pointers should match
+  BOOST_CHECK_EQUAL(derivedBlock.data(), block.data()); // pointers should match
   BOOST_CHECK_EQUAL(derivedBlock, block); // blocks should match
 
   derivedBlock = Block(block, block.begin() + 2, block.begin() + 5);
@@ -150,6 +151,7 @@
   BOOST_CHECK_EQUAL(b1.size(), 2); // 1-octet TLV-TYPE and 1-octet TLV-LENGTH
   BOOST_CHECK_EQUAL(b1.hasValue(), false);
   BOOST_CHECK_EQUAL(b1.value_size(), 0);
+  BOOST_CHECK_EQUAL(b1.value_bytes().empty(), true);
   BOOST_CHECK(b1.value() == nullptr);
 
   Block b2(258);
@@ -158,6 +160,7 @@
   BOOST_CHECK_EQUAL(b2.size(), 4); // 3-octet TLV-TYPE and 1-octet TLV-LENGTH
   BOOST_CHECK_EQUAL(b2.hasValue(), false);
   BOOST_CHECK_EQUAL(b2.value_size(), 0);
+  BOOST_CHECK_EQUAL(b2.value_bytes().empty(), true);
   BOOST_CHECK(b2.value() == nullptr);
 
   Block b3(tlv::Invalid);
@@ -168,6 +171,7 @@
   });
   BOOST_CHECK_EQUAL(b3.hasValue(), false);
   BOOST_CHECK_EQUAL(b3.value_size(), 0);
+  BOOST_CHECK_EQUAL(b3.value_bytes().empty(), true);
   BOOST_CHECK(b3.value() == nullptr);
 }
 
@@ -182,6 +186,8 @@
   BOOST_CHECK_EQUAL(b1.size(), 6);
   BOOST_CHECK_EQUAL(b1.hasValue(), true);
   BOOST_CHECK_EQUAL(b1.value_size(), sizeof(VALUE));
+  BOOST_CHECK_EQUAL(b1.value_bytes().size(), sizeof(VALUE));
+  BOOST_CHECK_EQUAL(b1.value_bytes().front(), 0x11);
   BOOST_CHECK(b1.value() != nullptr);
 
   // empty buffer as TLV-VALUE
@@ -191,6 +197,7 @@
   BOOST_CHECK_EQUAL(b2.size(), 2);
   BOOST_CHECK_EQUAL(b2.hasValue(), true);
   BOOST_CHECK_EQUAL(b2.value_size(), 0);
+  BOOST_CHECK_EQUAL(b2.value_bytes().empty(), true);
   BOOST_CHECK(b2.value() == nullptr);
 }
 
@@ -205,6 +212,8 @@
   BOOST_CHECK_EQUAL(b.size(), 10);
   BOOST_CHECK_EQUAL(b.hasValue(), true);
   BOOST_CHECK_EQUAL(b.value_size(), sizeof(buf));
+  BOOST_CHECK_EQUAL(b.value_bytes().size(), sizeof(buf));
+  BOOST_CHECK_EQUAL(b.value_bytes().front(), 0x80);
   BOOST_CHECK(b.value() != nullptr);
 }
 
@@ -218,21 +227,26 @@
   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_bytes().size(), 1);
+  BOOST_CHECK_EQUAL(*b.data(), 0x42);
   BOOST_CHECK_EQUAL(*b.value(), 0xfa);
+  BOOST_CHECK_EQUAL(b.value_bytes().front(), 0xfa);
 
   b = Block::fromStream(stream);
   BOOST_CHECK_EQUAL(b.type(), 1);
   BOOST_CHECK_EQUAL(b.size(), 3);
   BOOST_CHECK_EQUAL(b.value_size(), 1);
-  BOOST_CHECK_EQUAL(*b.wire(), 0x01);
+  BOOST_CHECK_EQUAL(b.value_bytes().size(), 1);
+  BOOST_CHECK_EQUAL(*b.data(), 0x01);
   BOOST_CHECK_EQUAL(*b.value(), 0xfb);
+  BOOST_CHECK_EQUAL(b.value_bytes().front(), 0xfb);
 
   b = Block::fromStream(stream);
   BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
   BOOST_CHECK_EQUAL(b.size(), 6);
   BOOST_CHECK_EQUAL(b.value_size(), 0);
-  BOOST_CHECK_EQUAL(*b.wire(), 0xfe);
+  BOOST_CHECK_EQUAL(b.value_bytes().size(), 0);
+  BOOST_CHECK_EQUAL(*b.data(), 0xfe);
   BOOST_CHECK(b.value() == nullptr);
 
   BOOST_CHECK(stream.eof());
@@ -282,18 +296,20 @@
   Block b1 = Block::fromStream(stream);
   BOOST_CHECK_EQUAL(b1.type(), 0x70);
   BOOST_CHECK_EQUAL(b1.value_size(), 0);
+  BOOST_CHECK_EQUAL(b1.value_bytes().size(), 0);
   BOOST_CHECK(b1.value() == nullptr);
 
   Block b2 = Block::fromStream(stream);
   BOOST_CHECK_EQUAL(b2.type(), 0x71);
   BOOST_CHECK_EQUAL(b2.value_size(), 3);
+  BOOST_CHECK_EQUAL(b2.value_bytes().size(), 3);
   const uint8_t EXPECTED_VALUE2[] = {0x86, 0x11, 0x24};
-  BOOST_CHECK_EQUAL_COLLECTIONS(b2.value_begin(), b2.value_end(),
-                                EXPECTED_VALUE2, EXPECTED_VALUE2 + sizeof(EXPECTED_VALUE2));
+  BOOST_TEST(b2.value_bytes() == EXPECTED_VALUE2, boost::test_tools::per_element());
 
   Block b3 = Block::fromStream(stream);
   BOOST_CHECK_EQUAL(b3.type(), 0x72);
   BOOST_CHECK_EQUAL(b3.value_size(), 0);
+  BOOST_CHECK_EQUAL(b3.value_bytes().size(), 0);
   BOOST_CHECK(b3.value() == nullptr);
 
   BOOST_CHECK_EXCEPTION(Block::fromStream(stream), tlv::Error, [] (const auto& e) {
@@ -328,8 +344,10 @@
   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_bytes().size(), 1);
+  BOOST_CHECK_EQUAL(*b.data(), 0x42);
   BOOST_CHECK_EQUAL(*b.value(), 0xfa);
+  BOOST_CHECK_EQUAL(b.value_bytes().front(), 0xfa);
   size_t offset = b.size();
 
   std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
@@ -337,8 +355,10 @@
   BOOST_CHECK_EQUAL(b.type(), 1);
   BOOST_CHECK_EQUAL(b.size(), 3);
   BOOST_CHECK_EQUAL(b.value_size(), 1);
-  BOOST_CHECK_EQUAL(*b.wire(),  0x01);
+  BOOST_CHECK_EQUAL(b.value_bytes().size(), 1);
+  BOOST_CHECK_EQUAL(*b.data(), 0x01);
   BOOST_CHECK_EQUAL(*b.value(), 0xfb);
+  BOOST_CHECK_EQUAL(b.value_bytes().front(), 0xfb);
   offset += b.size();
 
   std::tie(isOk, b) = Block::fromBuffer(buffer, offset);
@@ -346,7 +366,8 @@
   BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
   BOOST_CHECK_EQUAL(b.size(), 6);
   BOOST_CHECK_EQUAL(b.value_size(), 0);
-  BOOST_CHECK_EQUAL(*b.wire(),  0xfe);
+  BOOST_CHECK_EQUAL(b.value_bytes().empty(), true);
+  BOOST_CHECK_EQUAL(*b.data(), 0xfe);
   BOOST_CHECK(b.value() == nullptr);
 }
 
@@ -359,8 +380,10 @@
   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_bytes().size(), 1);
+  BOOST_CHECK_EQUAL(*b.data(), 0x42);
   BOOST_CHECK_EQUAL(*b.value(), 0xfa);
+  BOOST_CHECK_EQUAL(b.value_bytes().front(), 0xfa);
   auto offset = b.size();
 
   std::tie(isOk, b) = Block::fromBuffer(make_span(TEST_BUFFER).subspan(offset));
@@ -368,8 +391,10 @@
   BOOST_CHECK_EQUAL(b.type(), 1);
   BOOST_CHECK_EQUAL(b.size(), 3);
   BOOST_CHECK_EQUAL(b.value_size(), 1);
-  BOOST_CHECK_EQUAL(*b.wire(),  0x01);
+  BOOST_CHECK_EQUAL(b.value_bytes().size(), 1);
+  BOOST_CHECK_EQUAL(*b.data(), 0x01);
   BOOST_CHECK_EQUAL(*b.value(), 0xfb);
+  BOOST_CHECK_EQUAL(b.value_bytes().front(), 0xfb);
   offset += b.size();
 
   std::tie(isOk, b) = Block::fromBuffer(make_span(TEST_BUFFER).subspan(offset));
@@ -377,7 +402,8 @@
   BOOST_CHECK_EQUAL(b.type(), 0xffffffff);
   BOOST_CHECK_EQUAL(b.size(), 6);
   BOOST_CHECK_EQUAL(b.value_size(), 0);
-  BOOST_CHECK_EQUAL(*b.wire(),  0xfe);
+  BOOST_CHECK_EQUAL(b.value_bytes().empty(), true);
+  BOOST_CHECK_EQUAL(*b.data(), 0xfe);
   BOOST_CHECK(b.value() == nullptr);
 }
 
@@ -622,7 +648,7 @@
 {
   Block block = "0101A0"_block;
   boost::asio::const_buffer buffer(block);
-  BOOST_CHECK_EQUAL(boost::asio::buffer_cast<const uint8_t*>(buffer), block.wire());
+  BOOST_CHECK_EQUAL(boost::asio::buffer_cast<const uint8_t*>(buffer), block.data());
   BOOST_CHECK_EQUAL(boost::asio::buffer_size(buffer), block.size());
 }
 
diff --git a/tests/unit/ims/in-memory-storage.t.cpp b/tests/unit/ims/in-memory-storage.t.cpp
index 3d9ff1e..f6c2a40 100644
--- a/tests/unit/ims/in-memory-storage.t.cpp
+++ b/tests/unit/ims/in-memory-storage.t.cpp
@@ -270,12 +270,11 @@
 {
   shared_ptr<Data> data = makeData("/digest/compute");
 
-  auto digest1 = util::Sha256::computeDigest({data->wireEncode().wire(), data->wireEncode().size()});
+  auto digest1 = util::Sha256::computeDigest(data->wireEncode());
   BOOST_CHECK_EQUAL(digest1->size(), 32);
 
   InMemoryStorageEntry entry;
   entry.setData(*data);
-
   BOOST_CHECK_EQUAL_COLLECTIONS(digest1->begin(), digest1->end(),
                                 entry.getFullName()[-1].value_begin(),
                                 entry.getFullName()[-1].value_end());
@@ -368,7 +367,7 @@
   shared_ptr<Data> data7 = makeData("/c/c/1");
   ims.insert(*data7);
 
-  auto digest1 = util::Sha256::computeDigest({data->wireEncode().wire(), data->wireEncode().size()});
+  auto digest1 = util::Sha256::computeDigest(data->wireEncode());
 
   Name name("/a");
   ims.erase(name);
diff --git a/tests/unit/interest.t.cpp b/tests/unit/interest.t.cpp
index 495d036..95193ac 100644
--- a/tests/unit/interest.t.cpp
+++ b/tests/unit/interest.t.cpp
@@ -265,7 +265,7 @@
   i2.setNonce(0x4c1ecb4a);
   i2.setApplicationParameters("2404C0C1C2C3"_block);
   i2.setSignatureInfo(si);
-  i2.setSignatureValue(make_shared<Buffer>(sv.value(), sv.value_size()));
+  i2.setSignatureValue(make_shared<Buffer>(sv.value_begin(), sv.value_end()));
   BOOST_CHECK_EQUAL(i2.isParametersDigestValid(), true);
 
   BOOST_TEST(i2.wireEncode() == WIRE, boost::test_tools::per_element());
@@ -906,7 +906,7 @@
 
   // Throws because attempting to set InterestSignatureValue without set InterestSignatureInfo
   Block sv1("2E04 01020304"_block);
-  auto svBuffer1 = make_shared<Buffer>(sv1.value(), sv1.value_size());
+  auto svBuffer1 = make_shared<Buffer>(sv1.value_begin(), sv1.value_end());
   BOOST_CHECK_THROW(i.setSignatureValue(svBuffer1), tlv::Error);
 
   // Simple set/get case for InterestSignatureInfo (no prior set)
@@ -958,7 +958,7 @@
   i.wireEncode();
   BOOST_CHECK_EQUAL(i.hasWire(), true);
   Block sv2("2E04 99887766"_block);
-  auto svBuffer2 = make_shared<Buffer>(sv2.value(), sv2.value_size());
+  auto svBuffer2 = make_shared<Buffer>(sv2.value_begin(), sv2.value_end());
   i.setSignatureValue(svBuffer2);
   BOOST_CHECK_EQUAL(i.hasWire(), false);
   BOOST_CHECK(i.getSignatureInfo() == si2);
@@ -1027,7 +1027,8 @@
   BOOST_CHECK(i.getSignatureInfo() == si);
 
   Block sv("2E04 01020304"_block);
-  i.setSignatureValue(make_shared<Buffer>(sv.value(), sv.value_size())); // updates ParametersDigestSha256Component
+  i.setSignatureValue(make_shared<Buffer>(sv.value_begin(),
+                                          sv.value_end())); // updates ParametersDigestSha256Component
   BOOST_CHECK_EQUAL(i.getName(),
                     "/A/B/C/params-sha256=f649845ef944638390d1c689e2f0618ea02e471eff236110cbeb822d5932d342");
   BOOST_CHECK_EQUAL(i.isParametersDigestValid(), true);
diff --git a/tests/unit/lp/packet.t.cpp b/tests/unit/lp/packet.t.cpp
index 7763f06..588dedf 100644
--- a/tests/unit/lp/packet.t.cpp
+++ b/tests/unit/lp/packet.t.cpp
@@ -95,7 +95,7 @@
   buf[1] = 0xe8;
 
   Packet packet;
-  packet.add<FragmentField>(std::make_pair(buf.begin(), buf.end()));
+  packet.add<FragmentField>({buf.begin(), buf.end()});
   packet.add<SequenceField>(1000);
   Block wire = packet.wireEncode();
   BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
@@ -164,7 +164,7 @@
   frag[1] = 0xe8;
 
   Packet packet;
-  packet.add<FragmentField>(std::make_pair(frag.begin(), frag.end()));
+  packet.add<FragmentField>({frag.begin(), frag.end()});
   packet.add<FragIndexField>(0);
   packet.add<AckField>(2);
   packet.wireEncode();
diff --git a/tests/unit/meta-info.t.cpp b/tests/unit/meta-info.t.cpp
index 56ad239..af8416a 100644
--- a/tests/unit/meta-info.t.cpp
+++ b/tests/unit/meta-info.t.cpp
@@ -139,9 +139,7 @@
 
     block = info2.findAppMetaInfo(tlvType);
     BOOST_REQUIRE(block != nullptr);
-
-    std::string s3(reinterpret_cast<const char*>(block->value()), block->value_size());
-    BOOST_CHECK_EQUAL(s3, ss[i]);
+    BOOST_CHECK_EQUAL(readString(*block), ss[i]);
   }
 }
 
diff --git a/tests/unit/mgmt/dispatcher.t.cpp b/tests/unit/mgmt/dispatcher.t.cpp
index 30b5853..a4897a9 100644
--- a/tests/unit/mgmt/dispatcher.t.cpp
+++ b/tests/unit/mgmt/dispatcher.t.cpp
@@ -398,10 +398,8 @@
 
   content = [&dataInStorage] () -> Block {
     EncodingBuffer encoder;
-    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()});
+    size_t valueLength = encoder.prependBytes(dataInStorage[1].getContent().value_bytes());
+    valueLength += encoder.prependBytes(dataInStorage[0].getContent().value_bytes());
     encoder.prependVarNumber(valueLength);
     encoder.prependVarNumber(tlv::Content);
     return encoder.block();
diff --git a/tests/unit/mgmt/status-dataset-context.t.cpp b/tests/unit/mgmt/status-dataset-context.t.cpp
index 4192337..69b2694 100644
--- a/tests/unit/mgmt/status-dataset-context.t.cpp
+++ b/tests/unit/mgmt/status-dataset-context.t.cpp
@@ -42,7 +42,6 @@
 protected:
   StatusDatasetContextFixture()
     : interest(makeInterest("/test/context/interest"))
-    , contentBlock(makeStringBlock(tlv::Content, "/test/data/content"))
     , context(*interest,
               [this] (auto&&... args) {
                 sendDataHistory.push_back({std::forward<decltype(args)>(args)...});
@@ -60,23 +59,18 @@
     return name.appendSegment(segmentNo);
   }
 
-  Block
+  ConstBufferPtr
   concatenateDataContent() const
   {
-    EncodingBuffer encoder;
-    size_t valueLength = 0;
+    auto buf = std::make_shared<Buffer>();
     for (const auto& args : sendDataHistory) {
-      const auto& content = args.content;
-      valueLength += encoder.appendBytes({content.value(), content.value_size()});
+      buf->insert(buf->end(), args.content.value_begin(), args.content.value_end());
     }
-    encoder.prependVarNumber(valueLength);
-    encoder.prependVarNumber(tlv::Content);
-    return encoder.block();
+    return buf;
   }
 
 protected:
   shared_ptr<Interest> interest;
-  Block contentBlock;
   StatusDatasetContext context;
   std::vector<SendDataArgs> sendDataHistory;
   std::vector<ControlResponse> sendNackHistory;
@@ -125,7 +119,7 @@
 BOOST_AUTO_TEST_CASE(SetValidAfterAppend)
 {
   Name validPrefix = Name(interest->getName()).append("/valid");
-  context.append(contentBlock);
+  context.append({0x12, 0x34});
   BOOST_CHECK_EXCEPTION(context.setPrefix(validPrefix), std::logic_error, [] (const auto& e) {
     return e.what() == "cannot call setPrefix() after append/end/reject"s;
   });
@@ -155,7 +149,8 @@
 
 BOOST_AUTO_TEST_CASE(Basic)
 {
-  context.append(contentBlock);
+  const auto testBlock = makeStringBlock(tlv::Content, "TEST");
+  context.append(testBlock);
   BOOST_CHECK(sendDataHistory.empty()); // end() not called yet
 
   context.end();
@@ -163,19 +158,28 @@
 
   const auto& args = sendDataHistory[0];
   BOOST_CHECK_EQUAL(args.dataName, makeSegmentName(0));
-  BOOST_CHECK_EQUAL(args.content.blockFromValue(), contentBlock);
+  BOOST_CHECK_EQUAL(args.content.blockFromValue(), testBlock);
   BOOST_CHECK_EQUAL(args.isFinalBlock, true);
 }
 
+BOOST_AUTO_TEST_CASE(Empty)
+{
+  context.append({});
+  BOOST_TEST(sendDataHistory.empty()); // end() not called yet
+
+  context.end();
+  BOOST_TEST_REQUIRE(sendDataHistory.size() == 1);
+
+  const auto& args = sendDataHistory[0];
+  BOOST_TEST(args.dataName == makeSegmentName(0));
+  BOOST_TEST(args.content.value_size() == 0);
+  BOOST_TEST(args.isFinalBlock);
+}
+
 BOOST_AUTO_TEST_CASE(Large)
 {
-  const Block largeBlock = [] {
-    Block b(tlv::Content, std::make_shared<const Buffer>(10000));
-    b.encode();
-    return b;
-  }();
-
-  context.append(largeBlock);
+  const std::vector<uint8_t> big(10000, 'A');
+  context.append(big);
   BOOST_CHECK_EQUAL(sendDataHistory.size(), 1);
 
   context.end();
@@ -190,30 +194,31 @@
   BOOST_CHECK_EQUAL(sendDataHistory[1].isFinalBlock, true);
 
   // check data content
-  auto contentLargeBlock = concatenateDataContent();
-  BOOST_CHECK_NO_THROW(contentLargeBlock.parse());
-  BOOST_REQUIRE_EQUAL(contentLargeBlock.elements().size(), 1);
-  BOOST_CHECK_EQUAL(contentLargeBlock.elements()[0], largeBlock);
+  BOOST_TEST(*concatenateDataContent() == big, boost::test_tools::per_element());
 }
 
 BOOST_AUTO_TEST_CASE(MultipleSmall)
 {
-  const size_t nBlocks = 100;
+  const size_t nBlocks = 1000;
+  const auto contentBlock = makeStringBlock(0xFFFF, "Test Data Content");
   for (size_t i = 0 ; i < nBlocks ; i ++) {
     context.append(contentBlock);
   }
   context.end();
 
-  // check data to in-memory storage
-  BOOST_REQUIRE_EQUAL(sendDataHistory.size(), 1);
-  BOOST_CHECK_EQUAL(sendDataHistory[0].dataName, makeSegmentName(0));
-  BOOST_CHECK_EQUAL(sendDataHistory[0].isFinalBlock, true);
+  BOOST_TEST_REQUIRE(sendDataHistory.size() == 3);
+  BOOST_TEST(sendDataHistory[0].dataName == makeSegmentName(0));
+  BOOST_TEST(!sendDataHistory[0].isFinalBlock);
+  BOOST_TEST(sendDataHistory[1].dataName == makeSegmentName(1));
+  BOOST_TEST(!sendDataHistory[1].isFinalBlock);
+  BOOST_TEST(sendDataHistory[2].dataName == makeSegmentName(2));
+  BOOST_TEST(sendDataHistory[2].isFinalBlock);
 
-  auto contentMultiBlocks = concatenateDataContent();
+  Block contentMultiBlocks(tlv::Content, concatenateDataContent());
   contentMultiBlocks.parse();
-  BOOST_CHECK_EQUAL(contentMultiBlocks.elements().size(), nBlocks);
+  BOOST_TEST(contentMultiBlocks.elements().size() == nBlocks);
   for (const auto& element : contentMultiBlocks.elements()) {
-    BOOST_CHECK_EQUAL(element, contentBlock);
+    BOOST_TEST(element == contentBlock, boost::test_tools::per_element());
   }
 }
 
@@ -236,8 +241,7 @@
 
 BOOST_AUTO_TEST_CASE(AppendReject)
 {
-  const uint8_t buf[] = {0x82, 0x01, 0x02};
-  BOOST_CHECK_NO_THROW(context.append(Block(buf)));
+  BOOST_CHECK_NO_THROW(context.append({0x82, 0x01, 0x02}));
   BOOST_CHECK_EXCEPTION(context.reject(), std::logic_error, [] (const auto& e) {
     return e.what() == "cannot call reject() after append/end"s;
   });
@@ -245,8 +249,7 @@
 
 BOOST_AUTO_TEST_CASE(AppendEndReject)
 {
-  const uint8_t buf[] = {0x82, 0x01, 0x02};
-  BOOST_CHECK_NO_THROW(context.append(Block(buf)));
+  BOOST_CHECK_NO_THROW(context.append({0x82, 0x01, 0x02}));
   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;
@@ -256,8 +259,7 @@
 BOOST_AUTO_TEST_CASE(EndAppend)
 {
   BOOST_CHECK_NO_THROW(context.end());
-  const uint8_t buf[] = {0x82, 0x01, 0x02};
-  BOOST_CHECK_EXCEPTION(context.append(Block(buf)), std::logic_error, [] (const auto& e) {
+  BOOST_CHECK_EXCEPTION(context.append({0x82, 0x01, 0x02}), std::logic_error, [] (const auto& e) {
     return e.what() == "cannot call append() on a finalized context"s;
   });
 }
@@ -281,8 +283,7 @@
 BOOST_AUTO_TEST_CASE(RejectAppend)
 {
   BOOST_CHECK_NO_THROW(context.reject());
-  const uint8_t buf[] = {0x82, 0x01, 0x02};
-  BOOST_CHECK_EXCEPTION(context.append(Block(buf)), std::logic_error, [] (const auto& e) {
+  BOOST_CHECK_EXCEPTION(context.append({0x82, 0x01, 0x02}), std::logic_error, [] (const auto& e) {
     return e.what() == "cannot call append() on a finalized context"s;
   });
 }
diff --git a/tests/unit/security/additional-description.t.cpp b/tests/unit/security/additional-description.t.cpp
index 56a9090..2779816 100644
--- a/tests/unit/security/additional-description.t.cpp
+++ b/tests/unit/security/additional-description.t.cpp
@@ -72,10 +72,7 @@
   it++;
   BOOST_CHECK(it == aDescription.end());
 
-  BOOST_CHECK_EQUAL_COLLECTIONS(aDescription.wireEncode().wire(),
-                                aDescription.wireEncode().wire() + aDescription.wireEncode().size(),
-                                DESC,
-                                DESC + sizeof(DESC));
+  BOOST_TEST(aDescription.wireEncode() == DESC, boost::test_tools::per_element());
 
   AdditionalDescription aDescription2(Block{DESC});
   BOOST_CHECK_EQUAL(aDescription2, aDescription);
diff --git a/tests/unit/security/detail/certificate-bundle-decoder.t.cpp b/tests/unit/security/detail/certificate-bundle-decoder.t.cpp
index 630aaec..1199994 100644
--- a/tests/unit/security/detail/certificate-bundle-decoder.t.cpp
+++ b/tests/unit/security/detail/certificate-bundle-decoder.t.cpp
@@ -99,7 +99,7 @@
 {
   // First segment contains first 250 bytes of cert1
   Data d;
-  d.setContent(make_span(certBlock1.wire(), 250));
+  d.setContent(make_span(certBlock1).first(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());
diff --git a/tests/unit/security/pib/pib-data-fixture.cpp b/tests/unit/security/pib/pib-data-fixture.cpp
index 37e1e6d..4fb5e36 100644
--- a/tests/unit/security/pib/pib-data-fixture.cpp
+++ b/tests/unit/security/pib/pib-data-fixture.cpp
@@ -63,7 +63,7 @@
 
 //         EncodingBuffer buf;
 //         cert.wireEncode(buf, true);
-//         cert.setSignatureValue(tpm.sign(buf.buf(), buf.size(), keyName, DigestAlgorithm::SHA256));
+//         cert.setSignatureValue(tpm.sign({buf}, keyName, DigestAlgorithm::SHA256));
 
 //         printBytes(prefix + "_KEY" + to_string(keyId) + "_CERT" + to_string(certVersion),
 //                    cert.wireEncode());
@@ -72,18 +72,12 @@
 //   }
 
 //   static void
-//   printBytes(const std::string& name, const Block& block)
-//   {
-//     printBytes(name, make_span(block.wire(), block.size()));
-//   }
-
-//   static void
-//   printBytes(const std::string& name, span<const uint8_t> buf)
+//   printBytes(const std::string& name, span<const uint8_t> bytes)
 //   {
 //     std::cout << "\nconst uint8_t " << name << "[] = {\n"
 //               << "  ";
 
-//     std::string hex = toHex(buf);
+//     std::string hex = toHex(bytes);
 
 //     for (size_t i = 0; i < hex.size(); i++) {
 //       if (i > 0 && i % 40 == 0)
diff --git a/tests/unit/security/validation-policy-config.t.cpp b/tests/unit/security/validation-policy-config.t.cpp
index 32fbf01..83c6f52 100644
--- a/tests/unit/security/validation-policy-config.t.cpp
+++ b/tests/unit/security/validation-policy-config.t.cpp
@@ -247,7 +247,7 @@
     {
       using namespace ndn::security::transform;
       const auto& cert = this->identity.getDefaultKey().getDefaultCertificate().wireEncode();
-      bufferSource(make_span(cert.wire(), cert.size())) >> base64Encode(false) >> streamSink(os);
+      bufferSource(cert) >> base64Encode(false) >> streamSink(os);
     }
 
     this->policy.load(this->baseConfig + R"CONF(
diff --git a/tests/unit/security/validation-policy-simple-hierarchy.t.cpp b/tests/unit/security/validation-policy-simple-hierarchy.t.cpp
index d5734a8..70fb49e 100644
--- a/tests/unit/security/validation-policy-simple-hierarchy.t.cpp
+++ b/tests/unit/security/validation-policy-simple-hierarchy.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).
  *
@@ -73,15 +73,15 @@
 
 BOOST_AUTO_TEST_CASE(NonKeyNameInsideLocator)
 {
-  // auto cert = identity.getDefaultKey().getDefaultCertificate().wireEncode();
-  // std::cerr << "Certificate idCert{\"" << toHex(cert.wire(), cert.size()) << "\"_block};" << std::endl;
+//  auto cert = identity.getDefaultKey().getDefaultCertificate().wireEncode();
+//  std::cerr << "Certificate idCert{\"" << toHex(cert) << "\"_block};" << std::endl;
 
-  // cert = subIdentity.getDefaultKey().getDefaultCertificate().wireEncode();
-  // std::cerr << "Certificate subIdCert{\"" << toHex(cert.wire(), cert.size()) << "\"_block};" << std::endl;
+//  cert = subIdentity.getDefaultKey().getDefaultCertificate().wireEncode();
+//  std::cerr << "Certificate subIdCert{\"" << toHex(cert) << "\"_block};" << std::endl;
 
-  // Data packet("/Security/ValidatorFixture/Sub1/Sub2/Packet");
-  // m_keyChain.sign(packet, signingByIdentity(subIdentity));
-  // std::cerr << "Data packet{\"" << toHex(packet.wireEncode().wire(), packet.wireEncode().size()) << "\"_block};" << std::endl;
+//  Data pkt("/Security/ValidatorFixture/Sub1/Sub2/Packet");
+//  m_keyChain.sign(pkt, signingByIdentity(subIdentity));
+//  std::cerr << "Data packet{\"" << toHex(pkt.wireEncode()) << "\"_block};" << std::endl;
 
   // These are hard-coded with a key locator that is the exact name of the certificate
   Certificate idCert{"06FD014C073C08085365637572697479081056616C696461746F724669787475726508034B455"
diff --git a/tests/unit/security/verification-helpers.t.cpp b/tests/unit/security/verification-helpers.t.cpp
index d15f8f2..79cc41c 100644
--- a/tests/unit/security/verification-helpers.t.cpp
+++ b/tests/unit/security/verification-helpers.t.cpp
@@ -48,10 +48,10 @@
 //     {"Sha256", signingWithSha256()}
 //   };
 
-//   auto print = [] (const std::string& name, const uint8_t* buf, size_t size) {
+//   auto print = [] (const std::string& name, span<const uint8_t> buf) {
 //     std::cout << "  const Block " + name + "{{\n    ";
 
-//     std::string hex = toHex({buf, size});
+//     std::string hex = toHex(buf);
 
 //     for (size_t i = 0; i < hex.size(); i++) {
 //       if (i > 0 && i % 32 == 0)
@@ -74,23 +74,22 @@
 //     std::cout << "  const std::string name = \"" << type << "\";\n";
 
 //     if (signingInfo.getSignerType() == SigningInfo::SIGNER_TYPE_ID) {
-//       print("cert", signingInfo.getPibIdentity().getDefaultKey().getDefaultCertificate().wireEncode().wire(),
-//             signingInfo.getPibIdentity().getDefaultKey().getDefaultCertificate().wireEncode().size());
+//       print("cert", signingInfo.getPibIdentity().getDefaultKey().getDefaultCertificate().wireEncode());
 //     }
 //     else {
-//       print("cert", nullptr, 0);
+//       print("cert", {});
 //     }
 //     std::cout << "\n";
 
 //     // Create data that can be verified by cert
 //     Data data(Name("/test/data").append(type));
 //     m_keyChain.sign(data, signingInfo);
-//     print("goodData", data.wireEncode().wire(), data.wireEncode().size());
+//     print("goodData", data.wireEncode());
 //     std::cout << "\n";
 
 //     // Create data that cannot be verified by cert
 //     m_keyChain.sign(data, signingByIdentity(wrongIdentity));
-//     print("badSigData", data.wireEncode().wire(), data.wireEncode().size());
+//     print("badSigData", data.wireEncode());
 //     std::cout << "\n";
 
 //     // Create interest that can be verified by cert
@@ -99,13 +98,13 @@
 //     signingInfoV03.setSignedInterestFormat(SignedInterestFormat::V03);
 //     interest1.setNonce(0xF72C8A4B);
 //     m_keyChain.sign(interest1, signingInfoV03);
-//     print("goodInterest", interest1.wireEncode().wire(), interest1.wireEncode().size());
+//     print("goodInterest", interest1.wireEncode());
 //     std::cout << "\n";
 
 //     // Create interest that cannot be verified by cert
 //     m_keyChain.sign(interest1, signingByIdentity(wrongIdentity)
 //                                  .setSignedInterestFormat(SignedInterestFormat::V03));
-//     print("badSigInterest", interest1.wireEncode().wire(), interest1.wireEncode().size());
+//     print("badSigInterest", interest1.wireEncode());
 //     std::cout << "\n";
 
 //     // Create interest that can be verified by cert (old signed Interest format)
@@ -114,13 +113,13 @@
 //     signingInfoV02.setSignedInterestFormat(SignedInterestFormat::V03);
 //     interest2.setNonce(0xF72C8A4B);
 //     m_keyChain.sign(interest2, signingInfoV02);
-//     print("goodInterestOldFormat", interest2.wireEncode().wire(), interest2.wireEncode().size());
+//     print("goodInterestOldFormat", interest2.wireEncode());
 //     std::cout << "\n";
 
 //     // Create interest that cannot be verified by cert (old signed Interest format)
 //     m_keyChain.sign(interest2, signingByIdentity(wrongIdentity)
 //                                  .setSignedInterestFormat(SignedInterestFormat::V02));
-//     print("badSigInterestOldFormat", interest2.wireEncode().wire(), interest2.wireEncode().size());
+//     print("badSigInterestOldFormat", interest2.wireEncode());
 //     std::cout << "\n};\n\n";
 //   }
 // }
diff --git a/tests/unit/signature-info.t.cpp b/tests/unit/signature-info.t.cpp
index 11fdff1..dff4241 100644
--- a/tests/unit/signature-info.t.cpp
+++ b/tests/unit/signature-info.t.cpp
@@ -434,8 +434,7 @@
   // encode
   auto encoded = info.wireEncode();
   BOOST_CHECK_EQUAL(info.hasWire(), true);
-  BOOST_CHECK_EQUAL_COLLECTIONS(sigInfo, sigInfo + sizeof(sigInfo),
-                                encoded.wire(), encoded.wire() + encoded.size());
+  BOOST_TEST(encoded == sigInfo, boost::test_tools::per_element());
 
   info.setValidityPeriod(vp1);
   BOOST_CHECK_EQUAL(info.hasWire(), true);
diff --git a/tests/unit/util/io.t.cpp b/tests/unit/util/io.t.cpp
index ebe5799..270270c 100644
--- a/tests/unit/util/io.t.cpp
+++ b/tests/unit/util/io.t.cpp
@@ -187,10 +187,7 @@
   void
   wireDecode(const Block& block)
   {
-    // block must be 0xBB, 0x01, 0xEE
-    BOOST_CHECK_EQUAL(block.type(), 0xBB);
-    BOOST_REQUIRE_EQUAL(block.value_size(), 1);
-    BOOST_CHECK_EQUAL(block.value()[0], 0xEE);
+    BOOST_TEST(block == "BB01EE"_block);
   }
 };
 
diff --git a/tests/unit/util/sha256.t.cpp b/tests/unit/util/sha256.t.cpp
index ae4fea3..c5fd1fd 100644
--- a/tests/unit/util/sha256.t.cpp
+++ b/tests/unit/util/sha256.t.cpp
@@ -112,7 +112,22 @@
   BOOST_TEST(*digest == *expected, boost::test_tools::per_element());
 }
 
-BOOST_AUTO_TEST_CASE(InsertionOperatorBlock)
+BOOST_AUTO_TEST_CASE(InsertionOperatorUnsignedInt)
+{
+  const uint64_t input[] = {1, 2, 3, 4};
+  auto expected = fromHex("7236c00c170036c6de133a878210ddd58567aa1d0619a0f70f69e38ae6f916e9");
+
+  Sha256 statefulSha256;
+  for (size_t i = 0; i < sizeof(input) / sizeof(uint64_t); ++i) {
+    statefulSha256 << boost::endian::native_to_big(input[i]);
+  }
+  ConstBufferPtr digest = statefulSha256.computeDigest();
+
+  BOOST_CHECK_EQUAL(statefulSha256.empty(), false);
+  BOOST_TEST(*digest == *expected, boost::test_tools::per_element());
+}
+
+BOOST_AUTO_TEST_CASE(InsertionOperatorSpan)
 {
   const uint8_t input[] = {
     0x16, 0x1b, // SignatureInfo
@@ -130,22 +145,7 @@
   auto expected = fromHex("b372edfd4d6a4db2cfeaeead6c34fdee9b9e759f7b8d799cf8067e39e7f2886c");
 
   Sha256 statefulSha256;
-  statefulSha256 << Block{input};
-  ConstBufferPtr digest = statefulSha256.computeDigest();
-
-  BOOST_CHECK_EQUAL(statefulSha256.empty(), false);
-  BOOST_TEST(*digest == *expected, boost::test_tools::per_element());
-}
-
-BOOST_AUTO_TEST_CASE(InsertionOperatorUint64t)
-{
-  const uint64_t input[] = {1, 2, 3, 4};
-  auto expected = fromHex("7236c00c170036c6de133a878210ddd58567aa1d0619a0f70f69e38ae6f916e9");
-
-  Sha256 statefulSha256;
-  for (size_t i = 0; i < sizeof(input) / sizeof(uint64_t); ++i) {
-    statefulSha256 << boost::endian::native_to_big(input[i]);
-  }
+  statefulSha256 << input;
   ConstBufferPtr digest = statefulSha256.computeDigest();
 
   BOOST_CHECK_EQUAL(statefulSha256.empty(), false);
@@ -166,14 +166,6 @@
   BOOST_CHECK_NO_THROW(sha << 42);
 }
 
-BOOST_AUTO_TEST_CASE(Error)
-{
-  Sha256 sha;
-  sha << 42;
-  sha.computeDigest(); // finalize
-  BOOST_CHECK_THROW(sha << 42, Sha256::Error);
-}
-
 BOOST_AUTO_TEST_CASE(StaticComputeDigest)
 {
   auto expected = fromHex("9f64a747e1b97f131fabb6b447296c9b6f0201e79fb3c5356e6c77e89b6a806a");
@@ -182,6 +174,14 @@
   BOOST_TEST(*digest == *expected, boost::test_tools::per_element());
 }
 
+BOOST_AUTO_TEST_CASE(Error)
+{
+  Sha256 sha;
+  sha << 42;
+  sha.computeDigest(); // finalize
+  BOOST_CHECK_THROW(sha << 42, Sha256::Error);
+}
+
 BOOST_AUTO_TEST_CASE(Print)
 {
   const uint8_t origin[] = {0x94, 0xEE, 0x05, 0x93, 0x35, 0xE5, 0x87, 0xE5,
diff --git a/tests/unit/util/simple-notification.hpp b/tests/unit/util/simple-notification.hpp
index acfa172..ece2c48 100644
--- a/tests/unit/util/simple-notification.hpp
+++ b/tests/unit/util/simple-notification.hpp
@@ -59,8 +59,7 @@
   void
   wireDecode(const Block& block)
   {
-    m_message.assign(reinterpret_cast<const char*>(block.value()),
-                     block.value_size());
+    m_message = readString(block);
 
     // error for testing
     if (!m_message.empty() && m_message[0] == '\x07')
diff --git a/tests/unit/util/sqlite3-statement.t.cpp b/tests/unit/util/sqlite3-statement.t.cpp
index a78b077..99ea89f 100644
--- a/tests/unit/util/sqlite3-statement.t.cpp
+++ b/tests/unit/util/sqlite3-statement.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).
  *
@@ -98,7 +98,7 @@
 
   {
     Sqlite3Statement stmt(db, "INSERT INTO test VALUES (5, ?)");
-    stmt.bind(1, reinterpret_cast<const void*>(block.wire()), block.size(), SQLITE_STATIC);
+    stmt.bind(1, reinterpret_cast<const void*>(block.data()), block.size(), SQLITE_STATIC);
     stmt.step();
   }
 
diff --git a/tools/ndnsec/cert-dump.cpp b/tools/ndnsec/cert-dump.cpp
index 9f86f1c..b5ac12f 100644
--- a/tools/ndnsec/cert-dump.cpp
+++ b/tools/ndnsec/cert-dump.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).
  *
@@ -132,7 +132,7 @@
       std::cerr << "ERROR: Failed to connect to repo instance" << std::endl;
       return 1;
     }
-    requestStream.write(reinterpret_cast<const char*>(certificate.wireEncode().wire()),
+    requestStream.write(reinterpret_cast<const char*>(certificate.wireEncode().data()),
                         certificate.wireEncode().size());
     return 0;
   }
diff --git a/tools/ndnsec/cert-gen.cpp b/tools/ndnsec/cert-gen.cpp
index 51ad678..e44d063 100644
--- a/tools/ndnsec/cert-gen.cpp
+++ b/tools/ndnsec/cert-gen.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).
  *
@@ -160,8 +160,7 @@
 
   {
     using namespace security::transform;
-    const auto& wire = cert.wireEncode();
-    bufferSource(make_span(wire.wire(), wire.size())) >> base64Encode(true) >> streamSink(std::cout);
+    bufferSource(cert.wireEncode()) >> base64Encode(true) >> streamSink(std::cout);
   }
 
   return 0;