catchunks: pass versioned name to onDiscoverySuccess signal

refs: #4556
Change-Id: I599bafcf70647bd806236f87f24d7a22f73a3505
diff --git a/tools/chunks/catchunks/consumer.cpp b/tools/chunks/catchunks/consumer.cpp
index 0106629..e7f751e 100644
--- a/tools/chunks/catchunks/consumer.cpp
+++ b/tools/chunks/catchunks/consumer.cpp
@@ -45,8 +45,8 @@
   m_nextToPrint = 0;
   m_bufferedData.clear();
 
-  m_discover->onDiscoverySuccess.connect([this] (const Data& data) {
-    m_pipeline->run(data,
+  m_discover->onDiscoverySuccess.connect([this] (const Name& versionedName) {
+    m_pipeline->run(versionedName,
       [this] (const Data& data) { handleData(data); },
       [] (const std::string& msg) { NDN_THROW(std::runtime_error(msg)); });
   });
diff --git a/tools/chunks/catchunks/discover-version-fixed.cpp b/tools/chunks/catchunks/discover-version-fixed.cpp
index 5d434f0..c122d2f 100644
--- a/tools/chunks/catchunks/discover-version-fixed.cpp
+++ b/tools/chunks/catchunks/discover-version-fixed.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2017, Regents of the University of California,
+ * Copyright (c) 2016-2019, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -52,16 +52,18 @@
   if (isVerbose)
     std::cerr << "Data: " << data << std::endl;
 
-  size_t segmentIndex = interest.getName().size();
-  if (data.getName()[segmentIndex].isSegment()) {
+  // data name must end with a segment number, preceded by a version number
+  if (data.getName().size() >= 2 &&
+      data.getName()[-1].isSegment() &&
+      data.getName()[-2].isVersion()) {
     if (isVerbose)
-      std::cerr << "Found data with the requested version: " << m_prefix[-1] << std::endl;
+      std::cerr << "Found data with the requested version: " << data.getName()[-2] << std::endl;
 
-    this->emitSignal(onDiscoverySuccess, data);
+    this->emitSignal(onDiscoverySuccess, data.getName().getPrefix(-1));
   }
   else {
     // data isn't a valid segment, add to the exclude list
-    m_strayExcludes.excludeOne(data.getName()[segmentIndex]);
+    m_strayExcludes.excludeOne(data.getName()[-1]);
     Interest newInterest(interest);
     newInterest.refreshNonce();
     newInterest.setExclude(m_strayExcludes);
diff --git a/tools/chunks/catchunks/discover-version-iterative.cpp b/tools/chunks/catchunks/discover-version-iterative.cpp
index fddf08e..adeb48e 100644
--- a/tools/chunks/catchunks/discover-version-iterative.cpp
+++ b/tools/chunks/catchunks/discover-version-iterative.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2017, Regents of the University of California,
+ * Copyright (c) 2016-2019, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -109,12 +109,28 @@
       std::cerr << "Found data with the latest version: " << m_latestVersion << std::endl;
 
     // we discovered at least one version. assume what we have is the latest.
-    this->emitSignal(onDiscoverySuccess, *m_latestVersionData);
+    this->emitSignal(onDiscoverySuccess, Name(interest.getName()).appendVersion(m_latestVersion));
   }
   else {
     DiscoverVersion::handleTimeout(interest, reason);
   }
 }
 
+void
+DiscoverVersionIterative::handleNack(const Interest& interest, const std::string& reason)
+{
+  if (m_foundVersion) {
+    // a version has been found and after a nack this version can be used as the latest.
+    if (isVerbose)
+      std::cerr << "Found data with the latest version: " << m_latestVersion << std::endl;
+
+    // we discovered at least one version. assume what we have is the latest.
+    this->emitSignal(onDiscoverySuccess, Name(interest.getName()).appendVersion(m_latestVersion));
+  }
+  else {
+    DiscoverVersion::handleNack(interest, reason);
+  }
+}
+
 } // namespace chunks
 } // namespace ndn
diff --git a/tools/chunks/catchunks/discover-version-iterative.hpp b/tools/chunks/catchunks/discover-version-iterative.hpp
index e76ff17..8880a6d 100644
--- a/tools/chunks/catchunks/discover-version-iterative.hpp
+++ b/tools/chunks/catchunks/discover-version-iterative.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2017, Regents of the University of California,
+ * Copyright (c) 2016-2019, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -95,6 +95,9 @@
   void
   handleTimeout(const Interest& interest, const std::string& reason) final;
 
+  void
+  handleNack(const Interest& interest, const std::string& reason) final;
+
 private:
   uint64_t m_latestVersion;
   shared_ptr<const Data> m_latestVersionData;
diff --git a/tools/chunks/catchunks/discover-version.cpp b/tools/chunks/catchunks/discover-version.cpp
index 78b7c41..3a4309c 100644
--- a/tools/chunks/catchunks/discover-version.cpp
+++ b/tools/chunks/catchunks/discover-version.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2017, Regents of the University of California,
+ * Copyright (c) 2016-2019, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -50,12 +50,6 @@
 }
 
 void
