face+transport: Cleanup and preparation for implementation of fully async Face operations

Change-Id: I7816b6a9c99a0cf4825459b9652372d6585a5191
diff --git a/include/ndn-cpp/face.hpp b/include/ndn-cpp/face.hpp
index a0b3f0e..c7e0826 100644
--- a/include/ndn-cpp/face.hpp
+++ b/include/ndn-cpp/face.hpp
@@ -9,7 +9,8 @@
 #define NDN_FACE_HPP
 
 #include "node.hpp"
-#include "transport/tcp-transport.hpp"
+#include "transport/transport.hpp"
+#include "transport/unix-transport.hpp"
 
 namespace ndn {
 
@@ -19,6 +20,16 @@
 class Face {
 public:
   /**
+   * Create a new Face for communication with an NDN hub at host:port using the default TcpTransport.
+   * @param host The host of the NDN hub.
+   * @param port The port of the NDN hub. If omitted. use 6363.
+   */
+  Face()
+  : node_(ptr_lib::shared_ptr<UnixTransport>(new UnixTransport()))
+  {
+  }
+
+  /**
    * Create a new Face for communication with an NDN hub with the given Transport object and connectionInfo.
    * @param transport A shared_ptr to a Transport object used for communication.
    * @param transport A shared_ptr to a Transport::ConnectionInfo to be used to connect to the transport.
@@ -33,10 +44,10 @@
    * @param host The host of the NDN hub.
    * @param port The port of the NDN hub. If omitted. use 6363.
    */
-  Face(const char *host, unsigned short port = 6363)
-  : node_(ptr_lib::shared_ptr<TcpTransport>(new TcpTransport(host, port)))
-  {
-  }
+  // Face(const char *host, unsigned short port = 6363)
+  // : node_(ptr_lib::shared_ptr<TcpTransport>(new TcpTransport(host, port)))
+  // {
+  // }
     
   /**
    * Send the Interest through the transport, read the entire response and call onData(interest, data).
@@ -50,10 +61,9 @@
    */
   uint64_t 
   expressInterest
-    (const Interest& interest, const OnData& onData, const OnTimeout& onTimeout = OnTimeout(),
-     WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
+    (const Interest& interest, const OnData& onData, const OnTimeout& onTimeout = OnTimeout())
   {
-    return node_.expressInterest(interest, onData, onTimeout, wireFormat);
+    return node_.expressInterest(interest, onData, onTimeout);
   }
 
   /**
@@ -70,8 +80,7 @@
    */
   uint64_t 
   expressInterest
-    (const Name& name, const Interest *interestTemplate, const OnData& onData, const OnTimeout& onTimeout = OnTimeout(),
-     WireFormat& wireFormat = *WireFormat::getDefaultWireFormat());
+    (const Name& name, const Interest *interestTemplate, const OnData& onData, const OnTimeout& onTimeout = OnTimeout());
 
   /**
    * Encode name as an Interest, using a default interest lifetime.
@@ -86,10 +95,9 @@
    */
   uint64_t 
   expressInterest
-    (const Name& name, const OnData& onData, const OnTimeout& onTimeout = OnTimeout(),
-     WireFormat& wireFormat = *WireFormat::getDefaultWireFormat()) 
+    (const Name& name, const OnData& onData, const OnTimeout& onTimeout = OnTimeout()) 
   {
-    return expressInterest(name, 0, onData, onTimeout, wireFormat);
+    return expressInterest(name, 0, onData, onTimeout);
   }
 
   /**
@@ -118,10 +126,9 @@
    */
   uint64_t 
   setInterestFilter
-    (const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags = ForwardingFlags(), 
-     WireFormat& wireFormat = *WireFormat::getDefaultWireFormat())
+    (const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags = ForwardingFlags())
   {
-    return node_.registerPrefix(prefix, onInterest, onRegisterFailed, flags, wireFormat);
+    return node_.registerPrefix(prefix, onInterest, onRegisterFailed, flags);
   }
 
   /**
diff --git a/include/ndn-cpp/node.hpp b/include/ndn-cpp/node.hpp
index c68372d..3c43480 100644
--- a/include/ndn-cpp/node.hpp
+++ b/include/ndn-cpp/node.hpp
@@ -11,11 +11,9 @@
 #include "common.hpp"
 #include "interest.hpp"
 #include "data.hpp"
-#include "transport/tcp-transport.hpp"
 #include "forwarding-flags.hpp"
-#include "encoding/element-listener.hpp"
+#include "transport/transport.hpp"
 
-struct ndn_Interest;
 
 namespace ndn {
 
@@ -41,9 +39,8 @@
 typedef func_lib::function<void(const ptr_lib::shared_ptr<const Name>&)> OnRegisterFailed;
 
 class Face;
-class KeyChain;
     
-class Node : public ElementListener {
+class Node {
 public:
   /**
    * Create a new Node for communication with an NDN hub with the given Transport object and connectionInfo.
@@ -63,7 +60,7 @@
    * @return The pending interest ID which can be used with removePendingInterest.
    */
   uint64_t 
-  expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout, WireFormat& wireFormat);
+  expressInterest(const Interest& interest, const OnData& onData, const OnTimeout& onTimeout);
   
   /**
    * Remove the pending interest entry with the pendingInterestId from the pending interest table.
@@ -87,8 +84,7 @@
    */
   uint64_t 
   registerPrefix
-    (const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags, 
-     WireFormat& wireFormat);
+    (const Name& prefix, const OnInterest& onInterest, const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags);
 
   /**
    * Remove the registered prefix entry with the registeredPrefixId from the pending interest table.  
@@ -113,12 +109,13 @@
   getTransport() { return transport_; }
   
   void 
-  onReceivedElement(const uint8_t *element, size_t elementLength);
-  
-  void 
   shutdown();
 
 private:
+  void 
+  onReceiveElement(const Block &wire);
+
+private:
   class PendingInterest {
   public:
     /**
@@ -154,20 +151,6 @@
     getOnData() { return onData_; }
     
     /**
-     * Get the struct ndn_Interest for the interest_.
-     * WARNING: Assume that this PitEntry was created with new, so that no copy constructor is invoked between calls.
-     * This class is private to Node and only used by its methods, so this should be OK.
-     * TODO: Doesn't this functionality belong in the Interest class?
-     * @return A reference to the ndn_Interest struct.
-     * WARNING: The resulting pointers in are invalid uses getInterest() to manipulate the object which could reallocate memory.
-     */
-    const struct ndn_Interest& 
-    getInterestStruct()
-    {
-      return *interestStruct_;
-    }
-    
-    /**
      * Check if this interest is timed out.
      * @param nowMilliseconds The current time in milliseconds from ndn_getNowMilliseconds.
      * @return true if this interest timed out, otherwise false.
@@ -185,15 +168,13 @@
     callTimeout();
     
   private:
-    ptr_lib::shared_ptr<const Interest> interest_;
-    std::vector<struct ndn_NameComponent> nameComponents_;
-    std::vector<struct ndn_ExcludeEntry> excludeEntries_;
-    ptr_lib::shared_ptr<struct ndn_Interest> interestStruct_;
-  
     static uint64_t lastPendingInterestId_; /**< A class variable used to get the next unique ID. */
+
     uint64_t pendingInterestId_;            /**< A unique identifier for this entry so it can be deleted */
+    ptr_lib::shared_ptr<const Interest> interest_;
     const OnData onData_;
     const OnTimeout onTimeout_;
+    
     MillisecondsSince1970 timeoutTimeMilliseconds_; /**< The time when the interest times out in milliseconds according to ndn_getNowMilliseconds, or -1 for no timeout. */
   };
 
@@ -206,7 +187,9 @@
      * @param onInterest A function object to call when a matching data packet is received.
      */
     RegisteredPrefix(uint64_t registeredPrefixId, const ptr_lib::shared_ptr<const Name>& prefix, const OnInterest& onInterest)
-    : registeredPrefixId_(registeredPrefixId), prefix_(prefix), onInterest_(onInterest)
+      : registeredPrefixId_(registeredPrefixId)
+      , prefix_(prefix)
+      , onInterest_(onInterest)
     {
     }
     
@@ -223,79 +206,33 @@
      * Return the registeredPrefixId given to the constructor.
      */
     uint64_t 
-    getRegisteredPrefixId() { return registeredPrefixId_; }
+    getRegisteredPrefixId()
+    {
+      return registeredPrefixId_;
+    }
     
     const ptr_lib::shared_ptr<const Name>& 
-    getPrefix() { return prefix_; }
+    getPrefix()
+    {
+      return prefix_;
+    }
     
     const OnInterest& 
-    getOnInterest() { return onInterest_; }
+    getOnInterest()
+    {
+      return onInterest_;
+    }
     
   private:
     static uint64_t lastRegisteredPrefixId_; /**< A class variable used to get the next unique ID. */
+
     uint64_t registeredPrefixId_;            /**< A unique identifier for this entry so it can be deleted */
     ptr_lib::shared_ptr<const Name> prefix_;
     const OnInterest onInterest_;
   };
   
