Major change: in expressInterest, remove the Closure class and use function objects for onData and onTimeout.
diff --git a/ndn-cpp/closure.hpp b/ndn-cpp/closure.hpp
deleted file mode 100644
index 210ad17..0000000
--- a/ndn-cpp/closure.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @author: Jeff Thompson
- * This is a port of py from PyCCN, written by:
- * Derek Kulinski <takeda@takeda.tk>
- * Jeff Burke <jburke@ucla.edu>
- *
- * See COPYING for copyright and distribution information.
- */
-
-#ifndef NDN_CLOSURE_HPP
-#define NDN_CLOSURE_HPP
-
-#include "common.hpp"
-
-namespace ndn {
-
-enum UpcallResult {
- CLOSURE_RESULT_ERR = -1, // upcall detected an error
- CLOSURE_RESULT_OK = 0, // normal upcall return
- CLOSURE_RESULT_REEXPRESS = 1, // reexpress the same interest again
- CLOSURE_RESULT_INTEREST_CONSUMED = 2, // upcall claims to consume interest
- CLOSURE_RESULT_VERIFY = 3, // force an unverified result to be verified
- CLOSURE_RESULT_FETCHKEY = 4 // get the key in the key locator and re-call the interest
-};
-
-enum UpcallKind {
- UPCALL_FINAL = 0, // handler is about to be deregistered
- UPCALL_INTEREST = 1, // incoming interest
- UPCALL_CONSUMED_INTEREST = 2, // incoming interest, someone has answered
- UPCALL_DATA = 3, // incoming verified data packet
- UPCALL_INTEREST_TIMED_OUT = 4, // interest timed out
- UPCALL_DATA_UNVERIFIED = 5, // data packet that has not been verified
- UPCALL_DATA_BAD = 6 // verification failed
-};
-
-class Node;
-class Interest;
-class Data;
-
-class UpcallInfo {
-public:
- UpcallInfo(Node *node, const ptr_lib::shared_ptr<const Interest> &interest, int matchedComps, const ptr_lib::shared_ptr<Data> &data)
- : node_(node), interest_(interest), data_(data)
- {
- }
-
- Node *getNode() { return node_; }
-
- const ptr_lib::shared_ptr<const Interest> &getInterest() const { return interest_; }
-
- const ptr_lib::shared_ptr<Data> &getData() const { return data_; }
-
-private:
- Node *node_;
- ptr_lib::shared_ptr<const Interest> interest_;
- ptr_lib::shared_ptr<Data> data_;
-};
-
-class Closure {
-public:
- virtual UpcallResult upcall(UpcallKind kind, const UpcallInfo &upcallInfo) = 0;
-};
-
-}
-
-#endif
diff --git a/ndn-cpp/face.hpp b/ndn-cpp/face.hpp
index b317fa6..8db72a8 100644
--- a/ndn-cpp/face.hpp
+++ b/ndn-cpp/face.hpp
@@ -46,21 +46,56 @@
/**
* Encode name as an Interest. If interestTemplate is not 0, use its interest selectors.
- * Send the interest through the transport, read the entire response and call
- * closure->upcall(UPCALL_DATA (or UPCALL_DATA_UNVERIFIED),
- * UpcallInfo(this, interest, 0, data)).
- * @param name reference to a Name for the interest. This does not keep a pointer to the Name object.
- * @param closure a pointer for the Closure. The caller must manage the memory for the Closure. This will not try to delete it.
+ * Send the interest through the transport, read the entire response and call onData(interest, data).
+ * @param name A reference to a Name for the interest. This does not keep a pointer to the Name object.
* @param interestTemplate if not 0, copy interest selectors from the template. This does not keep a pointer to the Interest object.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
*/
- void expressInterest(const Name &name, Closure *closure, const Interest *interestTemplate)
+ void expressInterest(const Name &name, const Interest *interestTemplate, const OnData &onData, const OnTimeout &onTimeout)
{
- node_.expressInterest(name, closure, interestTemplate);
+ node_.expressInterest(name, interestTemplate, onData, onTimeout);
+ }
+
+ /**
+ * Encode name as an Interest, using a default interest lifetime.
+ * Send the interest through the transport, read the entire response and call onData(interest, data).
+ * @param name A reference to a Name for the interest. This does not keep a pointer to the Name object.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ */
+ void expressInterest(const Name &name, const OnData &onData, const OnTimeout &onTimeout)
+ {
+ node_.expressInterest(name, onData, onTimeout);
}
- void expressInterest(const Name &name, Closure *closure)
+ /**
+ * Encode name as an Interest. If interestTemplate is not 0, use its interest selectors.
+ * Send the interest through the transport, read the entire response and call onData(interest, data).
+ * @param name A reference to a Name for the interest. This does not keep a pointer to the Name object.
+ * @param interestTemplate if not 0, copy interest selectors from the template. This does not keep a pointer to the Interest object.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ */
+ void expressInterest(const Name &name, const Interest *interestTemplate, const OnData &onData)
{
- node_.expressInterest(name, closure);
+ node_.expressInterest(name, interestTemplate, onData);
+ }
+
+ /**
+ * Encode name as an Interest, using a default interest lifetime.
+ * Send the interest through the transport, read the entire response and call onData(interest, data).
+ * @param name A reference to a Name for the interest. This does not keep a pointer to the Name object.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ */
+ void expressInterest(const Name &name, const OnData &onData)
+ {
+ node_.expressInterest(name, onData);
}
/**
diff --git a/ndn-cpp/node.cpp b/ndn-cpp/node.cpp
index 77befa3..802b84a 100644
--- a/ndn-cpp/node.cpp
+++ b/ndn-cpp/node.cpp
@@ -22,8 +22,8 @@
return t.tv_sec * 1000.0 + t.tv_usec / 1000.0;
}
-Node::PitEntry::PitEntry(const ptr_lib::shared_ptr<const Interest> &interest, Closure *closure)
-: interest_(interest), closure_(closure)
+Node::PitEntry::PitEntry(const ptr_lib::shared_ptr<const Interest> &interest, const OnData &onData, const OnTimeout &onTimeout)
+: interest_(interest), onData_(onData), onTimeout_(onTimeout)
{
// Set up timeoutTime_.
if (interest_->getInterestLifetimeMilliseconds() >= 0.0)
@@ -44,14 +44,13 @@
bool Node::PitEntry::checkTimeout(Node *parent, double nowMilliseconds)
{
if (timeoutTimeMilliseconds_ >= 0.0 && nowMilliseconds >= timeoutTimeMilliseconds_) {
- shared_ptr<Data> dummyData;
- UpcallInfo upcallInfo(parent, interest_, 0, dummyData);
-
- // Ignore all exceptions.
- try {
- closure_->upcall(UPCALL_INTEREST_TIMED_OUT, upcallInfo);
+ if (onTimeout_) {
+ // Ignore all exceptions.
+ try {
+ onTimeout_(interest_);
+ }
+ catch (...) { }
}
- catch (...) { }
return true;
}
@@ -59,7 +58,7 @@
return false;
}
-void Node::expressInterest(const Name &name, Closure *closure, const Interest *interestTemplate)
+void Node::expressInterest(const Name &name, const Interest *interestTemplate, const OnData &onData, const OnTimeout &onTimeout)
{
shared_ptr<const Interest> interest;
if (interestTemplate)
@@ -71,7 +70,7 @@
else
interest.reset(new Interest(name, 4000.0));
- shared_ptr<PitEntry> pitEntry(new PitEntry(interest, closure));
+ shared_ptr<PitEntry> pitEntry(new PitEntry(interest, onData, onTimeout));
pit_.push_back(pitEntry);
shared_ptr<vector<unsigned char> > encoding = pitEntry->getInterest()->wireEncode();
@@ -109,12 +108,11 @@
int iPitEntry = getEntryIndexForExpressedInterest(data->getName());
if (iPitEntry >= 0) {
- UpcallInfo upcallInfo(this, pit_[iPitEntry]->getInterest(), 0, data);
-
- // Remove the PIT entry before the calling the callback.
- Closure *closure = pit_[iPitEntry]->getClosure();
+ // Copy pointers to the needed objects and remove the PIT entry before the calling the callback.
+ const OnData onData = pit_[iPitEntry]->getOnData();
+ const ptr_lib::shared_ptr<const Interest> interest = pit_[iPitEntry]->getInterest();
pit_.erase(pit_.begin() + iPitEntry);
- closure->upcall(UPCALL_DATA, upcallInfo);
+ onData(interest, data);
}
}
}
diff --git a/ndn-cpp/node.hpp b/ndn-cpp/node.hpp
index b72ba9c..911298b 100644
--- a/ndn-cpp/node.hpp
+++ b/ndn-cpp/node.hpp
@@ -6,13 +6,23 @@
#ifndef NDN_NODE_HPP
#define NDN_NODE_HPP
+#include "common.hpp"
#include "interest.hpp"
-#include "closure.hpp"
#include "transport/udp-transport.hpp"
#include "encoding/binary-xml-element-reader.hpp"
namespace ndn {
+/**
+ * An OnData function object is used to pass a callback to expressInterest.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<const Interest> &, const ptr_lib::shared_ptr<Data> &)> OnData;
+
+/**
+ * An OnTimeout function object is used to pass a callback to expressInterest.
+ */
+typedef func_lib::function<void(const ptr_lib::shared_ptr<const Interest> &)> OnTimeout;
+
class Face;
class Node : public ElementListener {
@@ -48,18 +58,53 @@
/**
* Encode name as an Interest. If interestTemplate is not 0, use its interest selectors.
- * Send the interest through the transport, read the entire response and call
- * closure->upcall(UPCALL_DATA (or UPCALL_DATA_UNVERIFIED),
- * UpcallInfo(this, interest, 0, data)).
- * @param name reference to a Name for the interest. This does not keep a pointer to the Name object.
- * @param closure a pointer for the Closure. The caller must manage the memory for the Closure. This will not try to delete it.
+ * Send the interest through the transport, read the entire response and call onData(interest, data).
+ * @param name A reference to a Name for the interest. This does not keep a pointer to the Name object.
* @param interestTemplate if not 0, copy interest selectors from the template. This does not keep a pointer to the Interest object.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
*/
- void expressInterest(const Name &name, Closure *closure, const Interest *interestTemplate);
-
- void expressInterest(const Name &name, Closure *closure)
+ void expressInterest(const Name &name, const Interest *interestTemplate, const OnData &onData, const OnTimeout &onTimeout);
+
+ /**
+ * Encode name as an Interest, using a default interest lifetime.
+ * Send the interest through the transport, read the entire response and call onData(interest, data).
+ * @param name A reference to a Name for the interest. This does not keep a pointer to the Name object.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
+ */
+ void expressInterest(const Name &name, const OnData &onData, const OnTimeout &onTimeout)
{
- expressInterest(name, closure, 0);
+ expressInterest(name, 0, onData, onTimeout);
+ }
+
+ /**
+ * Encode name as an Interest. If interestTemplate is not 0, use its interest selectors.
+ * Send the interest through the transport, read the entire response and call onData(interest, data).
+ * @param name A reference to a Name for the interest. This does not keep a pointer to the Name object.
+ * @param interestTemplate if not 0, copy interest selectors from the template. This does not keep a pointer to the Interest object.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ */
+ void expressInterest(const Name &name, const Interest *interestTemplate, const OnData &onData)
+ {
+ expressInterest(name, interestTemplate, onData, OnTimeout());
+ }
+
+ /**
+ * Encode name as an Interest, using a default interest lifetime.
+ * Send the interest through the transport, read the entire response and call onData(interest, data).
+ * @param name A reference to a Name for the interest. This does not keep a pointer to the Name object.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ */
+ void expressInterest(const Name &name, const OnData &onData)
+ {
+ expressInterest(name, 0, onData);
}
/**
@@ -85,14 +130,16 @@
/**
* Create a new PitEntry and set the timeoutTime_ based on the current time and the interest lifetime.
* @param interest A shared_ptr for the interest.
- * @param closure A pointer to the closure with the callbacks to call on match.
- * The caller must manage the memory for the Closure. This will not try to delete it.
+ * @param onData A function object to call when a matching data packet is received. This copies the function object, so you may need to
+ * use func_lib::ref() as appropriate.
+ * @param onTimeout A function object to call if the interest times out. If onTimeout is an empty OnTimeout(), this does not use it.
+ * This copies the function object, so you may need to use func_lib::ref() as appropriate.
*/
- PitEntry(const ptr_lib::shared_ptr<const Interest> &interest, Closure *closure);
+ PitEntry(const ptr_lib::shared_ptr<const Interest> &interest, const OnData &onData, const OnTimeout &onTimeout);
const ptr_lib::shared_ptr<const Interest> &getInterest() { return interest_; }
- Closure *getClosure() { return closure_; }
+ const OnData &getOnData() { return onData_; }
/**
* Get the struct ndn_Interest for the interest_.
@@ -108,7 +155,7 @@
}
/**
- * If this interest is timed out, call the timeout callback and return true.
+ * If this interest is timed out, call onTimeout_ (if defined) and return true.
* @param parent The parent Node for the UpcallInfo.
* @param nowMilliseconds The current time in milliseconds from gettimeofday.
* @return true if this interest timed out and the timeout callback was called, otherwise false.
@@ -121,7 +168,8 @@
std::vector<struct ndn_ExcludeEntry> excludeEntries_;
struct ndn_Interest interestStruct_;
- Closure *closure_;
+ const OnData onData_;
+ const OnTimeout onTimeout_;
double timeoutTimeMilliseconds_; /**< The time when the interest times out in milliseconds according to gettimeofday, or -1 for no timeout. */
};