management: StatusDataset client

refs #3329

Change-Id: Icf755ba7ed1fd36f6ea09af97cb77f70757f84c7
diff --git a/src/management/nfd-controller.hpp b/src/management/nfd-controller.hpp
index 4fbfa3e..7ebc5eb 100644
--- a/src/management/nfd-controller.hpp
+++ b/src/management/nfd-controller.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -23,9 +23,11 @@
 #define NDN_MANAGEMENT_NFD_CONTROLLER_HPP
 
 #include "nfd-control-command.hpp"
+#include "nfd-status-dataset.hpp"
+#include "nfd-command-options.hpp"
 #include "../face.hpp"
 #include "../security/key-chain.hpp"
-#include "nfd-command-options.hpp"
+#include "../security/validator-null.hpp"
 
 namespace ndn {
 namespace nfd {
@@ -48,7 +50,7 @@
 
   /** \brief a callback on command failure
    */
-  typedef function<void(uint32_t/*code*/,const std::string&/*reason*/)> CommandFailCallback;
+  typedef function<void(uint32_t code, const std::string& reason)> CommandFailCallback;
 
   /** \brief construct a Controller that uses face for transport,
    *         and uses the passed KeyChain to sign commands
@@ -68,6 +70,29 @@
     this->startCommand(command, parameters, onSuccess, onFailure, options);
   }
 
+  /** \brief start dataset fetching
+   */
+  template<typename Dataset>
+  typename std::enable_if<std::is_default_constructible<Dataset>::value>::type
+  fetch(const std::function<void(typename Dataset::ResultType)>& onSuccess,
+        const CommandFailCallback& onFailure,
+        const CommandOptions& options = CommandOptions())
+  {
+    this->fetchDataset(make_shared<Dataset>(), onSuccess, onFailure, options);
+  }
+
+  /** \brief start dataset fetching
+   */
+  template<typename Dataset, typename ParamType = typename Dataset::ParamType>
+  void
+  fetch(const ParamType& param,
+        const std::function<void(typename Dataset::ResultType)>& onSuccess,
+        const CommandFailCallback& onFailure,
+        const CommandOptions& options = CommandOptions())
+  {
+    this->fetchDataset(make_shared<Dataset>(param), onSuccess, onFailure, options);
+  }
+
 private:
   void
   startCommand(const shared_ptr<ControlCommand>& command,
@@ -82,6 +107,30 @@
                          const CommandSucceedCallback& onSuccess,
                          const CommandFailCallback& onFailure);
 
+  template<typename Dataset>
+  void
+  fetchDataset(shared_ptr<Dataset> dataset,
+               const std::function<void(typename Dataset::ResultType)>& onSuccess,
+               const CommandFailCallback& onFailure,
+               const CommandOptions& options);
+
+  void
+  fetchDataset(const Name& prefix,
+               const std::function<void(const ConstBufferPtr&)>& processResponse,
+               const CommandFailCallback& onFailure,
+               const CommandOptions& options);
+
+  template<typename Dataset>
+  void
+  processDatasetResponse(shared_ptr<Dataset> dataset,
+                         const std::function<void(typename Dataset::ResultType)>& onSuccess,
+                         const CommandFailCallback& onFailure,
+                         ConstBufferPtr payload);
+
+  void
+  processDatasetFetchError(const CommandFailCallback& onFailure, uint32_t code, std::string msg);
+
+
 public:
   /** \brief error code for timeout
    */
@@ -102,8 +151,44 @@
 protected:
   Face& m_face;
   KeyChain& m_keyChain;
+  Validator& m_validator;
+
+private:
+  static ValidatorNull s_validatorNull;
 };
 
+template<typename Dataset>
+inline void
+Controller::fetchDataset(shared_ptr<Dataset> dataset,
+                         const std::function<void(typename Dataset::ResultType)>& onSuccess,
+                         const CommandFailCallback& onFailure,
+                         const CommandOptions& options)
+{
+  Name prefix = dataset->getDatasetPrefix(options.getPrefix());
+  this->fetchDataset(prefix,
+                     bind(&Controller::processDatasetResponse<Dataset>, this, dataset, onSuccess, onFailure, _1),
+                     onFailure,
+                     options);
+}
+
+template<typename Dataset>
+inline void
+Controller::processDatasetResponse(shared_ptr<Dataset> dataset,
+                                   const std::function<void(typename Dataset::ResultType)>& onSuccess,
+                                   const CommandFailCallback& onFailure,
+                                   ConstBufferPtr payload)
+{
+  typename Dataset::ResultType result;
+  try {
+    result = dataset->parseResult(payload);
+  }
+  catch (const tlv::Error& ex) {
+    onFailure(ERROR_SERVER, ex.what());
+    return;
+  }
+  onSuccess(result);
+}
+
 } // namespace nfd
 } // namespace ndn