API change for closure. Return ParsedContentObject, not just content

Fixed bug in test/test-sync-core.cc: there should have been two independent schedulers
diff --git a/ccnx/ccnx-closure.cpp b/ccnx/ccnx-closure.cpp
index a96bbbe..312af6d 100644
--- a/ccnx/ccnx-closure.cpp
+++ b/ccnx/ccnx-closure.cpp
@@ -46,7 +46,7 @@
 
 
 void
-Closure::runDataCallback(const Name &name, const Bytes &content)
+Closure::runDataCallback(const Name &name, PcoPtr content)
 {
   if (!m_dataCallback.empty ())
     {
diff --git a/ccnx/ccnx-closure.h b/ccnx/ccnx-closure.h
index 39fbc16..343d8be 100644
--- a/ccnx/ccnx-closure.h
+++ b/ccnx/ccnx-closure.h
@@ -27,10 +27,13 @@
 
 namespace Ccnx {
 
+class ParsedContentObject;
+typedef boost::shared_ptr<ParsedContentObject> PcoPtr;
+
 class Closure
 {
 public:
-  typedef boost::function<void (const Name &, const Bytes &)> DataCallback;
+  typedef boost::function<void (const Name &, PcoPtr pco)> DataCallback;
 
   typedef enum
   {
@@ -44,7 +47,7 @@
   virtual ~Closure();
 
   virtual void
-  runDataCallback(const Name &name, const Bytes &content);
+  runDataCallback(const Name &name, Ccnx::PcoPtr pco);
 
   virtual TimeoutCallbackReturnValue
   runTimeoutCallback(const Name &interest);
diff --git a/ccnx/ccnx-pco.cpp b/ccnx/ccnx-pco.cpp
index 8c2fd3f..2c4e351 100644
--- a/ccnx/ccnx-pco.cpp
+++ b/ccnx/ccnx-pco.cpp
@@ -1,3 +1,24 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
 #include "ccnx-pco.h"
 
 namespace Ccnx {
@@ -5,13 +26,14 @@
 void
 ParsedContentObject::init(const unsigned char *data, size_t len)
 {
+  readRaw(m_bytes, data, len);
+
   m_comps = ccn_indexbuf_create();
-  int res = ccn_parse_ContentObject(data, len, &m_pco, m_comps);
+  int res = ccn_parse_ContentObject(head (m_bytes), len, &m_pco, m_comps);
   if (res < 0)
   {
     boost::throw_exception(MisformedContentObjectException());
   }
-  readRaw(m_bytes, data, len);
 }
 
 ParsedContentObject::ParsedContentObject(const unsigned char *data, size_t len)
@@ -43,13 +65,13 @@
 {
   const unsigned char *content;
   size_t len;
-  Bytes bytes;
   int res = ccn_content_get_value(head(m_bytes), m_pco.offset[CCN_PCO_E], &m_pco, &content, &len);
   if (res < 0)
   {
     boost::throw_exception(MisformedContentObjectException());
   }
 
+  Bytes bytes;
   readRaw(bytes, content, len);
   return bytes;
 }
diff --git a/ccnx/ccnx-pco.h b/ccnx/ccnx-pco.h
index 0c52c7a..cecc763 100644
--- a/ccnx/ccnx-pco.h
+++ b/ccnx/ccnx-pco.h
@@ -1,3 +1,24 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
 #ifndef CCNX_CONTENT_OBJECT_H
 #define CCNX_CONTENT_OBJECT_H
 
@@ -5,16 +26,15 @@
 #include "ccnx-common.h"
 #include "ccnx-name.h"
 
-using namespace std;
-
 namespace Ccnx {
 
-struct MisformedContentObjectException : virtual boost::exception, virtual exception { };
+struct MisformedContentObjectException : virtual boost::exception, virtual std::exception { };
 
 class ParsedContentObject
 {
 public:
   ParsedContentObject(const unsigned char *data, size_t len);
+  ParsedContentObject(const unsigned char *data, const ccn_parsed_ContentObject &pco);
   ParsedContentObject(const Bytes &bytes);
   ParsedContentObject(const ParsedContentObject &other);
   virtual ~ParsedContentObject();
@@ -24,7 +44,7 @@
 
   BytesPtr
   contentPtr() const;
-  
+
   Name
   name() const;
 
diff --git a/ccnx/ccnx-tunnel.cpp b/ccnx/ccnx-tunnel.cpp
deleted file mode 100644
index def125a..0000000
--- a/ccnx/ccnx-tunnel.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#include "ccnx-tunnel.h"
-#include "ccnx-pco.h"
-
-namespace Ccnx
-{
-
-CcnxTunnel::CcnxTunnel()
-  : CcnxWrapper()
-  , m_localPrefix("/")
-{
-  refreshLocalPrefix();
-}
-
-CcnxTunnel::~CcnxTunnel()
-{
-}
-
-void
-CcnxTunnel::refreshLocalPrefix()
-{
-  Name newPrefix = getLocalPrefix();
-  if (!newPrefix.toString().empty() && m_localPrefix != newPrefix)
-  {
-    CcnxWrapper::clearInterestFilter(m_localPrefix);
-    CcnxWrapper::setInterestFilter(newPrefix, bind(&CcnxTunnel::handleTunneledInterest, this, _1));
-    m_localPrefix = newPrefix;
-  }
-}
-
-int
-CcnxTunnel::sendInterest (const Name &interest, const Closure &closure, const Selectors &selectors)
-{
-  Name tunneledInterest = queryRoutableName(interest);
-
-  CcnxWrapper::sendInterest(tunneledInterest,
-                            TunnelClosure(closure, *this, interest),
-                            selectors);
-
-  return 0;
-}
-
-void
-CcnxTunnel::handleTunneledData(const Name &name, const Bytes &tunneledData, const Closure::DataCallback &originalDataCallback)
-{
-  ParsedContentObject pco(tunneledData);
-  originalDataCallback(pco.name(), pco.content());
-}
-
-int
-CcnxTunnel::publishData(const Name &name, const unsigned char *buf, size_t len, int freshness)
-{
-  Bytes content = createContentObject(name, buf, len, freshness);
-  storeContentObject(name, content);
-
-  return publishContentObject(name, content, freshness);
-}
-
-int
-CcnxTunnel::publishContentObject(const Name &name, const Bytes &contentObject, int freshness)
-{
-  Name tunneledName = m_localPrefix + name;
-  Bytes tunneledCo = createContentObject(tunneledName, head(contentObject), contentObject.size(), freshness);
-  return putToCcnd(tunneledCo);
-}
-
-void
-CcnxTunnel::handleTunneledInterest(const Name &tunneledInterest)
-{
-  // The interest must have m_localPrefix as a prefix (component-wise), otherwise ccnd would not deliver it to us
-  Name interest = tunneledInterest.getPartialName(m_localPrefix.size());
-
-  ReadLock lock(m_ritLock);
-
-  // This is linear scan, but should be acceptable under the assumption that the caller wouldn't be listening to a lot prefixes (as of now, most app listen to one or two prefixes)
-  for (RitIter it = m_rit.begin(); it != m_rit.end(); it++)
-  {
-    // evoke callback for any prefix that is the prefix of the interest
-    if (isPrefix(it->first, interest))
-    {
-      (it->second)(interest);
-    }
-  }
-}
-
-bool
-CcnxTunnel::isPrefix(const Name &prefix, const Name &name)
-{
-  if (prefix.size() > name.size())
-  {
-    return false;
-  }
-
-  int size = prefix.size();
-  for (int i = 0; i < size; i++)
-  {
-    if (prefix.getCompAsString(i) != name.getCompAsString(i))
-    {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-int
-CcnxTunnel::setInterestFilter(const Name &prefix, const InterestCallback &interestCallback)
-{
-  WriteLock lock(m_ritLock);
-  // make sure copy constructor for boost::function works properly
-  m_rit.insert(make_pair(prefix, interestCallback));
-  return 0;
-}
-
-void
-CcnxTunnel::clearInterestFilter(const Name &prefix)
-{
-  WriteLock lock(m_ritLock);
-  // remove all
-  m_rit.erase(prefix);
-}
-
-TunnelClosure::TunnelClosure(const DataCallback &dataCallback, CcnxTunnel &tunnel,
-                             const Name &originalInterest, const TimeoutCallback &timeoutCallback)
-  : Closure(dataCallback, timeoutCallback)
-  , m_tunnel(tunnel)
-  , m_originalInterest(originalInterest)
-{
-}
-
-TunnelClosure::TunnelClosure(const Closure &closure, CcnxTunnel &tunnel, const Name &originalInterest)
-  : Closure(closure)
-  , m_tunnel(tunnel)
-{
-}
-
-Closure *
-TunnelClosure::dup() const
-{
-  return new TunnelClosure (*this);
-}
-
-void
-TunnelClosure::runDataCallback(const Name &name, const Bytes &content)
-{
-  m_tunnel.handleTunneledData(name, content, m_dataCallback);
-}
-
-Closure::TimeoutCallbackReturnValue
-TunnelClosure::runTimeoutCallback(const Name &interest)
-{
-  return Closure::runTimeoutCallback(m_originalInterest);
-}
-
-} // Ccnx
diff --git a/ccnx/ccnx-tunnel.h b/ccnx/ccnx-tunnel.h
deleted file mode 100644
index 01dbf5e..0000000
--- a/ccnx/ccnx-tunnel.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013 University of California, Los Angeles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
- *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
- */
-
-#ifndef CCNX_TUNNEL_H
-#define CCNX_TUNNEL_H
-
-#include "ccnx-wrapper.h"
-
-#define _OVERRIDE
-#ifdef __GNUC__
-#if __GNUC_MAJOR >= 4 && __GNUC_MINOR__ >= 7
-  #undef _OVERRIDE
-  #define _OVERRIDE override
-#endif // __GNUC__ version
-#endif // __GNUC__
-
-// Eventually, Sync::CcnxWrapper should be moved to this namespace.
-// It has nothing to do with Sync.
-namespace Ccnx
-{
-
-class CcnxTunnel : public CcnxWrapper
-{
-public:
-  typedef std::multimap<Name, InterestCallback> RegisteredInterestTable;
-  typedef std::multimap<Name, InterestCallback>::iterator RitIter;
-
-
-  CcnxTunnel();
-  virtual ~CcnxTunnel();
-
-  // name is topology-independent
-  virtual int
-  publishData(const Name &name, const unsigned char *buf, size_t len, int freshness) _OVERRIDE;
-
-  int
-  publishContentObject(const Name &name, const Bytes &contentObject, int freshness);
-
-  virtual int
-  sendInterest (const Name &interest, const Closure &closure, const Selectors &selectors = Selectors());
-
-
-  // prefix is topology-independent
-  virtual int
-  setInterestFilter(const Name &prefix, const InterestCallback &interestCallback) _OVERRIDE;
-
-  // prefix is topology-independent
-  // this clears all entries with key equal to prefix
-  virtual void
-  clearInterestFilter(const Name &prefix) _OVERRIDE;
-
-  // subclass should provide translation service from topology-independent name
-  // to routable name
-  virtual Name
-  queryRoutableName(const Name &name) = 0;
-
-  // subclass should implement the function to store ContentObject with topoloy-independent
-  // name to the permanent storage; default does nothing
-  virtual void
-  storeContentObject(const Name &name, const Bytes &content) {}
-
-  // should be called  when connect to a different network
-  void
-  refreshLocalPrefix();
-
-  static bool
-  isPrefix(const Name &prefix, const Name &name);
-
-  void
-  handleTunneledInterest(const Name &tunneldInterest);
-
-  void
-  handleTunneledData(const Name &name, const Bytes &tunneledData, const Closure::DataCallback &originalDataCallback);
-
-private:
-  CcnxTunnel(const CcnxTunnel &other) {}
-
-protected:
-  // need a way to update local prefix, perhaps using macports trick, but eventually we need something more portable
-  Name m_localPrefix;
-  RegisteredInterestTable m_rit;
-  Lock m_ritLock;
-};
-
-class TunnelClosure : public Closure
-{
-public:
-  TunnelClosure(const DataCallback &dataCallback, CcnxTunnel &tunnel,
-                const Name &originalInterest, const TimeoutCallback &timeoutCallback = TimeoutCallback());
-
-  TunnelClosure(const Closure &closure, CcnxTunnel &tunnel, const Name &originalInterest);
-
-  virtual void
-  runDataCallback(const Name &name, const Bytes &content) _OVERRIDE;
-
-  virtual TimeoutCallbackReturnValue
-  runTimeoutCallback(const Name &interest) _OVERRIDE;
-
-  virtual Closure *
-  dup() const;
-
-private:
-  CcnxTunnel &m_tunnel;
-  Name m_originalInterest;
-};
-
-};
-
-#endif
diff --git a/ccnx/ccnx-wrapper.cpp b/ccnx/ccnx-wrapper.cpp
index fcaf224..7f2e567 100644
--- a/ccnx/ccnx-wrapper.cpp
+++ b/ccnx/ccnx-wrapper.cpp
@@ -1,3 +1,24 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
 #include "ccnx-wrapper.h"
 extern "C" {
 #include <ccn/fetch.h>
@@ -6,6 +27,7 @@
 #include <boost/throw_exception.hpp>
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/random.hpp>
+#include <boost/make_shared.hpp>
 #include <sstream>
 
 typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info_str;
@@ -265,21 +287,23 @@
       return CCN_UPCALL_RESULT_OK;
     }
 
-  const unsigned char *pcontent;
-  size_t len;
-  if (ccn_content_get_value(info->content_ccnb, info->pco->offset[CCN_PCO_E], info->pco, &pcontent, &len) < 0)
-  {
-    // BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("decode ContentObject failed"));
-  }
+  PcoPtr pco = make_shared<ParsedContentObject> (info->content_ccnb, info->pco->offset[CCN_PCO_E]);
 
-  Name name(info->content_ccnb, info->content_comps);
+  // const unsigned char *pcontent;
+  // size_t len;
+  // if (ccn_content_get_value(info->content_ccnb, info->pco->offset[CCN_PCO_E], info->pco, &pcontent, &len) < 0)
+  // {
+  //   // BOOST_THROW_EXCEPTION(CcnxOperationException() << errmsg_info_str("decode ContentObject failed"));
+  // }
 
-  Bytes content;
-  // copy content and do processing on the copy
-  // otherwise the pointed memory may have been changed during the processing
-  readRaw(content, pcontent, len);
+  // Name name(info->content_ccnb, info->content_comps);
 
-  cp->runDataCallback(name, content);
+  // Bytes content;
+  // // copy content and do processing on the copy
+  // // otherwise the pointed memory may have been changed during the processing
+  // readRaw(content, pcontent, len);
+
+  cp->runDataCallback (pco->name (), pco);
 
   return CCN_UPCALL_RESULT_OK;
 }
diff --git a/ccnx/ccnx-wrapper.h b/ccnx/ccnx-wrapper.h
index 938b890..cfd030b 100644
--- a/ccnx/ccnx-wrapper.h
+++ b/ccnx/ccnx-wrapper.h
@@ -1,3 +1,24 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
 #ifndef CCNX_WRAPPER_H
 #define CCNX_WRAPPER_H
 
@@ -9,12 +30,11 @@
 #include "ccnx-name.h"
 #include "ccnx-selectors.h"
 #include "ccnx-closure.h"
-
-using namespace std;
+#include "ccnx-pco.h"
 
 namespace Ccnx {
 
-struct CcnxOperationException : virtual boost::exception, virtual exception { };
+struct CcnxOperationException : virtual boost::exception, virtual std::exception { };
 
 class CcnxWrapper
 {