face: minor refactoring and Doxygen improvements
refs #3248
Change-Id: I8c44b4342b9d7b9e896dbc96fbf671d3e29bcb3c
diff --git a/src/detail/container-with-on-empty-signal.hpp b/src/detail/container-with-on-empty-signal.hpp
index 0c3e7c3..ef5f004 100644
--- a/src/detail/container-with-on-empty-signal.hpp
+++ b/src/detail/container-with-on-empty-signal.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -28,7 +28,7 @@
namespace ndn {
/**
- * @brief A simple container that will fire up onEmpty signal when there are no entries left
+ * @brief A container that emits onEmpty signal when it becomes empty
*/
template<class T>
class ContainerWithOnEmptySignal
diff --git a/src/detail/face-impl.hpp b/src/detail/face-impl.hpp
index 476e85e..fa5f989 100644
--- a/src/detail/face-impl.hpp
+++ b/src/detail/face-impl.hpp
@@ -45,11 +45,16 @@
namespace ndn {
+using ndn::nfd::ControlParameters;
+
+/**
+ * @brief implementation detail of Face
+ */
class Face::Impl : noncopyable
{
public:
typedef ContainerWithOnEmptySignal<shared_ptr<PendingInterest>> PendingInterestTable;
- typedef std::list<shared_ptr<InterestFilterRecord> > InterestFilterTable;
+ typedef std::list<shared_ptr<InterestFilterRecord>> InterestFilterTable;
typedef ContainerWithOnEmptySignal<shared_ptr<RegisteredPrefix>> RegisteredPrefixTable;
explicit
@@ -59,7 +64,7 @@
, m_processEventsTimeoutEvent(m_scheduler)
{
auto postOnEmptyPitOrNoRegisteredPrefixes = [this] {
- this->m_face.getIoService().post(bind(&Impl::onEmptyPitOrNoRegisteredPrefixes, this));
+ this->m_face.getIoService().post([this] { this->onEmptyPitOrNoRegisteredPrefixes(); });
// without this extra "post", transport can get paused (-async_read) and then resumed
// (+async_read) from within onInterest/onData callback. After onInterest/onData
// finishes, there is another +async_read with the same memory block. A few of such
@@ -70,67 +75,7 @@
m_registeredPrefixTable.onEmpty.connect(postOnEmptyPitOrNoRegisteredPrefixes);
}
- /////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////
-
- void
- satisfyPendingInterests(Data& data)
- {
- for (auto entry = m_pendingInterestTable.begin(); entry != m_pendingInterestTable.end(); ) {
- if ((*entry)->getInterest()->matchesData(data)) {
- shared_ptr<PendingInterest> matchedEntry = *entry;
-
- entry = m_pendingInterestTable.erase(entry);
-
- matchedEntry->invokeDataCallback(data);
- }
- else
- ++entry;
- }
- }
-
- void
- nackPendingInterests(const lp::Nack& nack)
- {
- for (auto entry = m_pendingInterestTable.begin(); entry != m_pendingInterestTable.end(); ) {
- const Interest& pendingInterest = *(*entry)->getInterest();
- if (pendingInterest == nack.getInterest()) {
- shared_ptr<PendingInterest> matchedEntry = *entry;
-
- entry = m_pendingInterestTable.erase(entry);
-
- matchedEntry->invokeNackCallback(nack);
- }
- else {
- ++entry;
- }
- }
- }
-
- void
- processInterestFilters(Interest& interest)
- {
- for (const auto& filter : m_interestFilterTable) {
- if (filter->doesMatch(interest.getName())) {
- filter->invokeInterestCallback(interest);
- }
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////
-
- void
- ensureConnected(bool wantResume)
- {
- if (!m_face.m_transport->isConnected())
- m_face.m_transport->connect(m_face.m_ioService,
- bind(&Face::onReceiveElement, &m_face, _1));
-
- if (wantResume && !m_face.m_transport->isReceiving())
- m_face.m_transport->resume();
- }
-
+public: // consumer
void
asyncExpressInterest(shared_ptr<const Interest> interest,
const DataCallback& afterSatisfied,
@@ -139,12 +84,8 @@
{
this->ensureConnected(true);
- auto entry =
- m_pendingInterestTable.insert(make_shared<PendingInterest>(interest,
- afterSatisfied,
- afterNacked,
- afterTimeout,
- ref(m_scheduler))).first;
+ auto entry = m_pendingInterestTable.insert(make_shared<PendingInterest>(
+ interest, afterSatisfied, afterNacked, afterTimeout, ref(m_scheduler))).first;
(*entry)->setDeleter([this, entry] { m_pendingInterestTable.erase(entry); });
lp::Packet packet;
@@ -173,6 +114,65 @@
}
void
+ satisfyPendingInterests(const Data& data)
+ {
+ for (auto entry = m_pendingInterestTable.begin(); entry != m_pendingInterestTable.end(); ) {
+ if ((*entry)->getInterest()->matchesData(data)) {
+ shared_ptr<PendingInterest> matchedEntry = *entry;
+ entry = m_pendingInterestTable.erase(entry);
+ matchedEntry->invokeDataCallback(data);
+ }
+ else {
+ ++entry;
+ }
+ }
+ }
+
+ void
+ nackPendingInterests(const lp::Nack& nack)
+ {
+ for (auto entry = m_pendingInterestTable.begin(); entry != m_pendingInterestTable.end(); ) {
+ const Interest& pendingInterest = *(*entry)->getInterest();
+ if (pendingInterest == nack.getInterest()) {
+ shared_ptr<PendingInterest> matchedEntry = *entry;
+ entry = m_pendingInterestTable.erase(entry);
+ matchedEntry->invokeNackCallback(nack);
+ }
+ else {
+ ++entry;
+ }
+ }
+ }
+
+public: // producer
+ void
+ asyncSetInterestFilter(shared_ptr<InterestFilterRecord> interestFilterRecord)
+ {
+ m_interestFilterTable.push_back(interestFilterRecord);
+ }
+
+ void
+ asyncUnsetInterestFilter(const InterestFilterId* interestFilterId)
+ {
+ InterestFilterTable::iterator i = std::find_if(m_interestFilterTable.begin(),
+ m_interestFilterTable.end(),
+ MatchInterestFilterId(interestFilterId));
+ if (i != m_interestFilterTable.end()) {
+ m_interestFilterTable.erase(i);
+ }
+ }
+
+ void
+ processInterestFilters(Interest& interest)
+ {
+ for (const auto& filter : m_interestFilterTable) {
+ if (filter->doesMatch(interest.getName())) {
+ filter->invokeInterestCallback(interest);
+ }
+ }
+ }
+
+ void
asyncPutData(const shared_ptr<const Data>& data)
{
this->ensureConnected(true);
@@ -204,67 +204,42 @@
m_face.m_transport->send(packet.wireEncode());
}
- /////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////
-
- void
- asyncSetInterestFilter(const shared_ptr<InterestFilterRecord>& interestFilterRecord)
- {
- m_interestFilterTable.push_back(interestFilterRecord);
- }
-
- void
- asyncUnsetInterestFilter(const InterestFilterId* interestFilterId)
- {
- InterestFilterTable::iterator i = std::find_if(m_interestFilterTable.begin(),
- m_interestFilterTable.end(),
- MatchInterestFilterId(interestFilterId));
- if (i != m_interestFilterTable.end())
- {
- m_interestFilterTable.erase(i);
- }
- }
-
- /////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////
-
+public: // prefix registration
const RegisteredPrefixId*
registerPrefix(const Name& prefix,
- const shared_ptr<InterestFilterRecord>& filter,
+ shared_ptr<InterestFilterRecord> filter,
const RegisterPrefixSuccessCallback& onSuccess,
const RegisterPrefixFailureCallback& onFailure,
uint64_t flags,
const nfd::CommandOptions& options)
{
- using namespace nfd;
-
ControlParameters params;
params.setName(prefix);
params.setFlags(flags);
auto prefixToRegister = make_shared<RegisteredPrefix>(prefix, filter, options);
- m_face.m_nfdController->start<RibRegisterCommand>(params,
- bind(&Impl::afterPrefixRegistered, this,
- prefixToRegister, onSuccess),
- bind(onFailure, prefixToRegister->getPrefix(), _2),
- options);
+ m_face.m_nfdController->start<nfd::RibRegisterCommand>(
+ params,
+ [=] (const ControlParameters&) { this->afterPrefixRegistered(prefixToRegister, onSuccess); },
+ [=] (uint32_t code, const std::string& reason) { onFailure(prefixToRegister->getPrefix(), reason); },
+ options);
return reinterpret_cast<const RegisteredPrefixId*>(prefixToRegister.get());
}
void
- afterPrefixRegistered(const shared_ptr<RegisteredPrefix>& registeredPrefix,
+ afterPrefixRegistered(shared_ptr<RegisteredPrefix> registeredPrefix,
const RegisterPrefixSuccessCallback& onSuccess)
{
m_registeredPrefixTable.insert(registeredPrefix);
- if (static_cast<bool>(registeredPrefix->getFilter())) {
+ if (registeredPrefix->getFilter() != nullptr) {
// it was a combined operation
m_interestFilterTable.push_back(registeredPrefix->getFilter());
}
- if (static_cast<bool>(onSuccess)) {
+ if (onSuccess != nullptr) {
onSuccess(registeredPrefix->getPrefix());
}
}
@@ -274,13 +249,11 @@
const UnregisterPrefixSuccessCallback& onSuccess,
const UnregisterPrefixFailureCallback& onFailure)
{
- using namespace nfd;
auto i = std::find_if(m_registeredPrefixTable.begin(),
m_registeredPrefixTable.end(),
MatchRegisteredPrefixId(registeredPrefixId));
if (i != m_registeredPrefixTable.end()) {
RegisteredPrefix& record = **i;
-
const shared_ptr<InterestFilterRecord>& filter = record.getFilter();
if (filter != nullptr) {
@@ -290,10 +263,11 @@
ControlParameters params;
params.setName(record.getPrefix());
- m_face.m_nfdController->start<RibUnregisterCommand>(params,
- bind(&Impl::finalizeUnregisterPrefix, this, i, onSuccess),
- bind(onFailure, _2),
- record.getCommandOptions());
+ m_face.m_nfdController->start<nfd::RibUnregisterCommand>(
+ params,
+ [=] (const ControlParameters&) { this->finalizeUnregisterPrefix(i, onSuccess); },
+ [=] (uint32_t code, const std::string& reason) { onFailure(reason); },
+ record.getCommandOptions());
}
else {
if (onFailure != nullptr) {
@@ -310,11 +284,24 @@
{
m_registeredPrefixTable.erase(item);
- if (static_cast<bool>(onSuccess)) {
+ if (onSuccess != nullptr) {
onSuccess();
}
}
+public: // IO routine
+ void
+ ensureConnected(bool wantResume)
+ {
+ if (!m_face.m_transport->isConnected())
+ m_face.m_transport->connect(m_face.m_ioService,
+ [=] (const Block& wire) { m_face.onReceiveElement(wire); });
+
+ if (wantResume && !m_face.m_transport->isReceiving()) {
+ m_face.m_transport->resume();
+ }
+ }
+
void
onEmptyPitOrNoRegisteredPrefixes()
{
diff --git a/src/detail/interest-filter-record.hpp b/src/detail/interest-filter-record.hpp
index f23123e..c2916f8 100644
--- a/src/detail/interest-filter-record.hpp
+++ b/src/detail/interest-filter-record.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -22,24 +22,40 @@
#ifndef NDN_DETAIL_INTEREST_FILTER_RECORD_HPP
#define NDN_DETAIL_INTEREST_FILTER_RECORD_HPP
-#include "../common.hpp"
#include "../name.hpp"
#include "../interest.hpp"
namespace ndn {
+/**
+ * @brief associates an InterestFilter with Interest callback
+ */
class InterestFilterRecord : noncopyable
{
public:
- typedef function<void (const InterestFilter&, const Interest&)> InterestCallback;
-
- InterestFilterRecord(const InterestFilter& filter, const InterestCallback& afterInterest)
+ /**
+ * @brief Construct an Interest filter record
+ *
+ * @param filter an InterestFilter that represents what Interest should invoke the callback
+ * @param interestCallback invoked when matching Interest is received
+ */
+ InterestFilterRecord(const InterestFilter& filter,
+ const InterestCallback& interestCallback)
: m_filter(filter)
- , m_afterInterest(afterInterest)
+ , m_interestCallback(interestCallback)
{
}
/**
+ * @return the filter
+ */
+ const InterestFilter&
+ getFilter() const
+ {
+ return m_filter;
+ }
+
+ /**
* @brief Check if Interest name matches the filter
* @param name Interest Name
*/
@@ -51,28 +67,20 @@
/**
* @brief invokes the InterestCallback
- * @note If the DataCallback is an empty function, this method does nothing.
*/
void
invokeInterestCallback(const Interest& interest) const
{
- m_afterInterest(m_filter, interest);
- }
-
- const InterestFilter&
- getFilter() const
- {
- return m_filter;
+ m_interestCallback(m_filter, interest);
}
private:
InterestFilter m_filter;
- InterestCallback m_afterInterest;
+ InterestCallback m_interestCallback;
};
-
/**
- * @brief Opaque class representing ID of the Interest filter
+ * @brief Opaque type to identify an InterestFilterRecord
*/
class InterestFilterId;
@@ -91,8 +99,9 @@
bool
operator()(const shared_ptr<InterestFilterRecord>& interestFilterId) const
{
- return (reinterpret_cast<const InterestFilterId*>(interestFilterId.get()) == m_id);
+ return reinterpret_cast<const InterestFilterId*>(interestFilterId.get()) == m_id;
}
+
private:
const InterestFilterId* m_id;
};
diff --git a/src/detail/pending-interest.hpp b/src/detail/pending-interest.hpp
index bac5836..f21fc2e 100644
--- a/src/detail/pending-interest.hpp
+++ b/src/detail/pending-interest.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -22,28 +22,30 @@
#ifndef NDN_DETAIL_PENDING_INTEREST_HPP
#define NDN_DETAIL_PENDING_INTEREST_HPP
-#include "../common.hpp"
#include "../interest.hpp"
#include "../data.hpp"
-#include "../util/time.hpp"
-#include "../util/scheduler.hpp"
-#include "../util/scheduler-scoped-event-id.hpp"
#include "../lp/nack.hpp"
+#include "../util/scheduler-scoped-event-id.hpp"
namespace ndn {
+/**
+ * @brief stores a pending Interest and associated callbacks
+ */
class PendingInterest : noncopyable
{
public:
/**
- * @brief Create a new PitEntry and set the timeout based on the current time and
- * the Interest lifetime.
- * @param interest shared_ptr for the Interest
- * @param dataCallback function to call when matching Data packet is received
- * @param nackCallback function to call when Nack matching Interest is received
- * @param timeoutCallback function to call if Interest times out
- * @param scheduler Scheduler instance to use to schedule a timeout event. The scheduled
- * event will be automatically cancelled when pending Interest is destroyed.
+ * @brief Construct a pending Interest record
+ *
+ * The timeout is set based on the current time and the Interest lifetime.
+ * This class will invoke the timeout callback unless the record is deleted before timeout.
+ *
+ * @param interest the Interest
+ * @param dataCallback invoked when matching Data packet is received
+ * @param nackCallback invoked when Nack matching Interest is received
+ * @param timeoutCallback invoked when Interest times out
+ * @param scheduler Scheduler for scheduling the timeout event
*/
PendingInterest(shared_ptr<const Interest> interest,
const DataCallback& dataCallback,
@@ -60,7 +62,7 @@
scheduler.scheduleEvent(m_interest->getInterestLifetime() > time::milliseconds::zero() ?
m_interest->getInterestLifetime() :
DEFAULT_INTEREST_LIFETIME,
- bind(&PendingInterest::invokeTimeoutCallback, this));
+ [=] { this->invokeTimeoutCallback(); });
}
/**
@@ -73,8 +75,7 @@
}
/**
- * @brief invokes the DataCallback
- * @note If the DataCallback is an empty function, this method does nothing.
+ * @brief invokes the Data callback
*/
void
invokeDataCallback(const Data& data)
@@ -83,8 +84,7 @@
}
/**
- * @brief invokes the NackCallback
- * @note If the NackCallback is an empty function, this method does nothing.
+ * @brief invokes the Nack callback
*/
void
invokeNackCallback(const lp::Nack& nack)
@@ -93,7 +93,7 @@
}
/**
- * @brief Set cleanup function to be called after interest times out
+ * @brief Set cleanup function to be invoked when Interest times out
*/
void
setDeleter(const std::function<void()>& deleter)
@@ -103,8 +103,7 @@
private:
/**
- * @brief invokes the TimeoutCallback
- * @note If the TimeoutCallback is an empty function, this method does nothing.
+ * @brief invokes the timeout callback (if non-empty) and the deleter
*/
void
invokeTimeoutCallback()
@@ -126,11 +125,13 @@
std::function<void()> m_deleter;
};
-
+/**
+ * @brief Opaque type to identify a PendingInterest
+ */
class PendingInterestId;
/**
- * @brief Functor to match pending interests against PendingInterestId
+ * @brief Functor to match PendingInterestId
*/
class MatchPendingInterestId
{
@@ -144,14 +145,13 @@
bool
operator()(const shared_ptr<const PendingInterest>& pendingInterest) const
{
- return (reinterpret_cast<const PendingInterestId*>(
- pendingInterest->getInterest().get()) == m_id);
+ return reinterpret_cast<const PendingInterestId*>(pendingInterest->getInterest().get()) == m_id;
}
+
private:
const PendingInterestId* m_id;
};
-
} // namespace ndn
#endif // NDN_DETAIL_PENDING_INTEREST_HPP
diff --git a/src/detail/registered-prefix.hpp b/src/detail/registered-prefix.hpp
index 983f5ea..bdc69bf 100644
--- a/src/detail/registered-prefix.hpp
+++ b/src/detail/registered-prefix.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -32,19 +32,14 @@
namespace ndn {
+/**
+ * @brief stores information about a prefix registered in NDN forwarder
+ */
class RegisteredPrefix : noncopyable
{
public:
- /** \brief a callback on command success
- */
- typedef function<void(const nfd::ControlParameters&)> SuccessCallback;
-
- /** \brief a callback on command failure
- */
- typedef function<void(uint32_t/*code*/,const std::string&/*reason*/)> FailureCallback;
-
RegisteredPrefix(const Name& prefix,
- const shared_ptr<InterestFilterRecord>& filter,
+ shared_ptr<InterestFilterRecord> filter,
const nfd::CommandOptions& options)
: m_prefix(prefix)
, m_filter(filter)
@@ -77,7 +72,7 @@
};
/**
- * @brief Opaque class representing ID of the registered prefix
+ * @brief Opaque type to identify a RegisteredPrefix
*/
class RegisteredPrefixId;
@@ -96,13 +91,13 @@
bool
operator()(const shared_ptr<RegisteredPrefix>& registeredPrefix) const
{
- return (reinterpret_cast<const RegisteredPrefixId*>(registeredPrefix.get()) == m_id);
+ return reinterpret_cast<const RegisteredPrefixId*>(registeredPrefix.get()) == m_id;
}
+
private:
const RegisteredPrefixId* m_id;
};
-
} // namespace ndn
#endif // NDN_DETAIL_REGISTERED_PREFIX_HPP
diff --git a/src/face.cpp b/src/face.cpp
index 4d68927..b52a54d 100644
--- a/src/face.cpp
+++ b/src/face.cpp
@@ -31,13 +31,13 @@
namespace ndn {
-Face::Face()
+Face::Face(shared_ptr<Transport> transport)
: m_internalIoService(new boost::asio::io_service())
, m_ioService(*m_internalIoService)
, m_internalKeyChain(new KeyChain())
, m_impl(new Impl(*this))
{
- construct(nullptr, *m_internalKeyChain);
+ construct(transport, *m_internalKeyChain);
}
Face::Face(boost::asio::io_service& ioService)
@@ -48,7 +48,7 @@
construct(nullptr, *m_internalKeyChain);
}
-Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
+Face::Face(const std::string& host, const std::string& port)
: m_internalIoService(new boost::asio::io_service())
, m_ioService(*m_internalIoService)
, m_internalKeyChain(new KeyChain())
@@ -57,19 +57,9 @@
construct(make_shared<TcpTransport>(host, port), *m_internalKeyChain);
}
-Face::Face(shared_ptr<Transport> transport)
- : m_internalIoService(new boost::asio::io_service())
- , m_ioService(*m_internalIoService)
- , m_internalKeyChain(new KeyChain())
- , m_impl(new Impl(*this))
-{
- construct(transport, *m_internalKeyChain);
-}
-
Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
: m_internalIoService(new boost::asio::io_service())
, m_ioService(*m_internalIoService)
- , m_internalKeyChain(nullptr)
, m_impl(new Impl(*this))
{
construct(transport, keyChain);
@@ -85,7 +75,6 @@
Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain)
: m_ioService(ioService)
- , m_internalKeyChain(nullptr)
, m_impl(new Impl(*this))
{
construct(transport, keyChain);
@@ -99,8 +88,9 @@
std::string transportUri;
- if (getenv("NDN_CLIENT_TRANSPORT") != nullptr) {
- transportUri = getenv("NDN_CLIENT_TRANSPORT");
+ const char* transportEnviron = getenv("NDN_CLIENT_TRANSPORT");
+ if (transportEnviron != nullptr) {
+ transportUri = transportEnviron;
}
else {
ConfigFile config;
@@ -171,8 +161,9 @@
}
// If the same ioService thread, dispatch directly calls the method
- m_ioService.dispatch([=] { m_impl->asyncExpressInterest(interestToExpress, afterSatisfied,
- afterNacked, afterTimeout); });
+ m_ioService.dispatch([=] {
+ m_impl->asyncExpressInterest(interestToExpress, afterSatisfied, afterNacked, afterTimeout);
+ });
return reinterpret_cast<const PendingInterestId*>(interestToExpress.get());
}
@@ -199,13 +190,10 @@
}
const PendingInterestId*
-Face::expressInterest(const Name& name,
- const Interest& tmpl,
- const OnData& onData, const OnTimeout& onTimeout/* = nullptr*/)
+Face::expressInterest(const Name& name, const Interest& tmpl,
+ const OnData& onData, const OnTimeout& onTimeout)
{
- return expressInterest(Interest(tmpl)
- .setName(name)
- .setNonce(0),
+ return expressInterest(Interest(tmpl).setName(name).setNonce(0),
onData, onTimeout);
}
@@ -256,46 +244,38 @@
const RegisteredPrefixId*
Face::setInterestFilter(const InterestFilter& interestFilter,
- const OnInterest& onInterest,
- const RegisterPrefixFailureCallback& onFailure,
- const security::SigningInfo& signingInfo,
- uint64_t flags)
+ const InterestCallback& onInterest,
+ const RegisterPrefixFailureCallback& onFailure,
+ const security::SigningInfo& signingInfo,
+ uint64_t flags)
{
- return setInterestFilter(interestFilter,
- onInterest,
- RegisterPrefixSuccessCallback(),
- onFailure,
- signingInfo,
- flags);
+ return setInterestFilter(interestFilter, onInterest, nullptr, onFailure, signingInfo, flags);
}
const RegisteredPrefixId*
Face::setInterestFilter(const InterestFilter& interestFilter,
- const OnInterest& onInterest,
- const RegisterPrefixSuccessCallback& onSuccess,
- const RegisterPrefixFailureCallback& onFailure,
- const security::SigningInfo& signingInfo,
- uint64_t flags)
+ const InterestCallback& onInterest,
+ const RegisterPrefixSuccessCallback& onSuccess,
+ const RegisterPrefixFailureCallback& onFailure,
+ const security::SigningInfo& signingInfo,
+ uint64_t flags)
{
- shared_ptr<InterestFilterRecord> filter =
- make_shared<InterestFilterRecord>(interestFilter, onInterest);
+ auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
- nfd::CommandOptions options;
- options.setSigningInfo(signingInfo);
+ nfd::CommandOptions options;
+ options.setSigningInfo(signingInfo);
- return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
- onSuccess, onFailure,
- flags, options);
+ return m_impl->registerPrefix(interestFilter.getPrefix(), filter,
+ onSuccess, onFailure, flags, options);
}
const InterestFilterId*
Face::setInterestFilter(const InterestFilter& interestFilter,
- const OnInterest& onInterest)
+ const InterestCallback& onInterest)
{
- shared_ptr<InterestFilterRecord> filter =
- make_shared<InterestFilterRecord>(interestFilter, onInterest);
+ auto filter = make_shared<InterestFilterRecord>(interestFilter, onInterest);
- getIoService().post([=] { m_impl->asyncSetInterestFilter(filter); });
+ m_ioService.post([=] { m_impl->asyncSetInterestFilter(filter); });
return reinterpret_cast<const InterestFilterId*>(filter.get());
}
@@ -314,9 +294,7 @@
if (!certificate.getName().empty()) {
signingInfo = signingByCertificate(certificate.getName());
}
- return setInterestFilter(interestFilter, onInterest,
- onSuccess, onFailure,
- signingInfo, flags);
+ return setInterestFilter(interestFilter, onInterest, onSuccess, onFailure, signingInfo, flags);
}
const RegisteredPrefixId*
@@ -330,8 +308,7 @@
if (!certificate.getName().empty()) {
signingInfo = signingByCertificate(certificate.getName());
}
- return setInterestFilter(interestFilter, onInterest,
- onFailure, signingInfo, flags);
+ return setInterestFilter(interestFilter, onInterest, onFailure, signingInfo, flags);
}
const RegisteredPrefixId*
@@ -343,7 +320,6 @@
uint64_t flags)
{
security::SigningInfo signingInfo = signingByIdentity(identity);
-
return setInterestFilter(interestFilter, onInterest,
onSuccess, onFailure,
signingInfo, flags);
@@ -357,27 +333,22 @@
uint64_t flags)
{
security::SigningInfo signingInfo = signingByIdentity(identity);
-
- return setInterestFilter(interestFilter, onInterest,
- onFailure, signingInfo, flags);
+ return setInterestFilter(interestFilter, onInterest, onFailure, signingInfo, flags);
}
#endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
const RegisteredPrefixId*
Face::registerPrefix(const Name& prefix,
- const RegisterPrefixSuccessCallback& onSuccess,
- const RegisterPrefixFailureCallback& onFailure,
- const security::SigningInfo& signingInfo,
- uint64_t flags)
+ const RegisterPrefixSuccessCallback& onSuccess,
+ const RegisterPrefixFailureCallback& onFailure,
+ const security::SigningInfo& signingInfo,
+ uint64_t flags)
{
+ nfd::CommandOptions options;
+ options.setSigningInfo(signingInfo);
- nfd::CommandOptions options;
- options.setSigningInfo(signingInfo);
-
- return m_impl->registerPrefix(prefix, shared_ptr<InterestFilterRecord>(),
- onSuccess, onFailure,
- flags, options);
+ return m_impl->registerPrefix(prefix, nullptr, onSuccess, onFailure, flags, options);
}
#ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
@@ -392,8 +363,7 @@
if (!certificate.getName().empty()) {
signingInfo = signingByCertificate(certificate.getName());
}
- return registerPrefix(prefix, onSuccess,
- onFailure, signingInfo, flags);
+ return registerPrefix(prefix, onSuccess, onFailure, signingInfo, flags);
}
const RegisteredPrefixId*
@@ -404,17 +374,14 @@
uint64_t flags)
{
security::SigningInfo signingInfo = signingByIdentity(identity);
- return registerPrefix(prefix, onSuccess,
- onFailure, signingInfo, flags);
+ return registerPrefix(prefix, onSuccess, onFailure, signingInfo, flags);
}
#endif // NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
void
Face::unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId)
{
- m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,
- UnregisterPrefixSuccessCallback(),
- UnregisterPrefixFailureCallback()); });
+ m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId, nullptr, nullptr); });
}
void
@@ -428,12 +395,11 @@
const UnregisterPrefixSuccessCallback& onSuccess,
const UnregisterPrefixFailureCallback& onFailure)
{
- m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId,onSuccess, onFailure); });
+ m_ioService.post([=] { m_impl->asyncUnregisterPrefix(registeredPrefixId, onSuccess, onFailure); });
}
void
-Face::processEvents(const time::milliseconds& timeout/* = time::milliseconds::zero()*/,
- bool keepThread/* = false*/)
+Face::processEvents(const time::milliseconds& timeout, bool keepThread)
{
if (m_ioService.stopped()) {
m_ioService.reset(); // ensure that run()/poll() will do some work
@@ -441,19 +407,19 @@
try {
if (timeout < time::milliseconds::zero()) {
- // do not block if timeout is negative, but process pending events
- m_ioService.poll();
- return;
- }
+ // do not block if timeout is negative, but process pending events
+ m_ioService.poll();
+ return;
+ }
if (timeout > time::milliseconds::zero()) {
boost::asio::io_service& ioService = m_ioService;
unique_ptr<boost::asio::io_service::work>& work = m_impl->m_ioServiceWork;
- m_impl->m_processEventsTimeoutEvent =
- m_impl->m_scheduler.scheduleEvent(timeout, [&ioService, &work] {
- ioService.stop();
- work.reset();
- });
+ m_impl->m_processEventsTimeoutEvent = m_impl->m_scheduler.scheduleEvent(timeout,
+ [&ioService, &work] {
+ ioService.stop();
+ work.reset();
+ });
}
if (keepThread) {
@@ -512,7 +478,7 @@
Block netPacket(&*begin, std::distance(begin, end));
switch (netPacket.type()) {
case tlv::Interest: {
- shared_ptr<Interest> interest = make_shared<Interest>(netPacket);
+ auto interest = make_shared<Interest>(netPacket);
if (lpPacket.has<lp::NackField>()) {
auto nack = make_shared<lp::Nack>(std::move(*interest));
nack->setHeader(lpPacket.get<lp::NackField>());
@@ -526,7 +492,7 @@
break;
}
case tlv::Data: {
- shared_ptr<Data> data = make_shared<Data>(netPacket);
+ auto data = make_shared<Data>(netPacket);
extractLpLocalFields(*data, lpPacket);
m_impl->satisfyPendingInterests(*data);
break;
diff --git a/src/face.hpp b/src/face.hpp
index fe6af03..c83a9ae 100644
--- a/src/face.hpp
+++ b/src/face.hpp
@@ -62,59 +62,65 @@
} // namespace nfd
/**
- * @brief Callback called when expressed Interest gets satisfied with a Data packet
+ * @brief Callback invoked when expressed Interest gets satisfied with a Data packet
*/
typedef function<void(const Interest&, const Data&)> DataCallback;
/**
- * @brief Callback called when Nack is sent in response to expressed Interest
+ * @brief Callback invoked when Nack is sent in response to expressed Interest
*/
typedef function<void(const Interest&, const lp::Nack&)> NackCallback;
/**
- * @brief Callback called when expressed Interest times out
+ * @brief Callback invoked when expressed Interest times out
*/
typedef function<void(const Interest&)> TimeoutCallback;
/**
- * @brief Callback called when expressed Interest gets satisfied with Data packet
+ * @brief Callback invoked when expressed Interest gets satisfied with Data packet
* @deprecated use DataCallback
*/
typedef function<void(const Interest&, Data&)> OnData;
/**
- * @brief Callback called when expressed Interest times out
+ * @brief Callback invoked when expressed Interest times out
* @deprecated use TimeoutCallback
*/
typedef function<void(const Interest&)> OnTimeout;
/**
- * @brief Callback called when incoming Interest matches the specified InterestFilter
+ * @brief Callback invoked when incoming Interest matches the specified InterestFilter
+ */
+typedef function<void(const InterestFilter&, const Interest&)> InterestCallback;
+
+/**
+ * @brief Callback invoked when incoming Interest matches the specified InterestFilter
+ * @deprecated use InterestCallback
*/
typedef function<void (const InterestFilter&, const Interest&)> OnInterest;
/**
- * @brief Callback called when registerPrefix or setInterestFilter command succeeds
+ * @brief Callback invoked when registerPrefix or setInterestFilter command succeeds
*/
typedef function<void(const Name&)> RegisterPrefixSuccessCallback;
/**
- * @brief Callback called when registerPrefix or setInterestFilter command fails
+ * @brief Callback invoked when registerPrefix or setInterestFilter command fails
*/
typedef function<void(const Name&, const std::string&)> RegisterPrefixFailureCallback;
/**
- * @brief Callback called when unregisterPrefix or unsetInterestFilter command succeeds
+ * @brief Callback invoked when unregisterPrefix or unsetInterestFilter command succeeds
*/
typedef function<void()> UnregisterPrefixSuccessCallback;
/**
- * @brief Callback called when unregisterPrefix or unsetInterestFilter command fails
+ * @brief Callback invoked when unregisterPrefix or unsetInterestFilter command fails
*/
typedef function<void(const std::string&)> UnregisterPrefixFailureCallback;
/**
- * @brief Abstraction to communicate with local or remote NDN forwarder
+ * @brief Provide a communication channel with local or remote NDN forwarder
*/
class Face : noncopyable
{
@@ -131,101 +137,99 @@
public: // constructors
/**
- * @brief Create a new Face using the default transport (UnixTransport)
+ * @brief Create Face using given transport (or default transport if omitted)
+ * @param transport the transport for lower layer communication. If nullptr,
+ * a default transport will be used. The default transport is
+ * determined from a FaceUri in NDN_CLIENT_TRANSPORT environ,
+ * a FaceUri in configuration file 'transport' key, or UnixTransport.
*
- * @throws ConfigFile::Error on configuration file parse failure
- * @throws ConfigFile::Error if configuration file specifies an unsupported protocol
+ * @throw ConfigFile::Error if @p transport is nullptr, and the configuration file cannot be
+ * parsed or specifies an unsupported protocol
+ * @note shared_ptr is passed by value because ownership is shared with this class
*/
- Face();
+ explicit
+ Face(shared_ptr<Transport> transport = nullptr);
/**
- * @brief Create a new Face using the default transport (UnixTransport)
+ * @brief Create Face using default transport and given io_service
*
- * @par Usage examples:
+ * Usage examples:
*
- * Face face1;
- * Face face2(face1.getIoService());
+ * @code
+ * Face face1;
+ * Face face2(face1.getIoService());
*
- * // Now the following ensures that events on both faces are processed
- * face1.processEvents();
- * // or face1.getIoService().run();
+ * // Now the following ensures that events on both faces are processed
+ * face1.processEvents();
+ * // or face1.getIoService().run();
+ * @endcode
*
- * @par or
+ * or
*
- * boost::asio::io_service ioService;
- * Face face1(ioService);
- * Face face2(ioService);
- * ...
+ * @code
+ * boost::asio::io_service ioService;
+ * Face face1(ioService);
+ * Face face2(ioService);
*
- * ioService.run();
+ * ioService.run();
+ * @endcode
*
* @param ioService A reference to boost::io_service object that should control all
* IO operations.
- * @throws ConfigFile::Error on configuration file parse failure
- * @throws ConfigFile::Error if configuration file specifies an unsupported protocol
+ * @throw ConfigFile::Error the configuration file cannot be parsed or specifies an unsupported protocol
*/
explicit
Face(boost::asio::io_service& ioService);
/**
- * @brief Create a new Face using TcpTransport
+ * @brief Create Face using TcpTransport
*
- * @param host The host of the NDN forwarder
- * @param port (optional) The port or service name of the NDN forwarder (**default**: "6363")
+ * @param host IP address or hostname of the NDN forwarder
+ * @param port port number or service name of the NDN forwarder (**default**: "6363")
*/
Face(const std::string& host, const std::string& port = "6363");
/**
- * @brief Create a new Face using the given Transport
- * @param transport the Transport used for communication. If nullptr, then the default
- * transport will be used.
- *
- * @throws ConfigFile::Error if @p transport is nullptr on configuration file parse failure
- * @throws ConfigFile::Error if @p transport is nullptr and the configuration file
- * specifies an unsupported protocol
- * @note shared_ptr is passed by value because ownership is shared with this class
- */
- explicit
- Face(shared_ptr<Transport> transport);
-
- /**
- * @brief Create a new Face using the given Transport and KeyChain instance
- * @param transport the Transport used for communication. If nullptr, then the default
- * transport will be used.
+ * @brief Create Face using given transport and KeyChain
+ * @param transport the transport for lower layer communication. If nullptr,
+ * a default transport will be used.
* @param keyChain the KeyChain to sign commands
*
- * @throws ConfigFile::Error if @p transport is nullptr on configuration file parse failure
- * @throws ConfigFile::Error if @p transport is nullptr and the configuration file
- * specifies an unsupported protocol
+ * @sa Face(shared_ptr<Transport>)
+ *
+ * @throw ConfigFile::Error if @p transport is nullptr, and the configuration file cannot be
+ * parsed or specifies an unsupported protocol
* @note shared_ptr is passed by value because ownership is shared with this class
*/
Face(shared_ptr<Transport> transport, KeyChain& keyChain);
/**
- * @brief Create a new Face using the given Transport and IO service object
- * @param transport the Transport used for communication. If nullptr, then the default
- * transport will be used.
+ * @brief Create Face using given transport and IO service
+ * @param transport the transport for lower layer communication. If nullptr,
+ * a default transport will be used.
* @param ioService the io_service that controls all IO operations
*
* @sa Face(boost::asio::io_service&)
+ * @sa Face(shared_ptr<Transport>)
*
- * @throws ConfigFile::Error if @p transport is nullptr on configuration file parse failure
- * @throws ConfigFile::Error if @p transport is nullptr and the configuration file
- * specifies an unsupported protocol
+ * @throw ConfigFile::Error if @p transport is nullptr, and the configuration file cannot be
+ * parsed or specifies an unsupported protocol
* @note shared_ptr is passed by value because ownership is shared with this class
*/
Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService);
/**
- * @brief Create a new Face using the given Transport and IO service object
- * @param transport the Transport used for communication. If nullptr, then the default
- * transport will be used.
+ * @brief Create a new Face using given Transport and IO service
+ * @param transport the transport for lower layer communication. If nullptr,
+ * a default transport will be used.
* @param ioService the io_service that controls all IO operations
* @param keyChain the KeyChain to sign commands
*
- * @throws ConfigFile::Error if @p transport is nullptr on configuration file parse failure
- * @throws ConfigFile::Error if @p transport is nullptr and the configuration file
- * specifies an unsupported protocol
+ * @sa Face(boost::asio::io_service&)
+ * @sa Face(shared_ptr<Transport>, KeyChain&)
+ *
+ * @throw ConfigFile::Error if @p transport is nullptr, and the configuration file cannot be
+ * parsed or specifies an unsupported protocol
* @note shared_ptr is passed by value because ownership is shared with this class
*/
Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain);
@@ -257,7 +261,7 @@
*
* @return The pending interest ID which can be used with removePendingInterest
*
- * @throws Error when Interest size exceeds maximum limit (MAX_NDN_PACKET_SIZE)
+ * @throw Error when Interest size exceeds maximum limit (MAX_NDN_PACKET_SIZE)
*
* @deprecated use expressInterest(Interest, DataCallback, NackCallback, TimeoutCallback)
*/
@@ -276,7 +280,7 @@
*
* @return Opaque pending interest ID which can be used with removePendingInterest
*
- * @throws Error when Interest size exceeds maximum limit (MAX_NDN_PACKET_SIZE)
+ * @throw Error when Interest size exceeds maximum limit (MAX_NDN_PACKET_SIZE)
*
* @deprecated use expressInterest(Interest, DataCallback, NackCallback, TimeoutCallback)
*/
@@ -329,7 +333,7 @@
*/
const RegisteredPrefixId*
setInterestFilter(const InterestFilter& interestFilter,
- const OnInterest& onInterest,
+ const InterestCallback& onInterest,
const RegisterPrefixFailureCallback& onFailure,
const security::SigningInfo& signingInfo = security::SigningInfo(),
uint64_t flags = nfd::ROUTE_FLAG_CHILD_INHERIT);
@@ -357,7 +361,7 @@
*/
const RegisteredPrefixId*
setInterestFilter(const InterestFilter& interestFilter,
- const OnInterest& onInterest,
+ const InterestCallback& onInterest,
const RegisterPrefixSuccessCallback& onSuccess,
const RegisterPrefixFailureCallback& onFailure,
const security::SigningInfo& signingInfo = security::SigningInfo(),
@@ -377,7 +381,7 @@
*/
const InterestFilterId*
setInterestFilter(const InterestFilter& interestFilter,
- const OnInterest& onInterest);
+ const InterestCallback& onInterest);
#ifdef NDN_FACE_KEEP_DEPRECATED_REGISTRATION_SIGNING
/**
@@ -634,7 +638,7 @@
* extra copy of the Data packet to ensure validity of published Data until
* asynchronous put() operation finishes.
*
- * @throws Error when Data size exceeds maximum limit (MAX_NDN_PACKET_SIZE)
+ * @throw Error when Data size exceeds maximum limit (MAX_NDN_PACKET_SIZE)
*/
void
put(const Data& data);
@@ -685,7 +689,7 @@
shutdown();
/**
- * @brief Get reference to IO service object
+ * @return reference to IO service object
*/
boost::asio::io_service&
getIoService()
@@ -695,21 +699,20 @@
NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
/**
- * @brief Get the underlying transport of the face
+ * @return underlying transport
*/
shared_ptr<Transport>
getTransport();
private:
-
/**
- * @throws ConfigFile::Error on parse error and unsupported protocols
+ * @throw ConfigFile::Error on parse error and unsupported protocols
*/
shared_ptr<Transport>
makeDefaultTransport();
/**
- * @throws Face::Error on unsupported protocol
+ * @throw Face::Error on unsupported protocol
* @note shared_ptr is passed by value because ownership is transferred to this function
*/
void
@@ -729,11 +732,12 @@
shared_ptr<Transport> m_transport;
- /** @brief if not null, a pointer to an internal KeyChain owned by Face
- * @note if a KeyChain is supplied to constructor, this pointer will be null,
- * and the passed KeyChain is given to nfdController;
- * currently Face does not keep the KeyChain passed in constructor
- * because it's not needed, but this may change in the future
+ /**
+ * @brief if not null, a pointer to an internal KeyChain owned by Face
+ * @note if a KeyChain is supplied to constructor, this pointer will be null,
+ * and the passed KeyChain is given to nfdController;
+ * currently Face does not keep the KeyChain passed in constructor
+ * because it's not needed, but this may change in the future
*/
unique_ptr<KeyChain> m_internalKeyChain;
diff --git a/src/interest-filter.cpp b/src/interest-filter.cpp
index c360a41..36e08f1 100644
--- a/src/interest-filter.cpp
+++ b/src/interest-filter.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2014 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -20,38 +20,46 @@
*/
#include "interest-filter.hpp"
-
#include "util/regex/regex-pattern-list-matcher.hpp"
namespace ndn {
+InterestFilter::InterestFilter(const Name& prefix)
+ : m_prefix(prefix)
+{
+}
+
+InterestFilter::InterestFilter(const char* prefixUri)
+ : m_prefix(prefixUri)
+{
+}
+
+InterestFilter::InterestFilter(const std::string& prefixUri)
+ : m_prefix(prefixUri)
+{
+}
+
InterestFilter::InterestFilter(const Name& prefix, const std::string& regexFilter)
: m_prefix(prefix)
- , m_regexFilter(ndn::make_shared<RegexPatternListMatcher>(regexFilter,
- shared_ptr<RegexBackrefManager>()))
+ , m_regexFilter(make_shared<RegexPatternListMatcher>(regexFilter, nullptr))
{
}
+InterestFilter::operator const Name&() const
+{
+ if (hasRegexFilter()) {
+ BOOST_THROW_EXCEPTION(Error("Please update InterestCallback to accept const InterestFilter&"
+ " (non-trivial InterestFilter is being used)"));
+ }
+ return m_prefix;
+}
+
bool
InterestFilter::doesMatch(const Name& name) const
{
- if (name.size() < m_prefix.size())
- return false;
-
- if (hasRegexFilter()) {
- // perform prefix match and regular expression match for the remaining components
- bool isMatch = m_prefix.isPrefixOf(name);
-
- if (!isMatch)
- return false;
-
- return m_regexFilter->match(name, m_prefix.size(), name.size() - m_prefix.size());
- }
- else {
- // perform just prefix match
-
- return m_prefix.isPrefixOf(name);
- }
+ return m_prefix.isPrefixOf(name) &&
+ (!hasRegexFilter() ||
+ m_regexFilter->match(name, m_prefix.size(), name.size() - m_prefix.size()));
}
std::ostream&
diff --git a/src/interest-filter.hpp b/src/interest-filter.hpp
index 074f527..d6241a1 100644
--- a/src/interest-filter.hpp
+++ b/src/interest-filter.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -28,6 +28,10 @@
class RegexPatternListMatcher;
+/**
+ * @brief declares the set of Interests a producer can serve,
+ * which starts with a name prefix, plus an optional regular expression
+ */
class InterestFilter
{
public:
@@ -42,66 +46,63 @@
};
/**
- * @brief Create an Interest filter to match Interests by prefix
+ * @brief Construct an InterestFilter to match Interests by prefix
*
- * This filter will match all Interests, whose name start with the given prefix
+ * This filter matches Interests whose name start with the given prefix.
*
- * Any Name can be implicitly converted to the InterestFilter.
+ * @note InterestFilter is implicitly convertible from Name.
*/
InterestFilter(const Name& prefix);
/**
- * @brief Create an Interest filter to match Interests by prefix URI
+ * @brief Construct an InterestFilter to match Interests by prefix
*
- * This filter will match all Interests, whose name start with the given prefix
+ * This filter matches Interests whose name start with the given prefix.
*
- * Any const char* can be implicitly converted to the InterestFilter.
+ * @param prefixUri name prefix, interpreted as ndn URI
+ * @note InterestFilter is implicitly convertible from null-terminated byte string.
*/
InterestFilter(const char* prefixUri);
/**
- * @brief Create an Interest filter to match Interests by prefix URI
+ * @brief Construct an InterestFilter to match Interests by prefix
*
- * This filter will match all Interests, whose name start with the given prefix
+ * This filter matches Interests whose name start with the given prefix.
*
- * Any std::string can be implicitly converted to the InterestFilter.
+ * @param prefixUri name prefix, interpreted as ndn URI
+ * @note InterestFilter is implicitly convertible from std::string.
*/
InterestFilter(const std::string& prefixUri);
/**
- * @brief Create an Interest filter to match Interest by prefix and regular expression
+ * @brief Construct an InterestFilter to match Interests by prefix and regular expression
*
- * This filter will match all Interests, whose name start with the given prefix and
- * other components of the Interest name match the given regular expression.
+ * This filter matches Interests whose name start with the given prefix and
+ * the remaining components match the given regular expression.
* For example, the following InterestFilter:
*
* InterestFilter("/hello", "<world><>+")
*
- * will match all Interests, whose name has prefix `/hello`, which is followed by
- * component `world` and has at least one more component after it. Examples:
+ * matches Interests whose name has prefix `/hello` followed by component `world`
+ * and has at least one more component after it, such as:
*
- * /hello/world/!
+ * /hello/world/%21
* /hello/world/x/y/z
*
- * Note that regular expression will need to match all components (e.g., there is
- * an implicit heading `^` and trailing `$` symbols in the regular expression).
+ * Note that regular expression will need to match all components (e.g., there are
+ * implicit heading `^` and trailing `$` symbols in the regular expression).
*/
InterestFilter(const Name& prefix, const std::string& regexFilter);
/**
- * @brief Implicit conversion to Name (to provide backwards compatibility for onInterest callback)
+ * @brief Implicit conversion to Name
+ * @note This allows InterestCallback to be declared with `Name` rather than `InterestFilter`,
+ * but this does not work if InterestFilter has regular expression.
*/
- operator const Name&() const
- {
- if (static_cast<bool>(m_regexFilter)) {
- BOOST_THROW_EXCEPTION(Error("Please update OnInterest callback to accept const "
- "InterestFilter& (non-trivial Interest filter is being used)"));
- }
- return m_prefix;
- }
+ operator const Name&() const;
/**
- * @brief Check if specified name matches the filter
+ * @brief Check if specified Interest name matches the filter
*/
bool
doesMatch(const Name& name) const;
@@ -115,7 +116,7 @@
bool
hasRegexFilter() const
{
- return static_cast<bool>(m_regexFilter);
+ return m_regexFilter != nullptr;
}
const RegexPatternListMatcher&
@@ -132,25 +133,6 @@
std::ostream&
operator<<(std::ostream& os, const InterestFilter& filter);
-
-inline
-InterestFilter::InterestFilter(const Name& prefix)
- : m_prefix(prefix)
-{
-}
-
-inline
-InterestFilter::InterestFilter(const char* prefixUri)
- : m_prefix(prefixUri)
-{
-}
-
-inline
-InterestFilter::InterestFilter(const std::string& prefixUri)
- : m_prefix(prefixUri)
-{
-}
-
} // namespace ndn
#endif // NDN_INTEREST_FILTER_HPP
diff --git a/tests/unit-tests/face.t.cpp b/tests/unit-tests/face.t.cpp
index 1fc9c86..2ffe6d4 100644
--- a/tests/unit-tests/face.t.cpp
+++ b/tests/unit-tests/face.t.cpp
@@ -60,6 +60,8 @@
BOOST_FIXTURE_TEST_SUITE(TestFace, FaceFixture)
+BOOST_AUTO_TEST_SUITE(Consumer)
+
BOOST_AUTO_TEST_CASE(ExpressInterestData)
{
size_t nData = 0;
@@ -69,12 +71,8 @@
BOOST_CHECK_EQUAL(i.getName(), "/Hello/World");
++nData;
},
- bind([] {
- BOOST_FAIL("Unexpected Nack");
- }),
- bind([] {
- BOOST_FAIL("Unexpected timeout");
- }));
+ bind([] { BOOST_FAIL("Unexpected Nack"); }),
+ bind([] { BOOST_FAIL("Unexpected timeout"); }));
advanceClocks(time::milliseconds(1), 40);
@@ -91,9 +89,7 @@
face.expressInterest(Interest("/Hello/World/a/2", time::milliseconds(50)),
bind([]{}),
bind([]{}),
- bind([&nTimeouts] {
- ++nTimeouts;
- }));
+ bind([&nTimeouts] { ++nTimeouts; }));
advanceClocks(time::milliseconds(10), 100);
BOOST_CHECK_EQUAL(nTimeouts, 1);
}
@@ -103,13 +99,11 @@
{
size_t nData = 0;
face.expressInterest(Interest("/Hello/World", time::milliseconds(50)),
- [&] (const Interest& i, const Data& d) {
+ [&] (const Interest& i, Data& d) {
BOOST_CHECK(i.getName().isPrefixOf(d.getName()));
++nData;
},
- bind([] {
- BOOST_FAIL("Unexpected timeout");
- }));
+ bind([] { BOOST_FAIL("Unexpected timeout"); }));
advanceClocks(time::milliseconds(1), 40);
@@ -123,13 +117,11 @@
BOOST_CHECK_EQUAL(face.sentData.size(), 0);
face.expressInterest(Interest("/Hello/World/a", time::milliseconds(50)),
- [&] (const Interest& i, const Data& d) {
+ [&] (const Interest& i, Data& d) {
BOOST_CHECK(i.getName().isPrefixOf(d.getName()));
++nData;
},
- bind([] {
- BOOST_FAIL("Unexpected timeout");
- }));
+ bind([] { BOOST_FAIL("Unexpected timeout"); }));
advanceClocks(time::milliseconds(1), 40);
face.receive(*makeData("/Hello/World/a/1/xxxxx"));
@@ -142,9 +134,7 @@
size_t nTimeouts = 0;
face.expressInterest(Interest("/Hello/World/a/2", time::milliseconds(50)),
bind([]{}),
- bind([&nTimeouts] {
- ++nTimeouts;
- }));
+ bind([&nTimeouts] { ++nTimeouts; }));
advanceClocks(time::milliseconds(10), 100);
BOOST_CHECK_EQUAL(nTimeouts, 1);
}
@@ -153,12 +143,8 @@
{
size_t nTimeouts = 0;
face.expressInterest(Interest("/Hello/World", time::milliseconds(50)),
- bind([] {
- BOOST_FAIL("Unexpected ata");
- }),
- bind([] {
- BOOST_FAIL("Unexpected Nack");
- }),
+ bind([] { BOOST_FAIL("Unexpected Data"); }),
+ bind([] { BOOST_FAIL("Unexpected Nack"); }),
[&nTimeouts] (const Interest& i) {
BOOST_CHECK_EQUAL(i.getName(), "/Hello/World");
++nTimeouts;
@@ -177,12 +163,8 @@
{
size_t nTimeouts = 0;
face.expressInterest(Interest("/Hello/World", time::milliseconds(50)),
- bind([] {
- BOOST_FAIL("Unexpected data");
- }),
- bind([&nTimeouts] {
- ++nTimeouts;
- }));
+ bind([] { BOOST_FAIL("Unexpected data"); }),
+ bind([&nTimeouts] { ++nTimeouts; }));
advanceClocks(time::milliseconds(10), 100);
@@ -198,18 +180,14 @@
Interest interest("/Hello/World", time::milliseconds(50));
face.expressInterest(interest,
- bind([] {
- BOOST_FAIL("Unexpected Data");
- }),
+ bind([] { BOOST_FAIL("Unexpected Data"); }),
[&] (const Interest& i, const lp::Nack& n) {
BOOST_CHECK(i.getName().isPrefixOf(n.getInterest().getName()));
BOOST_CHECK_EQUAL(i.getName(), "/Hello/World");
BOOST_CHECK_EQUAL(n.getReason(), lp::NackReason::DUPLICATE);
++nNacks;
},
- bind([] {
- BOOST_FAIL("Unexpected timeout");
- }));
+ bind([] { BOOST_FAIL("Unexpected timeout"); }));
advanceClocks(time::milliseconds(1), 40);
@@ -230,22 +208,19 @@
{
const PendingInterestId* interestId =
face.expressInterest(Interest("/Hello/World", time::milliseconds(50)),
- bind([] {
- BOOST_FAIL("Unexpected data");
- }),
- bind([] {
- BOOST_FAIL("Unexpected timeout");
- }));
+ bind([] { BOOST_FAIL("Unexpected data"); }),
+ bind([] { BOOST_FAIL("Unexpected nack"); }),
+ bind([] { BOOST_FAIL("Unexpected timeout"); }));
advanceClocks(time::milliseconds(10));
face.removePendingInterest(interestId);
advanceClocks(time::milliseconds(10));
- face.receive(*makeData("/Hello/World/!"));
+ face.receive(*makeData("/Hello/World/%21"));
advanceClocks(time::milliseconds(10), 100);
}
-BOOST_AUTO_TEST_CASE(removeAllPendingInterests)
+BOOST_AUTO_TEST_CASE(RemoveAllPendingInterests)
{
face.expressInterest(Interest("/Hello/World/0", time::milliseconds(50)),
bind([] { BOOST_FAIL("Unexpected data"); }),
@@ -269,6 +244,36 @@
advanceClocks(time::milliseconds(10), 100);
}
+BOOST_AUTO_TEST_CASE(DestructionWithoutCancellingPendingInterests) // Bug #2518
+{
+ {
+ DummyClientFace face2(io, m_keyChain);
+ face2.expressInterest(Interest("/Hello/World", time::milliseconds(50)),
+ bind([]{}), bind([]{}));
+ advanceClocks(time::milliseconds(10), 10);
+ }
+
+ advanceClocks(time::milliseconds(10), 10);
+ // should not segfault
+}
+
+BOOST_AUTO_TEST_SUITE_END() // Consumer
+
+BOOST_AUTO_TEST_SUITE(Producer)
+
+BOOST_AUTO_TEST_CASE(PutNack)
+{
+ lp::Nack nack(Interest("/Hello/World", time::milliseconds(50)));
+ nack.setReason(lp::NackReason::NO_ROUTE);
+
+ BOOST_CHECK_EQUAL(face.sentNacks.size(), 0);
+
+ face.put(nack);
+
+ advanceClocks(time::milliseconds(10));
+
+ BOOST_CHECK_EQUAL(face.sentNacks.size(), 1);
+}
BOOST_AUTO_TEST_CASE(SetUnsetInterestFilter)
{
@@ -278,24 +283,22 @@
face.setInterestFilter("/Hello/World",
bind([&nInterests] { ++nInterests; }),
bind([&nRegs] { ++nRegs; }),
- bind([] {
- BOOST_FAIL("Unexpected setInterestFilter failure");
- }));
+ bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
advanceClocks(time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(nRegs, 1);
BOOST_CHECK_EQUAL(nInterests, 0);
- face.receive(Interest("/Hello/World/!"));
+ face.receive(Interest("/Hello/World/%21"));
advanceClocks(time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(nRegs, 1);
BOOST_CHECK_EQUAL(nInterests, 1);
- face.receive(Interest("/Bye/World/!"));
+ face.receive(Interest("/Bye/World/%21"));
advanceClocks(time::milliseconds(10000), 10);
BOOST_CHECK_EQUAL(nInterests, 1);
- face.receive(Interest("/Hello/World/!/2"));
+ face.receive(Interest("/Hello/World/%21/2"));
advanceClocks(time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(nInterests, 2);
@@ -303,13 +306,13 @@
face.unsetInterestFilter(regPrefixId);
advanceClocks(time::milliseconds(10), 10);
- face.receive(Interest("/Hello/World/!/3"));
+ face.receive(Interest("/Hello/World/%21/3"));
BOOST_CHECK_EQUAL(nInterests, 2);
- face.unsetInterestFilter(static_cast<const RegisteredPrefixId*>(0));
+ face.unsetInterestFilter(static_cast<const RegisteredPrefixId*>(nullptr));
advanceClocks(time::milliseconds(10), 10);
- face.unsetInterestFilter(static_cast<const InterestFilterId*>(0));
+ face.unsetInterestFilter(static_cast<const InterestFilterId*>(nullptr));
advanceClocks(time::milliseconds(10), 10);
}
@@ -319,22 +322,20 @@
const RegisteredPrefixId* regPrefixId =
face.setInterestFilter("/Hello/World",
bind([&nInterests] { ++nInterests; }),
- bind([] {
- BOOST_FAIL("Unexpected setInterestFilter failure");
- }));
+ bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
advanceClocks(time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(nInterests, 0);
- face.receive(Interest("/Hello/World/!"));
+ face.receive(Interest("/Hello/World/%21"));
advanceClocks(time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(nInterests, 1);
- face.receive(Interest("/Bye/World/!"));
+ face.receive(Interest("/Bye/World/%21"));
advanceClocks(time::milliseconds(10000), 10);
BOOST_CHECK_EQUAL(nInterests, 1);
- face.receive(Interest("/Hello/World/!/2"));
+ face.receive(Interest("/Hello/World/%21/2"));
advanceClocks(time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(nInterests, 2);
@@ -342,13 +343,13 @@
face.unsetInterestFilter(regPrefixId);
advanceClocks(time::milliseconds(10), 10);
- face.receive(Interest("/Hello/World/!/3"));
+ face.receive(Interest("/Hello/World/%21/3"));
BOOST_CHECK_EQUAL(nInterests, 2);
- face.unsetInterestFilter(static_cast<const RegisteredPrefixId*>(0));
+ face.unsetInterestFilter(static_cast<const RegisteredPrefixId*>(nullptr));
advanceClocks(time::milliseconds(10), 10);
- face.unsetInterestFilter(static_cast<const InterestFilterId*>(0));
+ face.unsetInterestFilter(static_cast<const InterestFilterId*>(nullptr));
advanceClocks(time::milliseconds(10), 10);
}
@@ -357,15 +358,9 @@
// don't enable registration reply
size_t nRegFailed = 0;
face.setInterestFilter("/Hello/World",
- bind([] {
- BOOST_FAIL("Unexpected Interest");
- }),
- bind([] {
- BOOST_FAIL("Unexpected success of setInterestFilter");
- }),
- bind([&nRegFailed] {
- ++nRegFailed;
- }));
+ bind([] { BOOST_FAIL("Unexpected Interest"); }),
+ bind([] { BOOST_FAIL("Unexpected success of setInterestFilter"); }),
+ bind([&nRegFailed] { ++nRegFailed; }));
advanceClocks(time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(nRegFailed, 0);
@@ -379,12 +374,8 @@
// don't enable registration reply
size_t nRegFailed = 0;
face.setInterestFilter("/Hello/World",
- bind([] {
- BOOST_FAIL("Unexpected Interest");
- }),
- bind([&nRegFailed] {
- ++nRegFailed;
- }));
+ bind([] { BOOST_FAIL("Unexpected Interest"); }),
+ bind([&nRegFailed] { ++nRegFailed; }));
advanceClocks(time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(nRegFailed, 0);
@@ -399,9 +390,7 @@
const RegisteredPrefixId* regPrefixId =
face.registerPrefix("/Hello/World",
bind([&nRegSuccesses] { ++nRegSuccesses; }),
- bind([] {
- BOOST_FAIL("Unexpected registerPrefix failure");
- }));
+ bind([] { BOOST_FAIL("Unexpected registerPrefix failure"); }));
advanceClocks(time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(nRegSuccesses, 1);
@@ -409,9 +398,7 @@
size_t nUnregSuccesses = 0;
face.unregisterPrefix(regPrefixId,
bind([&nUnregSuccesses] { ++nUnregSuccesses; }),
- bind([] {
- BOOST_FAIL("Unexpected unregisterPrefix failure");
- }));
+ bind([] { BOOST_FAIL("Unexpected unregisterPrefix failure"); }));
advanceClocks(time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(nUnregSuccesses, 1);
@@ -421,9 +408,7 @@
{
size_t nRegFailures = 0;
face.registerPrefix("/Hello/World",
- bind([] {
- BOOST_FAIL("Unexpected registerPrefix success");
- }),
+ bind([] { BOOST_FAIL("Unexpected registerPrefix success"); }),
bind([&nRegFailures] { ++nRegFailures; }));
advanceClocks(time::milliseconds(1000), 100);
@@ -435,30 +420,24 @@
size_t nInInterests1 = 0;
face.setInterestFilter("/Hello/World",
bind([&nInInterests1] { ++nInInterests1; }),
- RegisterPrefixSuccessCallback(),
- bind([] {
- BOOST_FAIL("Unexpected setInterestFilter failure");
- }));
+ nullptr,
+ bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
size_t nInInterests2 = 0;
face.setInterestFilter("/Hello",
bind([&nInInterests2] { ++nInInterests2; }),
- RegisterPrefixSuccessCallback(),
- bind([] {
- BOOST_FAIL("Unexpected setInterestFilter failure");
- }));
+ nullptr,
+ bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
size_t nInInterests3 = 0;
face.setInterestFilter("/Los/Angeles/Lakers",
bind([&nInInterests3] { ++nInInterests3; }),
- RegisterPrefixSuccessCallback(),
- bind([] {
- BOOST_FAIL("Unexpected setInterestFilter failure");
- }));
+ nullptr,
+ bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
advanceClocks(time::milliseconds(10), 10);
- face.receive(Interest("/Hello/World/!"));
+ face.receive(Interest("/Hello/World/%21"));
advanceClocks(time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(nInInterests1, 1);
@@ -472,10 +451,8 @@
[] (const Name&, const Interest&) {
BOOST_FAIL("InterestFilter::Error should have been triggered");
},
- RegisterPrefixSuccessCallback(),
- bind([] {
- BOOST_FAIL("Unexpected setInterestFilter failure");
- }));
+ nullptr,
+ bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
advanceClocks(time::milliseconds(10), 10);
@@ -487,10 +464,8 @@
size_t nInInterests = 0;
face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
bind([&nInInterests] { ++nInInterests; }),
- RegisterPrefixSuccessCallback(),
- bind([] {
- BOOST_FAIL("Unexpected setInterestFilter failure");
- }));
+ nullptr,
+ bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
advanceClocks(time::milliseconds(10), 10);
@@ -516,9 +491,7 @@
size_t nRegSuccesses = 0;
face.registerPrefix("/Hello/World",
bind([&nRegSuccesses] { ++nRegSuccesses; }),
- bind([] {
- BOOST_FAIL("Unexpected setInterestFilter failure");
- }));
+ bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
advanceClocks(time::milliseconds(10), 10);
BOOST_CHECK_EQUAL(nRegSuccesses, 1);
@@ -552,6 +525,8 @@
BOOST_CHECK_EQUAL(hit, 1);
}
+BOOST_AUTO_TEST_SUITE_END() // Producer
+
BOOST_AUTO_TEST_CASE(ProcessEvents)
{
face.processEvents(time::milliseconds(-1)); // io_service::reset()/poll() inside
@@ -559,9 +534,7 @@
size_t nRegSuccesses = 0;
face.registerPrefix("/Hello/World",
bind([&nRegSuccesses] { ++nRegSuccesses; }),
- bind([] {
- BOOST_FAIL("Unexpected setInterestFilter failure");
- }));
+ bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
// io_service::poll() without reset
face.getIoService().poll();
@@ -571,33 +544,6 @@
BOOST_CHECK_EQUAL(nRegSuccesses, 1);
}
-BOOST_AUTO_TEST_CASE(PutNack)
-{
- lp::Nack nack(Interest("/Hello/World", time::milliseconds(50)));
- nack.setReason(lp::NackReason::NO_ROUTE);
-
- BOOST_CHECK_EQUAL(face.sentNacks.size(), 0);
-
- face.put(nack);
-
- advanceClocks(time::milliseconds(10));
-
- BOOST_CHECK_EQUAL(face.sentNacks.size(), 1);
-}
-
-BOOST_AUTO_TEST_CASE(DestructionWithoutCancellingPendingInterests) // Bug #2518
-{
- {
- DummyClientFace face2(io, m_keyChain);
- face2.expressInterest(Interest("/Hello/World", time::milliseconds(50)),
- bind([]{}), bind([]{}));
- advanceClocks(time::milliseconds(10), 10);
- }
-
- advanceClocks(time::milliseconds(10), 10);
- // should not segfault
-}
-
struct PibDirWithDefaultTpm
{
const std::string PATH = "build/keys-with-default-tpm";