Use ndn::mgmt::Dispatcher for repo commands

refs #4129

Change-Id: Idb7826fc76b6660ce76d69e7e88a9e922c55a2e1
diff --git a/src/repo-command-parameter.hpp b/src/repo-command-parameter.hpp
index 97208b6..1ad212f 100644
--- a/src/repo-command-parameter.hpp
+++ b/src/repo-command-parameter.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017, Regents of the University of California.
+ * Copyright (c) 2014-2018, Regents of the University of California.
  *
  * This file is part of NDN repo-ng (Next generation of NDN repository).
  * See AUTHORS.md for complete list of repo-ng authors and contributors.
@@ -26,6 +26,7 @@
 #include <ndn-cxx/encoding/block-helpers.hpp>
 #include <ndn-cxx/name.hpp>
 #include <ndn-cxx/selectors.hpp>
+#include <ndn-cxx/mgmt/control-parameters.hpp>
 
 namespace repo {
 
@@ -37,12 +38,33 @@
 using ndn::EncodingBuffer;
 using namespace ndn::time;
 
+enum RepoParameterField {
+  REPO_PARAMETER_NAME,
+  REPO_PARAMETER_START_BLOCK_ID,
+  REPO_PARAMETER_END_BLOCK_ID,
+  REPO_PARAMETER_PROCESS_ID,
+  REPO_PARAMETER_MAX_INTEREST_NUM,
+  REPO_PARAMETER_WATCH_TIME_OUT,
+  REPO_PARAMETER_INTEREST_LIFETIME,
+  REPO_PARAMETER_UBOUND
+};
+
+const std::string REPO_PARAMETER_FIELD[REPO_PARAMETER_UBOUND] = {
+  "Name",
+  "StartBlockId",
+  "EndBlockId",
+  "ProcessId",
+  "MaxInterestNum",
+  "WatchTimeout",
+  "InterestLifetime"
+};
+
 /**
 * @brief Class defining abstraction of parameter of command for NDN Repo Protocol
 * @sa link https://redmine.named-data.net/projects/repo-ng/wiki/Repo_Protocol_Specification#RepoCommandParameter
 **/
 
-class RepoCommandParameter
+class RepoCommandParameter : public ndn::mgmt::ControlParameters
 {
 public:
   class Error : public ndn::tlv::Error
@@ -56,18 +78,13 @@
   };
 
   RepoCommandParameter()
-    : m_hasName(false)
-    , m_hasStartBlockId(false)
-    , m_hasEndBlockId(false)
-    , m_hasProcessId(false)
-    , m_hasMaxInterestNum(false)
-    , m_hasWatchTimeout(false)
-    , m_hasInterestLifetime(false)
+    : m_hasFields(REPO_PARAMETER_UBOUND)
   {
   }
 
   explicit
   RepoCommandParameter(const Block& block)
+    : m_hasFields(REPO_PARAMETER_UBOUND)
   {
     wireDecode(block);
   }
@@ -79,18 +96,12 @@
   }
 
   RepoCommandParameter&
-  setName(const Name& name)
-  {
-    m_name = name;
-    m_hasName = true;
-    m_wire.reset();
-    return *this;
-  }
+  setName(const Name& name);
 
   bool
   hasName() const
   {
-    return m_hasName;
+    return m_hasFields[REPO_PARAMETER_NAME];
   }
 
   const Selectors&
@@ -100,12 +111,7 @@
   }
 
   RepoCommandParameter&
-  setSelectors(const Selectors& selectors)
-  {
-    m_selectors = selectors;
-    m_wire.reset();
-    return *this;
-  }
+  setSelectors(const Selectors& selectors);
 
   bool
   hasSelectors() const
@@ -121,18 +127,12 @@
   }
 
   RepoCommandParameter&
-  setStartBlockId(uint64_t startBlockId)
-  {
-    m_startBlockId  = startBlockId;
-    m_hasStartBlockId = true;
-    m_wire.reset();
-    return *this;
-  }
+  setStartBlockId(uint64_t startBlockId);
 
   bool
   hasStartBlockId() const
   {
-    return m_hasStartBlockId;
+    return m_hasFields[REPO_PARAMETER_START_BLOCK_ID];
   }
 
   uint64_t
@@ -143,18 +143,12 @@
   }
 
   RepoCommandParameter&
-  setEndBlockId(uint64_t endBlockId)
-  {
-    m_endBlockId  = endBlockId;
-    m_hasEndBlockId = true;
-    m_wire.reset();
-    return *this;
-  }
+  setEndBlockId(uint64_t endBlockId);
 
   bool
   hasEndBlockId() const
   {
-    return m_hasEndBlockId;
+    return m_hasFields[REPO_PARAMETER_END_BLOCK_ID];
   }
 
   uint64_t
@@ -165,18 +159,12 @@
   }
 
   RepoCommandParameter&
