util: unnest nested Options classes
Change-Id: If20eea845d4c9ff2a03e6133f7ba51b579bcc7e9
diff --git a/ndn-cxx/util/dummy-client-face.cpp b/ndn-cxx/util/dummy-client-face.cpp
index b4dc341..8b55f18 100644
--- a/ndn-cxx/util/dummy-client-face.cpp
+++ b/ndn-cxx/util/dummy-client-face.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).
*
@@ -33,8 +33,9 @@
#include <boost/asio/post.hpp>
namespace ndn {
+namespace {
-class DummyClientFace::Transport final : public ndn::Transport
+class DummyTransport final : public ndn::Transport
{
public:
void
@@ -68,9 +69,11 @@
}
public:
- signal::Signal<Transport, Block> onSendBlock;
+ signal::Signal<DummyTransport, Block> onSendBlock;
};
+} // namespace
+
struct DummyClientFace::BroadcastLink
{
std::vector<DummyClientFace*> faces;
@@ -82,7 +85,7 @@
}
DummyClientFace::DummyClientFace(const Options& options)
- : Face(make_shared<DummyClientFace::Transport>())
+ : Face(make_shared<DummyTransport>())
, m_internalKeyChain(make_unique<KeyChain>())
, m_keyChain(*m_internalKeyChain)
{
@@ -90,14 +93,14 @@
}
DummyClientFace::DummyClientFace(KeyChain& keyChain, const Options& options)
- : Face(make_shared<DummyClientFace::Transport>(), keyChain)
+ : Face(make_shared<DummyTransport>(), keyChain)
, m_keyChain(keyChain)
{
this->construct(options);
}
DummyClientFace::DummyClientFace(boost::asio::io_context& ioCtx, const Options& options)
- : Face(make_shared<DummyClientFace::Transport>(), ioCtx)
+ : Face(make_shared<DummyTransport>(), ioCtx)
, m_internalKeyChain(make_unique<KeyChain>())
, m_keyChain(*m_internalKeyChain)
{
@@ -105,7 +108,7 @@
}
DummyClientFace::DummyClientFace(boost::asio::io_context& ioCtx, KeyChain& keyChain, const Options& options)
- : Face(make_shared<DummyClientFace::Transport>(), ioCtx, keyChain)
+ : Face(make_shared<DummyTransport>(), ioCtx, keyChain)
, m_keyChain(keyChain)
{
this->construct(options);
@@ -119,7 +122,7 @@
void
DummyClientFace::construct(const Options& options)
{
- static_cast<Transport&>(getTransport()).onSendBlock.connect([this] (Block packet) {
+ static_cast<DummyTransport&>(getTransport()).onSendBlock.connect([this] (Block packet) {
packet.encode();
lp::Packet lpPacket(packet);
auto frag = lpPacket.get<lp::FragmentField>();
@@ -245,7 +248,7 @@
addFieldFromTag<lp::NextHopFaceIdField, lp::NextHopFaceIdTag>(lpPacket, interest);
addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, interest);
- static_cast<Transport&>(getTransport()).receive(lpPacket.wireEncode());
+ static_cast<DummyTransport&>(getTransport()).receive(lpPacket.wireEncode());
}
void
@@ -256,7 +259,7 @@
addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, data);
addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, data);
- static_cast<Transport&>(getTransport()).receive(lpPacket.wireEncode());
+ static_cast<DummyTransport&>(getTransport()).receive(lpPacket.wireEncode());
}
void
@@ -270,7 +273,7 @@
addFieldFromTag<lp::IncomingFaceIdField, lp::IncomingFaceIdTag>(lpPacket, nack);
addFieldFromTag<lp::CongestionMarkField, lp::CongestionMarkTag>(lpPacket, nack);
- static_cast<Transport&>(getTransport()).receive(lpPacket.wireEncode());
+ static_cast<DummyTransport&>(getTransport()).receive(lpPacket.wireEncode());
}
void
diff --git a/ndn-cxx/util/dummy-client-face.hpp b/ndn-cxx/util/dummy-client-face.hpp
index 35c9acd..2bc1b59 100644
--- a/ndn-cxx/util/dummy-client-face.hpp
+++ b/ndn-cxx/util/dummy-client-face.hpp
@@ -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,110 +29,103 @@
namespace ndn {
/**
+ * \brief Options for DummyClientFace.
+ */
+struct DummyClientFaceOptions
+{
+ DummyClientFaceOptions() = default;
+
+ DummyClientFaceOptions(bool enablePacketLogging, bool enableRegistrationReply,
+ const std::function<void(time::milliseconds)>& processEventsOverride = nullptr)
+ : enablePacketLogging(enablePacketLogging)
+ , enableRegistrationReply(enableRegistrationReply)
+ , processEventsOverride(processEventsOverride)
+ {
+ }
+
+ /// If true, packets sent out of DummyClientFace will be appended to a container.
+ bool enablePacketLogging = true;
+
+ /// If true, prefix registration commands will be automatically replied to with a successful response.
+ bool enableRegistrationReply = false;
+
+ /// FaceId used in prefix registration replies.
+ uint64_t registrationReplyFaceId = 1;
+
+ /// If not empty, `face.processEvents()` will be overridden by this function.
+ std::function<void(time::milliseconds)> processEventsOverride;
+};
+
+/**
* \brief A client-side face for unit testing.
*/
class DummyClientFace : public Face
{
public:
- /**
- * \brief %Options for DummyClientFace.
- */
- class Options
- {
- public:
- Options(bool enablePacketLogging, bool enableRegistrationReply,
- const std::function<void(time::milliseconds)>& processEventsOverride)
- : enablePacketLogging(enablePacketLogging)
- , enableRegistrationReply(enableRegistrationReply)
- , processEventsOverride(processEventsOverride)
- {
- }
-
- Options(bool enablePacketLogging, bool enableRegistrationReply)
- : Options(enablePacketLogging, enableRegistrationReply, nullptr)
- {
- }
-
- Options()
- : Options(true, false)
- {
- }
-
- public:
- /** \brief If true, packets sent out of DummyClientFace will be appended to a container.
- */
- bool enablePacketLogging;
-
- /** \brief If true, prefix registration command will be automatically
- * replied with a successful response.
- */
- bool enableRegistrationReply;
-
- /** \brief FaceId used in prefix registration replies.
- */
- uint64_t registrationReplyFaceId = 1;
-
- /** \brief If not empty, `face.processEvents()` will be overridden by this function.
- */
- std::function<void(time::milliseconds)> processEventsOverride;
- };
-
class AlreadyLinkedError : public Error
{
public:
AlreadyLinkedError();
};
- /** \brief Create a dummy face with internal I/O context.
+ using Options = DummyClientFaceOptions;
+
+ /**
+ * \brief Create a dummy face with an internal I/O context.
*/
explicit
- DummyClientFace(const Options& options = Options());
+ DummyClientFace(const Options& options = {});
- /** \brief Create a dummy face with internal I/O context and the specified KeyChain.
+ /**
+ * \brief Create a dummy face with an internal I/O context and the specified KeyChain.
*/
explicit
- DummyClientFace(KeyChain& keyChain, const Options& options = Options());
+ DummyClientFace(KeyChain& keyChain, const Options& options = {});
- /** \brief Create a dummy face with the provided I/O context.
+ /**
+ * \brief Create a dummy face with the provided I/O context.
*/
explicit
- DummyClientFace(boost::asio::io_context& ioCtx, const Options& options = Options());
+ DummyClientFace(boost::asio::io_context& ioCtx, const Options& options = {});
- /** \brief Create a dummy face with the provided I/O context and the specified KeyChain.
+ /**
+ * \brief Create a dummy face with the specified I/O context and KeyChain.
*/
- DummyClientFace(boost::asio::io_context& ioCtx, KeyChain& keyChain,
- const Options& options = Options());
+ DummyClientFace(boost::asio::io_context& ioCtx, KeyChain& keyChain, const Options& options = {});
~DummyClientFace() override;
- /** \brief Cause the Face to receive an Interest packet.
+ /**
+ * \brief Cause the face to receive an Interest packet.
*/
void
receive(const Interest& interest);
- /** \brief Cause the Face to receive a Data packet.
+ /**
+ * \brief Cause the face to receive a Data packet.
*/
void
receive(const Data& data);
- /** \brief Cause the Face to receive a Nack packet.
+ /**
+ * \brief Cause the face to receive a Nack packet.
*/
void
receive(const lp::Nack& nack);
- /** \brief Link another DummyClientFace through a broadcast media.
+ /**
+ * \brief Link another DummyClientFace through a broadcast medium.
*/
void
linkTo(DummyClientFace& other);
- /** \brief Unlink the broadcast media if previously linked.
+ /**
+ * \brief Unlink the broadcast medium if previously linked.
*/
void
unlink();
private:
- class Transport;
-
void
construct(const Options& options);
@@ -149,45 +142,51 @@
doProcessEvents(time::milliseconds timeout, bool keepRunning) override;
public:
- /** \brief Interests sent out of this DummyClientFace.
+ /**
+ * \brief Interests sent out of this DummyClientFace.
*
- * Sent Interests are appended to this container if options.enablePacketLogger is true.
- * User of this class is responsible for cleaning up the container, if necessary.
- * After .expressInterest, .processEvents must be called before the Interest would show up here.
+ * Sent Interests are appended to this container if Options::enablePacketLogging is true.
+ * The user of this class is responsible for cleaning up the container, if necessary.
+ *
+ * \note After expressInterest(), processEvents() must be called before the %Interest shows up here.
*/
std::vector<Interest> sentInterests;
- /** \brief Data sent out of this DummyClientFace.
+ /**
+ * \brief %Data sent out of this DummyClientFace.
*
- * Sent Data are appended to this container if options.enablePacketLogger is true.
- * User of this class is responsible for cleaning up the container, if necessary.
- * After .put, .processEvents must be called before the Data would show up here.
+ * Sent %Data are appended to this container if Options::enablePacketLogging is true.
+ * The user of this class is responsible for cleaning up the container, if necessary.
+ *
+ * \note After put(), processEvents() must be called before the %Data shows up here.
*/
std::vector<Data> sentData;
- /** \brief Nacks sent out of this DummyClientFace.
+ /**
+ * \brief Nacks sent out of this DummyClientFace.
*
- * Sent Nacks are appended to this container if options.enablePacketLogger is true.
- * User of this class is responsible for cleaning up the container, if necessary.
- * After .put, .processEvents must be called before the NACK would show up here.
+ * Sent Nacks are appended to this container if Options::enablePacketLogging is true.
+ * The user of this class is responsible for cleaning up the container, if necessary.
+ *
+ * \note After put(), processEvents() must be called before the %Nack shows up here.
*/
std::vector<lp::Nack> sentNacks;
- /** \brief Emits whenever an Interest is sent.
- *
- * After .expressInterest, .processEvents must be called before this signal would be emitted.
+ /**
+ * \brief Emitted whenever an %Interest is sent.
+ * \note After expressInterest(), processEvents() must be called before this signal is emitted.
*/
signal::Signal<DummyClientFace, Interest> onSendInterest;
- /** \brief Emits whenever a Data packet is sent.
- *
- * After .put, .processEvents must be called before this signal would be emitted.
+ /**
+ * \brief Emitted whenever a %Data packet is sent.
+ * \note After put(), processEvents() must be called before this signal is emitted.
*/
signal::Signal<DummyClientFace, Data> onSendData;
- /** \brief Emits whenever a Nack is sent.
- *
- * After .put, .processEvents must be called before this signal would be emitted.
+ /**
+ * \brief Emitted whenever a %Nack is sent.
+ * \note After put(), processEvents() must be called before this signal is emitted.
*/
signal::Signal<DummyClientFace, lp::Nack> onSendNack;
diff --git a/ndn-cxx/util/segment-fetcher.hpp b/ndn-cxx/util/segment-fetcher.hpp
index 1312de6..2635d3e 100644
--- a/ndn-cxx/util/segment-fetcher.hpp
+++ b/ndn-cxx/util/segment-fetcher.hpp
@@ -34,6 +34,46 @@
namespace ndn {
/**
+ * \brief Options for SegmentFetcher.
+ */
+struct SegmentFetcherOptions
+{
+ /// Lifetime of sent Interests (independent of Interest timeout)
+ time::milliseconds interestLifetime = 4_s;
+ /// Maximum allowed time between successful receipt of segments
+ time::milliseconds maxTimeout = 60_s;
+ /// Use the first Interest to probe the latest version of the object
+ bool probeLatestVersion = true;
+ /// Set to true for 'in order' mode, false for 'block' mode
+ bool inOrder = false;
+ /// If true, Interest timeout is kept fixed at #maxTimeout
+ bool useConstantInterestTimeout = false;
+ /// If true, window size is kept fixed at #initCwnd
+ bool useConstantCwnd = false;
+ /// Disable Conservative Window Adaptation
+ bool disableCwa = false;
+ /// Reduce cwnd to #initCwnd when a loss event occurs
+ bool resetCwndToInit = false;
+ /// Disable window decrease after a congestion mark is received
+ bool ignoreCongMarks = false;
+ /// Initial congestion window size
+ double initCwnd = 1.0;
+ /// Initial slow start threshold
+ double initSsthresh = std::numeric_limits<double>::max();
+ /// Additive increase step (in segments)
+ double aiStep = 1.0;
+ /// Multiplicative decrease coefficient
+ double mdCoef = 0.5;
+ /// Options for the RTT estimator
+ util::RttEstimator::Options rttOptions;
+ /// Maximum number of segments stored in the reorder buffer
+ size_t flowControlWindow = 25000;
+
+ void
+ validate();
+};
+
+/**
* @brief Utility class to fetch a versioned and segmented object.
*
* SegmentFetcher assumes that segments in the object are named `/<prefix>/<version>/<segment>`,
@@ -102,33 +142,7 @@
FINALBLOCKID_NOT_SEGMENT = 5,
};
- class Options
- {
- public:
- Options()
- {
- }
-
- void
- validate();
-
- public:
- time::milliseconds interestLifetime = 4_s; ///< lifetime of sent Interests - independent of Interest timeout
- time::milliseconds maxTimeout = 60_s; ///< maximum allowed time between successful receipt of segments
- bool probeLatestVersion = true; ///< use the first Interest to probe the latest version of the object
- bool inOrder = false; ///< true for 'in order' mode, false for 'block' mode
- bool useConstantInterestTimeout = false; ///< if true, Interest timeout is kept at `maxTimeout`
- bool useConstantCwnd = false; ///< if true, window size is kept at `initCwnd`
- bool disableCwa = false; ///< disable Conservative Window Adaptation
- bool resetCwndToInit = false; ///< reduce cwnd to initCwnd when loss event occurs
- bool ignoreCongMarks = false; ///< disable window decrease after congestion mark received
- double initCwnd = 1.0; ///< initial congestion window size
- double initSsthresh = std::numeric_limits<double>::max(); ///< initial slow start threshold
- double aiStep = 1.0; ///< additive increase step (in segments)
- double mdCoef = 0.5; ///< multiplicative decrease coefficient
- util::RttEstimator::Options rttOptions; ///< options for RTT estimator
- size_t flowControlWindow = 25000; ///< maximum number of segments stored in the reorder buffer
- };
+ using Options = SegmentFetcherOptions;
/**
* @brief Initiates segment fetching.
@@ -155,10 +169,8 @@
* SegmentFetcher's signals can be connected to.
*/
static shared_ptr<SegmentFetcher>
- start(Face& face,
- const Interest& baseInterest,
- security::Validator& validator,
- const Options& options = Options());
+ start(Face& face, const Interest& baseInterest, security::Validator& validator,
+ const Options& options = {});
/**
* @brief Stops fetching.
diff --git a/tests/unit/util/dummy-client-face.t.cpp b/tests/unit/util/dummy-client-face.t.cpp
index 0eea2e6..a946858 100644
--- a/tests/unit/util/dummy-client-face.t.cpp
+++ b/tests/unit/util/dummy-client-face.t.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).
*
@@ -93,8 +93,8 @@
BOOST_AUTO_TEST_CASE(BroadcastLink)
{
- DummyClientFace face1(m_io, m_keyChain, DummyClientFace::Options{true, true});
- DummyClientFace face2(m_io, m_keyChain, DummyClientFace::Options{true, true});
+ DummyClientFace face1(m_io, m_keyChain, {true, true});
+ DummyClientFace face2(m_io, m_keyChain, {true, true});
face1.linkTo(face2);
int nFace1Interest = 0;
@@ -141,14 +141,14 @@
BOOST_AUTO_TEST_CASE(BroadcastLinkDestroy)
{
- DummyClientFace face1(m_io, m_keyChain, DummyClientFace::Options{true, true});
- DummyClientFace face2(m_io, m_keyChain, DummyClientFace::Options{true, true});
+ DummyClientFace face1(m_io, m_keyChain, {true, true});
+ DummyClientFace face2(m_io, m_keyChain, {true, true});
face1.linkTo(face2);
face2.unlink();
BOOST_CHECK(face1.m_bcastLink == nullptr);
- DummyClientFace face3(m_io, m_keyChain, DummyClientFace::Options{true, true});
+ DummyClientFace face3(m_io, m_keyChain, {true, true});
face1.linkTo(face2);
face3.linkTo(face1);
face2.unlink();