-  /**
-   * An NdndIdFetcher receives the Data packet with the publisher public key digest for the connected NDN hub.
-   * This class is a function object for the callbacks. It only holds a pointer to an Info object, so it is OK to copy the pointer.
-   */
-  class NdndIdFetcher {
-  public:
-    class Info;
-    NdndIdFetcher(ptr_lib::shared_ptr<NdndIdFetcher::Info> info)
-    : info_(info)
-    {      
-    }
-    
-    /**
-     * We received the ndnd ID.
-     * @param interest
-     * @param data
-     */
-    void 
-    operator()(const ptr_lib::shared_ptr<const Interest>& interest, const ptr_lib::shared_ptr<Data>& ndndIdData);
-
-    /**
-     * We timed out fetching the ndnd ID.
-     * @param interest
-     */
-    void 
-    operator()(const ptr_lib::shared_ptr<const Interest>& timedOutInterest);
-    
-    class Info {
-    public:
-      /**
-       * 
-       * @param node
-       * @param registeredPrefixId The PrefixEntry::getNextRegisteredPrefixId() which registerPrefix got so it could return it to the caller.
-       * @param prefix
-       * @param onInterest
-       * @param onRegisterFailed
-       * @param flags
-       * @param wireFormat
-       */
-      Info(Node *node, uint64_t registeredPrefixId, const Name& prefix, const OnInterest& onInterest, 
-           const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags, WireFormat& wireFormat)
-      : node_(*node), registeredPrefixId_(registeredPrefixId), prefix_(new Name(prefix)), onInterest_(onInterest), onRegisterFailed_(onRegisterFailed), 
-        flags_(flags), wireFormat_(wireFormat)
-      {      
-      }
-      
-      Node& node_;
-      uint64_t registeredPrefixId_;
-      ptr_lib::shared_ptr<const Name> prefix_;
-      const OnInterest onInterest_;
-      const OnRegisterFailed onRegisterFailed_;
-      ForwardingFlags flags_;
-      WireFormat& wireFormat_;
-    };
-    
-  private:
-    ptr_lib::shared_ptr<Info> info_;
-  };
+  typedef std::vector<ptr_lib::shared_ptr<PendingInterest> > PendingInterestTable;
+  typedef std::vector<ptr_lib::shared_ptr<RegisteredPrefix> > RegisteredPrefixTable;
   
   /**
    * Find the entry from the pit_ where the name conforms to the entry's interest selectors, and
@@ -303,7 +240,7 @@
    * @param name The name to find the interest for (from the incoming data packet).
    * @return The index in pit_ of the pit entry, or -1 if not found.
    */