-  setProcessId(uint64_t processId)
-  {
-    m_processId = processId;
-    m_hasProcessId = true;
-    m_wire.reset();
-    return *this;
-  }
+  setProcessId(uint64_t processId);
 
   bool
   hasProcessId() const
   {
-    return m_hasProcessId;
+    return m_hasFields[REPO_PARAMETER_PROCESS_ID];
   }
 
   uint64_t
@@ -187,18 +175,12 @@
   }
 
   RepoCommandParameter&
-  setMaxInterestNum(uint64_t maxInterestNum)
-  {
-    m_maxInterestNum = maxInterestNum;
-    m_hasMaxInterestNum = true;
-    m_wire.reset();
-    return *this;
-  }
+  setMaxInterestNum(uint64_t maxInterestNum);
 
   bool
   hasMaxInterestNum() const
   {
-    return m_hasMaxInterestNum;
+    return m_hasFields[REPO_PARAMETER_MAX_INTEREST_NUM];
   }
 
   milliseconds
@@ -209,18 +191,12 @@
   }
 
   RepoCommandParameter&
-  setWatchTimeout(milliseconds watchTimeout)
-  {
-    m_watchTimeout = watchTimeout;
-    m_hasWatchTimeout = true;
-    m_wire.reset();
-    return *this;
-  }
+  setWatchTimeout(milliseconds watchTimeout);
 
   bool
   hasWatchTimeout() const
   {
-    return m_hasWatchTimeout;
+    return m_hasFields[REPO_PARAMETER_WATCH_TIME_OUT];
   }
 
   milliseconds
@@ -231,32 +207,31 @@
   }
 
   RepoCommandParameter&
-  setInterestLifetime(milliseconds interestLifetime)
-  {
-    m_interestLifetime = interestLifetime;
-    m_hasInterestLifetime = true;
-    m_wire.reset();
-    return *this;
-  }
+  setInterestLifetime(milliseconds interestLifetime);
 
   bool
   hasInterestLifetime() const
   {
-    return m_hasInterestLifetime;
+    return m_hasFields[REPO_PARAMETER_INTEREST_LIFETIME];
+  }
+
+  const std::vector<bool>&
+  getPresentFields() const {
+    return m_hasFields;
   }
 
   template<ndn::encoding::Tag T>
   size_t
   wireEncode(EncodingImpl<T>& block) const;
 
-  const Block&
+  Block
   wireEncode() const;
 
   void
   wireDecode(const Block& wire);
 
 private:
-
+  std::vector<bool> m_hasFields;
   Name m_name;
   Selectors m_selectors;
   uint64_t m_startBlockId;
@@ -266,217 +241,10 @@
   milliseconds m_watchTimeout;
   milliseconds m_interestLifetime;
 
-  bool m_hasName;
-  bool m_hasStartBlockId;
-  bool m_hasEndBlockId;
-  bool m_hasProcessId;
-  bool m_hasMaxInterestNum;
-  bool m_hasWatchTimeout;
-  bool m_hasInterestLifetime;
-
   mutable Block m_wire;
 };
 
