interest: add appendParameterDigestToName
refs: #4658

Change-Id: I0329b7733ab6b887e445074cbd19478f6677a2ef
diff --git a/ndn-cxx/interest.cpp b/ndn-cxx/interest.cpp
index 0cbc4ae..e4b3636 100644
--- a/ndn-cxx/interest.cpp
+++ b/ndn-cxx/interest.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -22,6 +22,7 @@
 #include "ndn-cxx/interest.hpp"
 #include "ndn-cxx/data.hpp"
 #include "ndn-cxx/util/random.hpp"
+#include "util/sha256.hpp"
 
 #include <boost/scope_exit.hpp>
 
@@ -622,6 +623,42 @@
   return *this;
 }
 
+Interest&
+Interest::appendParameterDigestToName()
+{
+  if (!hasParameters()) {
+    return *this;
+  }
+
+  if (!m_parameters.hasWire()) {
+    m_parameters.encode();
+  }
+  m_name.append(name::Component::fromParametersSha256Digest(
+    std::move(util::Sha256::computeDigest(m_parameters.wire(), m_parameters.size()))));
+  return *this;
+}
+
+Interest&
+Interest::removeParameterDigestFromName()
+{
+  Name newname;
+  for (auto it = m_name.begin(); it != m_name.end(); ++ it) {
+    if (!it->isParametersSha256Digest()) {
+      newname.append(*it);
+    }
+  }
+  m_name = newname;
+  return *this;
+}
+
+Interest&
+Interest::refreshParameterDigestInName()
+{
+  removeParameterDigestFromName();
+  appendParameterDigestToName();
+  return *this;
+}
+
 // ---- operators ----
 
 bool
diff --git a/ndn-cxx/interest.hpp b/ndn-cxx/interest.hpp
index ad271d0..1701b32 100644
--- a/ndn-cxx/interest.hpp
+++ b/ndn-cxx/interest.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -332,6 +332,17 @@
   Interest&
   unsetParameters();
 
+public:
+  /** @brief Refresh the digest for parameters in Name
+   *
+   *  If the block has parameters, add InterestParametersSha256DigestComponent
+   *  to Name. Remove the old component if necessary.
+   *  If the block doesn't have parameters, remove the old component.
+   *  @return a reference to this Interest
+   */
+  Interest&
+  refreshParameterDigestInName();
+
 public: // Selectors (deprecated)
   /** @brief Check if Interest has any selector present.
    */
@@ -465,6 +476,25 @@
   void
   decode03();
 
+private:
+  /** @brief Add the digest for parameters to Name
+   *
+   *  If the block has parameters, add InterestParametersSha256DigestComponent
+   *  to Name.
+   *  If the block doesn't have parameters, do nothing.
+   *  Call this funcion twice will append a redundant component.
+   *  @return a reference to this Interest
+   */
+  Interest&
+  appendParameterDigestToName();
+
+  /** @brief Remove the digest for parameters from Name
+   *
+   *  @return a reference to this Interest
+   */
+  Interest&
+  removeParameterDigestFromName();
+
 #ifdef NDN_CXX_HAVE_TESTS
 public:
   /** @brief If true, not setting CanBePrefix results in an error in wireEncode().
diff --git a/tests/unit/interest.t.cpp b/tests/unit/interest.t.cpp
index ef646bb..cf60ab9 100644
--- a/tests/unit/interest.t.cpp
+++ b/tests/unit/interest.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -585,6 +585,37 @@
   BOOST_CHECK_EQUAL(i.getParameters(), "23038001C1"_block);
 }
 
+BOOST_AUTO_TEST_CASE(AppendParametersSha256Digest)
+{
+  Name name("/local/ndn/prefix");
+  Interest i(name);
+
+  BOOST_CHECK(!i.hasParameters());
+  BOOST_CHECK_EQUAL(i.getName().toUri(), "/local/ndn/prefix");
+
+  i.setParameters("2301C0"_block);
+  i.refreshParameterDigestInName();
+  BOOST_CHECK(i.hasParameters());
+  BOOST_CHECK_EQUAL(i.getName().size(), name.size() + 1);
+  BOOST_CHECK_EQUAL_COLLECTIONS(i.getName().begin(), i.getName().end() - 1,
+                                name.begin(), name.end());
+  BOOST_CHECK(i.getName().get(-1).isParametersSha256Digest());
+
+  BOOST_CHECK_EQUAL(i.getName().toUri(),
+    "/local/ndn/prefix/"
+    "params-sha256=a16cc669b4c9ef6801e1569488513f9523ffb28a39e53aa6e11add8d00a413fc");
+
+  i.setParameters("8001C1"_block);
+  i.refreshParameterDigestInName();
+  BOOST_CHECK_EQUAL(i.getName().toUri(),
+    "/local/ndn/prefix/"
+    "params-sha256=f85d18efea7ab78d6b9b50b2cf017cfafb720fc94cb9ae4c493f61175a7786e6");
+
+  i.unsetParameters();
+  i.refreshParameterDigestInName();
+  BOOST_CHECK_EQUAL(i.getName().toUri(), "/local/ndn/prefix");
+}
+
 // ---- operators ----
 
 BOOST_AUTO_TEST_CASE(Equality)