-  int 
+  PendingInterestTable::iterator 
   getEntryIndexForExpressedInterest(const Name& name);
   
   /**
@@ -311,7 +248,7 @@
    * @param name The name to find the PrefixEntry for (from the incoming interest packet).
    * @return A pointer to the entry, or 0 if not found.
    */
-  RegisteredPrefix*
+  RegisteredPrefixTable::iterator
   getEntryForRegisteredPrefix(const Name& name);
 
   /**
@@ -326,15 +263,23 @@
   void 
   registerPrefixHelper
     (uint64_t registeredPrefixId, const ptr_lib::shared_ptr<const Name>& prefix, const OnInterest& onInterest, 
-     const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags, WireFormat& wireFormat);
+     const OnRegisterFailed& onRegisterFailed, const ForwardingFlags& flags);
+
+  void
+  checkPitExpire();
+  
+private:
+  boost::asio::io_service ioService_;
+  boost::asio::deadline_timer timer_;
   
   ptr_lib::shared_ptr<Transport> transport_;
-  std::vector<ptr_lib::shared_ptr<PendingInterest> > pendingInterestTable_;
-  std::vector<ptr_lib::shared_ptr<RegisteredPrefix> > registeredPrefixTable_;
+
+  PendingInterestTable pendingInterestTable_;
+  RegisteredPrefixTable registeredPrefixTable_;
   Interest ndndIdFetcherInterest_;
-  Blob ndndId_;
+  Buffer ndndId_;
 };
 
-}
+} // namespace ndn
 
 #endif
diff --git a/include/ndn-cpp/transport/transport.hpp b/include/ndn-cpp/transport/transport.hpp
index 80d41b2..8bfa355 100644
--- a/include/ndn-cpp/transport/transport.hpp
+++ b/include/ndn-cpp/transport/transport.hpp
@@ -8,58 +8,88 @@
 #ifndef NDN_TRANSPORT_HPP
 #define NDN_TRANSPORT_HPP
 
+#include <ndn-cpp/common.hpp>
+
 #include <vector>
+#include <boost/asio.hpp>
 
 namespace ndn {
 
-class ElementListener;
-
 class Transport {
 public:
+  typedef ptr_lib::function<void (const Block &wire)> ReceiveCallback;
+  
+  inline
+  Transport();
+  
+  inline virtual
+  ~Transport();
+
   /**
    * Connect according to the info in ConnectionInfo, and processEvents() will use elementListener.
    * @param connectionInfo A reference to an object of a subclass of ConnectionInfo.
-   * @param elementListener Not a shared_ptr because we assume that it will remain valid during the life of this object.
+   */
+  inline virtual void 
+  connect(boost::asio::io_service &io_service, const ReceiveCallback &receiveCallback);
+  
+  /**
+   * Close the connection.
    */
   virtual void 