-DiscoverVersion::handleData(const Interest& interest, const Data& data)
-{
-  onDiscoverySuccess(data);
-}
-
-void
 DiscoverVersion::handleNack(const Interest& interest, const std::string& reason)
 {
   onDiscoveryFailure(reason);
diff --git a/tools/chunks/catchunks/discover-version.hpp b/tools/chunks/catchunks/discover-version.hpp
index 464b28e..d29f94a 100644
--- a/tools/chunks/catchunks/discover-version.hpp
+++ b/tools/chunks/catchunks/discover-version.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2017, Regents of the University of California,
+ * Copyright (c) 2016-2019, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -46,9 +46,9 @@
 {
 public: // signals
   /**
-   * @brief Signal emited when the first segment of a specific version is found.
+   * @brief Signal emitted when the versioned name of Data is found.
    */
-  signal::Signal<DiscoverVersion, const Data&> onDiscoverySuccess;
+  signal::Signal<DiscoverVersion, Name> onDiscoverySuccess;
 
   /**
    * @brief Signal emitted when a failure occurs.
@@ -78,7 +78,7 @@
   expressInterest(const Interest& interest, int maxRetriesNack, int maxRetriesTimeout);
 
   virtual void
-  handleData(const Interest& interest, const Data& data);
+  handleData(const Interest& interest, const Data& data) = 0;
 
   virtual void
   handleNack(const Interest& interest, const std::string& reason);
diff --git a/tools/chunks/catchunks/pipeline-interests.cpp b/tools/chunks/catchunks/pipeline-interests.cpp
index 2318378..a6c7c21 100644
--- a/tools/chunks/catchunks/pipeline-interests.cpp
+++ b/tools/chunks/catchunks/pipeline-interests.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2018, Regents of the University of California,
+ * Copyright (c) 2016-2019, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -40,7 +40,6 @@
   , m_nReceived(0)
   , m_receivedSize(0)
   , m_nextSegmentNo(0)
-  , m_excludedSegmentNo(0)
   , m_isStopping(false)
 {
 }
@@ -48,20 +47,13 @@
 PipelineInterests::~PipelineInterests() = default;
 
 void
-PipelineInterests::run(const Data& data, DataCallback dataCb, FailureCallback failureCb)
+PipelineInterests::run(const Name& versionedName, DataCallback dataCb, FailureCallback failureCb)
 {
+  BOOST_ASSERT(!versionedName.empty() && versionedName[-1].isVersion());
   BOOST_ASSERT(dataCb != nullptr);
+  m_prefix = versionedName;
   m_onData = std::move(dataCb);
   m_onFailure = std::move(failureCb);
-  m_prefix = data.getName().getPrefix(-1);
-  m_excludedSegmentNo = getSegmentFromPacket(data);
-
-  if (data.getFinalBlock()) {
-    m_lastSegmentNo = data.getFinalBlock()->toSegment();
-    m_hasFinalBlockId = true;
-  }
-
-  onData(data);
 
   // record the start time of the pipeline
   m_startTime = time::steady_clock::now();
@@ -82,17 +74,14 @@
 bool
 PipelineInterests::allSegmentsReceived() const
 {
-  BOOST_ASSERT(m_nReceived > 0);
-  return m_hasFinalBlockId && static_cast<uint64_t>(m_nReceived - 1) >= m_lastSegmentNo;
+  return m_nReceived > 0 &&
+         m_hasFinalBlockId &&
+         static_cast<uint64_t>(m_nReceived - 1) >= m_lastSegmentNo;
 }
 
 uint64_t
 PipelineInterests::getNextSegmentNo()
 {
-  // skip the excluded segment
-  if (m_nextSegmentNo == m_excludedSegmentNo)
-    m_nextSegmentNo++;
-
   return m_nextSegmentNo++;
 }
 
diff --git a/tools/chunks/catchunks/pipeline-interests.hpp b/tools/chunks/catchunks/pipeline-interests.hpp
index 20fec04..fc17392 100644
--- a/tools/chunks/catchunks/pipeline-interests.hpp
+++ b/tools/chunks/catchunks/pipeline-interests.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2018, Regents of the University of California,
+ * Copyright (c) 2016-2019, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -67,12 +67,12 @@
   /**
    * @brief start fetching all the segments of the specified prefix
    *
-   * @param data a segment of the segmented Data to fetch; the Data name must end with a segment number
+   * @param versionedName the name of the segmented Data ending with a version number
    * @param onData callback for every segment correctly received, must not be empty
    * @param onFailure callback if an error occurs, may be empty
    */
   void
-  run(const Data& data, DataCallback onData, FailureCallback onFailure);
+  run(const Name& versionedName, DataCallback onData, FailureCallback onFailure);
 
   /**
    * @brief stop all fetch operations
@@ -163,7 +163,6 @@
   DataCallback m_onData;
   FailureCallback m_onFailure;
   uint64_t m_nextSegmentNo;
-  uint64_t m_excludedSegmentNo;
   time::steady_clock::TimePoint m_startTime;
   bool m_isStopping;
 };