face: use std::array

Change-Id: I5d52fd75b6ff35988e74415972041f9b12a0fa89
diff --git a/daemon/face/datagram-transport.hpp b/daemon/face/datagram-transport.hpp
index 923dde3..0dcf0e1 100644
--- a/daemon/face/datagram-transport.hpp
+++ b/daemon/face/datagram-transport.hpp
@@ -202,7 +202,7 @@
 void
 DatagramTransport<T, U>::handleReceive(const boost::system::error_code& error, size_t nBytesReceived)
 {
-  receiveDatagram(ndn::make_span(m_receiveBuffer).first(nBytesReceived), error);
+  receiveDatagram(ndn::span(m_receiveBuffer).first(nBytesReceived), error);
 
   if (m_socket.is_open())
     m_socket.async_receive_from(boost::asio::buffer(m_receiveBuffer), m_sender,
diff --git a/daemon/face/ethernet-transport.cpp b/daemon/face/ethernet-transport.cpp
index 9ddbdb7..57cae35 100644
--- a/daemon/face/ethernet-transport.cpp
+++ b/daemon/face/ethernet-transport.cpp
@@ -29,6 +29,8 @@
 
 #include <pcap/pcap.h>
 
+#include <array>
+
 #include <boost/asio/defer.hpp>
 #include <boost/endian/conversion.hpp>
 
@@ -118,11 +120,14 @@
 
   // pad with zeroes if the payload is too short
   if (block.size() < ethernet::MIN_DATA_LEN) {
-    static const uint8_t padding[ethernet::MIN_DATA_LEN] = {};
-    buffer.appendBytes(ndn::make_span(padding).subspan(block.size()));
+    static const std::array<uint8_t, ethernet::MIN_DATA_LEN> padding{};
+    buffer.appendBytes(ndn::span(padding).subspan(block.size()));
   }
 
   // construct and prepend the ethernet header
+#if BOOST_VERSION >= 107200
+  constexpr
+#endif
   uint16_t ethertype = boost::endian::native_to_big(ethernet::ETHERTYPE_NDN);
   buffer.prependBytes({reinterpret_cast<const uint8_t*>(&ethertype), ethernet::TYPE_LEN});
   buffer.prependBytes(m_srcAddress);
diff --git a/daemon/face/stream-transport.hpp b/daemon/face/stream-transport.hpp
index bd6cc12..750432f 100644
--- a/daemon/face/stream-transport.hpp
+++ b/daemon/face/stream-transport.hpp
@@ -30,6 +30,7 @@
 #include "socket-utils.hpp"
 #include "common/global.hpp"
 
+#include <array>
 #include <queue>
 
 #include <boost/asio/defer.hpp>
@@ -104,10 +105,10 @@
   NFD_LOG_MEMBER_DECL();
 
 private:
-  uint8_t m_receiveBuffer[ndn::MAX_NDN_PACKET_SIZE];
-  size_t m_receiveBufferSize = 0;
-  std::queue<Block> m_sendQueue;
   size_t m_sendQueueBytes = 0;
+  std::queue<Block> m_sendQueue;
+  size_t m_receiveBufferSize = 0;
+  std::array<uint8_t, ndn::MAX_NDN_PACKET_SIZE> m_receiveBuffer;
 };
 
 
@@ -230,8 +231,8 @@
 {
   BOOST_ASSERT(getState() == TransportState::UP);
 
-  m_socket.async_receive(boost::asio::buffer(m_receiveBuffer + m_receiveBufferSize,
-                                             ndn::MAX_NDN_PACKET_SIZE - m_receiveBufferSize),
+  m_socket.async_receive(boost::asio::buffer(m_receiveBuffer.data() + m_receiveBufferSize,
+                                             m_receiveBuffer.size() - m_receiveBufferSize),
                          [this] (auto&&... args) { this->handleReceive(std::forward<decltype(args)>(args)...); });
 }
 
@@ -246,38 +247,32 @@
   NFD_LOG_FACE_TRACE("Received: " << nBytesReceived << " bytes");
 
   m_receiveBufferSize += nBytesReceived;
-  auto bufferView = ndn::make_span(m_receiveBuffer, m_receiveBufferSize);
-  size_t offset = 0;
-  bool isOk = true;
-  while (offset < bufferView.size()) {
-    Block element;
-    std::tie(isOk, element) = Block::fromBuffer(bufferView.subspan(offset));
+  auto unparsedBytes = ndn::span(m_receiveBuffer).first(m_receiveBufferSize);
+  while (!unparsedBytes.empty()) {
+    auto [isOk, element] = Block::fromBuffer(unparsedBytes);
     if (!isOk)
       break;
 
-    offset += element.size();
-    BOOST_ASSERT(offset <= bufferView.size());
-
+    unparsedBytes = unparsedBytes.subspan(element.size());
     this->receive(element);
   }
 
-  if (!isOk && m_receiveBufferSize == ndn::MAX_NDN_PACKET_SIZE && offset == 0) {
+  if (unparsedBytes.empty()) {
+    // nothing left in the receive buffer
+    m_receiveBufferSize = 0;
+  }
+  else if (unparsedBytes.data() != m_receiveBuffer.data()) {
+    // move remaining unparsed bytes to the beginning of the receive buffer
+    std::copy(unparsedBytes.begin(), unparsedBytes.end(), m_receiveBuffer.begin());
+    m_receiveBufferSize = unparsedBytes.size();
+  }
+  else if (unparsedBytes.size() == m_receiveBuffer.size()) {
     NFD_LOG_FACE_ERROR("Failed to parse incoming packet or packet too large to process");
     this->setState(TransportState::FAILED);
     doClose();
     return;
   }
 
-  if (offset > 0) {
-    if (offset != m_receiveBufferSize) {
-      std::copy(m_receiveBuffer + offset, m_receiveBuffer + m_receiveBufferSize, m_receiveBuffer);
-      m_receiveBufferSize -= offset;
-    }
-    else {
-      m_receiveBufferSize = 0;
-    }
-  }
-
   startReceive();
 }
 
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index a7515f4..4361b63 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2023,  Regents of the University of California,
+ * Copyright (c) 2014-2024,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -141,7 +141,7 @@
 
   // dispatch the datagram to the face for processing
   auto* transport = static_cast<UnicastUdpTransport*>(face->getTransport());
-  transport->receiveDatagram(ndn::make_span(m_receiveBuffer).first(nBytesReceived), error);
+  transport->receiveDatagram(ndn::span(m_receiveBuffer).first(nBytesReceived), error);
 
   waitForNewPeer(onFaceCreated, onReceiveFailed);
 }