-  connect(ElementListener& elementListener) = 0;
-  
+  close() = 0;
+
   /**
    * Set data to the host
    * @param data A pointer to the buffer of data to send.
    * @param dataLength The number of bytes in data.
    */
   virtual void 
-  send(const uint8_t *data, size_t dataLength) = 0;
-  
-  inline void 
-  send(const std::vector<uint8_t>& data)
-  {
-    send(&data[0], data.size());
-  }
-  
-  /**
-   * Process any data to receive.  For each element received, call elementListener.onReceivedElement.
-   * This is non-blocking and will return immediately if there is no data to receive.
-   * You should normally not call this directly since it is called by Face.processEvents.
-   * @throw This may throw an exception for reading data or in the callback for processing the data.  If you
-   * call this from an main event loop, you may want to catch and log/disregard all exceptions.
-   */
-  virtual void 
-  processEvents() = 0;
+  send(const Block &wire) = 0;
 
-  virtual bool 
-  getIsConnected() = 0;
+  inline bool 
+  isConnected();
+
+protected:
+  inline void
+  receive(const Block &wire);
   
-  /**
-   * Close the connection.  This base class implementation does nothing, but your derived class can override.
-   */
-  virtual void 
-  close();
-  
-  virtual ~Transport();
+protected:
+  boost::asio::io_service *ioService_;
+  bool isConnected_;
+  ReceiveCallback receiveCallback_;
 };
 
+inline
+Transport::Transport()
+  : ioService_(0)
+  , isConnected_(false)
+{
+}
+
+inline
+Transport::~Transport()
+{
+}
+
+inline void 
+Transport::connect(boost::asio::io_service &ioService, const ReceiveCallback &receiveCallback)
+{
+  ioService_ = &ioService;
+  receiveCallback_ = receiveCallback;
+}
+
+inline bool 
+Transport::isConnected()
+{
+  return isConnected_;
+}
+
+inline void
+Transport::receive(const Block &wire)
+{
+  receiveCallback_(wire);
+}
+
 }
 
 #endif
diff --git a/include/ndn-cpp/transport/unix-transport.hpp b/include/ndn-cpp/transport/unix-transport.hpp
index bb77bb4..1cc4758 100644
--- a/include/ndn-cpp/transport/unix-transport.hpp
+++ b/include/ndn-cpp/transport/unix-transport.hpp
@@ -13,49 +13,24 @@
 
 namespace ndn {
   
-class UnixTransport : public Transport {
+class UnixTransport : public Transport
+{
 public:
   UnixTransport(const std::string &unixSocket = "/tmp/.ndnd.sock");
   ~UnixTransport();
 
-  /**
-   * Connect according to the info in ConnectionInfo, and processEvents() will use elementListener.
-   * @param connectionInfo A reference to a TcpTransport::ConnectionInfo.
-   * @param elementListener Not a shared_ptr because we assume that it will remain valid during the life of this object.
-   */
+  // from Transport
   virtual void 
-  connect(ElementListener& elementListener);
+  connect(boost::asio::io_service &ioService, const ReceiveCallback &receiveCallback);
   
-  /**
-   * Set data to the host
-   * @param data A pointer to the buffer of data to send.
-   * @param dataLength The number of bytes in data.
-   */
-  virtual void 
-  send(const uint8_t *data, size_t dataLength);
-
-  /**
-   * Process any data to receive.  For each element received, call elementListener.onReceivedElement.
-   * This is non-blocking and will return immediately if there is no data to receive.
-   * You should normally not call this directly since it is called by Face.processEvents.
-   * @throw This may throw an exception for reading data or in the callback for processing the data.  If you
-   * call this from an main event loop, you may want to catch and log/disregard all exceptions.
-   */
-  virtual void 
-  processEvents();
-  
-  virtual bool 
-  getIsConnected();
-
-  /**
-   * Close the connection to the host.
-   */
   virtual void 
   close();
+
+  virtual void 
+  send(const Block &wire);
   
 private:
   std::string unixSocket_;
-  bool isConnected_;
 
   class Impl;
   std::auto_ptr<Impl> impl_;