net+transport: use std::array

Change-Id: If5e73eeca86d2a568effb8a9ada79551a056ca07
diff --git a/ndn-cxx/net/impl/netlink-socket.cpp b/ndn-cxx/net/impl/netlink-socket.cpp
index bfcd4d8..14b41f8 100644
--- a/ndn-cxx/net/impl/netlink-socket.cpp
+++ b/ndn-cxx/net/impl/netlink-socket.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2023 Regents of the University of California.
+ * Copyright (c) 2013-2024 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -29,6 +29,8 @@
 #include <linux/genetlink.h>
 #include <sys/socket.h>
 
+#include <array>
+
 #ifndef SOL_NETLINK
 #define SOL_NETLINK 270
 #endif
@@ -247,14 +249,14 @@
   iovec iov{};
   iov.iov_base = m_buffer.data();
   iov.iov_len = m_buffer.size();
-  uint8_t cmsgBuffer[CMSG_SPACE(sizeof(nl_pktinfo))];
+  std::array<uint8_t, CMSG_SPACE(sizeof(nl_pktinfo))> cmsgBuffer{};
   msghdr msg{};
   msg.msg_name = &sender;
   msg.msg_namelen = sizeof(sender);
   msg.msg_iov = &iov;
   msg.msg_iovlen = 1;
-  msg.msg_control = cmsgBuffer;
-  msg.msg_controllen = sizeof(cmsgBuffer);
+  msg.msg_control = cmsgBuffer.data();
+  msg.msg_controllen = cmsgBuffer.size();
 
   ssize_t nBytesRead = ::recvmsg(m_sock->native_handle(), &msg, 0);
   if (nBytesRead < 0) {
diff --git a/ndn-cxx/transport/detail/stream-transport-impl.hpp b/ndn-cxx/transport/detail/stream-transport-impl.hpp
index 0c65a5e..8df5edd 100644
--- a/ndn-cxx/transport/detail/stream-transport-impl.hpp
+++ b/ndn-cxx/transport/detail/stream-transport-impl.hpp
@@ -28,6 +28,7 @@
 #include <boost/asio/write.hpp>
 #include <boost/lexical_cast.hpp>
 
+#include <array>
 #include <list>
 #include <queue>
 
@@ -108,7 +109,7 @@
   {
     if (m_transport.getState() == Transport::State::PAUSED) {
       m_transport.setState(Transport::State::RUNNING);
-      m_inputBufferSize = 0;
+      m_rxBufferSize = 0;
       asyncReceive();
     }
   }
@@ -183,8 +184,8 @@
   void
   asyncReceive()
   {
-    m_socket.async_receive(boost::asio::buffer(m_inputBuffer + m_inputBufferSize,
-                                               MAX_NDN_PACKET_SIZE - m_inputBufferSize), 0,
+    m_socket.async_receive(boost::asio::buffer(m_rxBuffer.data() + m_rxBufferSize,
+                                               m_rxBuffer.size() - m_rxBufferSize),
       // capture a copy of the shared_ptr to "this" to prevent deallocation
       [this, self = this->shared_from_this()] (const auto& error, size_t nBytesRecvd) {
         if (error) {
@@ -196,52 +197,43 @@
           NDN_THROW(Transport::Error(error, "socket read error"));
         }
 
-        m_inputBufferSize += nBytesRecvd;
-        // do magic
+        m_rxBufferSize += nBytesRecvd;
+        auto unparsedBytes = span(m_rxBuffer).first(m_rxBufferSize);
+        while (!unparsedBytes.empty()) {
+          auto [isOk, element] = Block::fromBuffer(unparsedBytes);
+          if (!isOk) {
+            break;
+          }
+          unparsedBytes = unparsedBytes.subspan(element.size());
+          m_transport.m_receiveCallback(element);
+        }
 
-        std::size_t offset = 0;
-        bool hasProcessedSome = processAllReceived(m_inputBuffer, offset, m_inputBufferSize);
-        if (!hasProcessedSome && m_inputBufferSize == MAX_NDN_PACKET_SIZE && offset == 0) {
+        if (unparsedBytes.empty()) {
+          // nothing left in the receive buffer
+          m_rxBufferSize = 0;
+        }
+        else if (unparsedBytes.data() != m_rxBuffer.data()) {
+          // move remaining unparsed bytes to the beginning of the receive buffer
+          std::copy(unparsedBytes.begin(), unparsedBytes.end(), m_rxBuffer.begin());
+          m_rxBufferSize = unparsedBytes.size();
+        }
+        else if (unparsedBytes.size() == m_rxBuffer.size()) {
           m_transport.close();
           NDN_THROW(Transport::Error("receive buffer full, but a valid TLV cannot be decoded"));
         }
 
-        if (offset > 0) {
-          if (offset != m_inputBufferSize) {
-            std::copy(m_inputBuffer + offset, m_inputBuffer + m_inputBufferSize, m_inputBuffer);
-            m_inputBufferSize -= offset;
-          }
-          else {
-            m_inputBufferSize = 0;
-          }
-        }
-
         asyncReceive();
       });
   }
 
-  bool
-  processAllReceived(uint8_t* buffer, size_t& offset, size_t nBytesAvailable)
-  {
-    while (offset < nBytesAvailable) {
-      auto [isOk, element] = Block::fromBuffer({buffer + offset, nBytesAvailable - offset});
-      if (!isOk) {
-        return false;
-      }
-      m_transport.m_receiveCallback(element);
-      offset += element.size();
-    }
-    return true;
-  }
-
 protected:
   BaseTransport& m_transport;
   typename Protocol::endpoint m_endpoint;
   typename Protocol::socket m_socket;
   boost::asio::steady_timer m_connectTimer;
   TransmissionQueue m_transmissionQueue;
-  size_t m_inputBufferSize = 0;
-  uint8_t m_inputBuffer[MAX_NDN_PACKET_SIZE];
+  size_t m_rxBufferSize = 0;
+  std::array<uint8_t, MAX_NDN_PACKET_SIZE> m_rxBuffer;
 };
 
 } // namespace ndn::detail