-template<ndn::encoding::Tag T>
-inline size_t
-RepoCommandParameter::wireEncode(EncodingImpl<T>& encoder) const
-{
-  size_t totalLength = 0;
-  size_t variableLength = 0;
-
-  if (m_hasProcessId) {
-    variableLength = encoder.prependNonNegativeInteger(m_processId);
-    totalLength += variableLength;
-    totalLength += encoder.prependVarNumber(variableLength);
-    totalLength += encoder.prependVarNumber(tlv::ProcessId);
-  }
-
-  if (m_hasEndBlockId) {
-    variableLength = encoder.prependNonNegativeInteger(m_endBlockId);
-    totalLength += variableLength;
-    totalLength += encoder.prependVarNumber(variableLength);
-    totalLength += encoder.prependVarNumber(tlv::EndBlockId);
-  }
-
-  if (m_hasStartBlockId) {
-    variableLength = encoder.prependNonNegativeInteger(m_startBlockId);
-    totalLength += variableLength;
-    totalLength += encoder.prependVarNumber(variableLength);
-    totalLength += encoder.prependVarNumber(tlv::StartBlockId);
-  }
-
-  if (m_hasMaxInterestNum) {
-    variableLength = encoder.prependNonNegativeInteger(m_maxInterestNum);
-    totalLength += variableLength;
-    totalLength += encoder.prependVarNumber(variableLength);
-    totalLength += encoder.prependVarNumber(tlv::MaxInterestNum);
-  }
-
-  if (m_hasWatchTimeout) {
-    variableLength = encoder.prependNonNegativeInteger(m_watchTimeout.count());
-    totalLength += variableLength;
-    totalLength += encoder.prependVarNumber(variableLength);
-    totalLength += encoder.prependVarNumber(tlv::WatchTimeout);
-  }
-
-  if (m_hasInterestLifetime) {
-    variableLength = encoder.prependNonNegativeInteger(m_interestLifetime.count());
-    totalLength += variableLength;
-    totalLength += encoder.prependVarNumber(variableLength);
-    totalLength += encoder.prependVarNumber(tlv::InterestLifetime);
-  }
-
-  if (!getSelectors().empty()) {
-    totalLength += getSelectors().wireEncode(encoder);
-  }
-
-  if (m_hasName) {
-    totalLength += getName().wireEncode(encoder);
-  }
-
-  totalLength += encoder.prependVarNumber(totalLength);
-  totalLength += encoder.prependVarNumber(tlv::RepoCommandParameter);
-  return totalLength;
-}
-
-inline const Block&
-RepoCommandParameter::wireEncode() const
-{
-  if (m_wire.hasWire())
-    return m_wire;
-
-  EncodingEstimator estimator;
-  size_t estimatedSize = wireEncode(estimator);
-
-  EncodingBuffer buffer(estimatedSize, 0);
-  wireEncode(buffer);
-
-  m_wire = buffer.block();
-  return m_wire;
-}
-
-inline void
-RepoCommandParameter::wireDecode(const Block& wire)
-{
-  m_hasName = false;
-  m_hasStartBlockId = false;
-  m_hasEndBlockId = false;
-  m_hasProcessId = false;
-  m_hasMaxInterestNum = false;
-  m_hasWatchTimeout = false;
-  m_hasInterestLifetime = false;
-
-  m_wire = wire;
-
-  m_wire.parse();
-
-  if (m_wire.type() != tlv::RepoCommandParameter)
-    BOOST_THROW_EXCEPTION(Error("Requested decoding of RepoCommandParameter, but Block is of different type"));
-
-  // Name
-  Block::element_const_iterator val = m_wire.find(tlv::Name);
-  if (val != m_wire.elements_end())
-  {
-    m_hasName = true;
-    m_name.wireDecode(m_wire.get(tlv::Name));
-  }
-
-  // Selectors
-  val = m_wire.find(tlv::Selectors);
-  if (val != m_wire.elements_end())
-  {
-    m_selectors.wireDecode(*val);
-  }
-  else
-    m_selectors = Selectors();
-
-  // StartBlockId
-  val = m_wire.find(tlv::StartBlockId);
-  if (val != m_wire.elements_end())
-  {
-    m_hasStartBlockId = true;
-    m_startBlockId = readNonNegativeInteger(*val);
-  }
-
-  // EndBlockId
-  val = m_wire.find(tlv::EndBlockId);
-  if (val != m_wire.elements_end())
-  {
-    m_hasEndBlockId = true;
-    m_endBlockId = readNonNegativeInteger(*val);
-  }
-
-  // ProcessId
-  val = m_wire.find(tlv::ProcessId);
-  if (val != m_wire.elements_end())
-  {
-    m_hasProcessId = true;
-    m_processId = readNonNegativeInteger(*val);
-  }
-
-  // MaxInterestNum
-  val = m_wire.find(tlv::MaxInterestNum);
-  if (val != m_wire.elements_end())
-  {
-    m_hasMaxInterestNum = true;
-    m_maxInterestNum = readNonNegativeInteger(*val);
-  }
-
-  // WatchTimeout
-  val = m_wire.find(tlv::WatchTimeout);
-  if (val != m_wire.elements_end())
-  {
-    m_hasWatchTimeout = true;
-    m_watchTimeout = milliseconds(readNonNegativeInteger(*val));
-  }
-
-  // InterestLiftTime
-  val = m_wire.find(tlv::InterestLifetime);
-  if (val != m_wire.elements_end())
-  {
-    m_hasInterestLifetime = true;
-    m_interestLifetime = milliseconds(readNonNegativeInteger(*val));
-  }
-
-
-}
-
-inline std::ostream&
-operator<<(std::ostream& os, const RepoCommandParameter& repoCommandParameter)
-{
-  os << "RepoCommandParameter(";
-
-  // Name
-  if (repoCommandParameter.hasName()) {
-    os << " Name: " << repoCommandParameter.getName();
-  }
-  if (repoCommandParameter.hasStartBlockId()) {
-  // StartBlockId
-    os << " StartBlockId: " << repoCommandParameter.getStartBlockId();
-  }
-  // EndBlockId
-  if (repoCommandParameter.hasEndBlockId()) {
-    os << " EndBlockId: " << repoCommandParameter.getEndBlockId();
-  }
-  // ProcessId
-  if (repoCommandParameter.hasProcessId()) {
-    os << " ProcessId: " << repoCommandParameter.getProcessId();
-  }
-  // MaxInterestNum
-  if (repoCommandParameter.hasMaxInterestNum()) {
-    os << " MaxInterestNum: " << repoCommandParameter.getMaxInterestNum();
-  }
-  // WatchTimeout
-  if (repoCommandParameter.hasProcessId()) {
-    os << " WatchTimeout: " << repoCommandParameter.getWatchTimeout();
-  }
-  // InterestLifetime
-  if (repoCommandParameter.hasProcessId()) {
-    os << " InterestLifetime: " << repoCommandParameter.getInterestLifetime();
-  }
-  os << " )";
-  return os;
-}
+NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(RepoCommandParameter);
 
 } // namespace repo