mgmt: fix ndns-add-rr-from-file indicating input format

Change-Id: I8959e783aeec3f440344a163c37fb433a1030c97
Refs: #2258
diff --git a/src/mgmt/management-tool.cpp b/src/mgmt/management-tool.cpp
index c6fc51e..9edd131 100644
--- a/src/mgmt/management-tool.cpp
+++ b/src/mgmt/management-tool.cpp
@@ -30,7 +30,6 @@
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/lexical_cast.hpp>
 
-#include <ndn-cxx/util/io.hpp>
 #include <ndn-cxx/util/regex.hpp>
 #include <ndn-cxx/encoding/oid.hpp>
 #include <ndn-cxx/security/cryptopp.hpp>
@@ -297,7 +296,8 @@
 ManagementTool::addRrSet(const Name& zoneName,
                          const std::string& inFile,
                          const time::seconds& ttl,
-                         const Name& inputDskCertName)
+                         const Name& inputDskCertName,
+                         const ndn::io::IoEncoding encoding)
 {
   //check precondition
   Zone zone(zoneName);
@@ -327,12 +327,12 @@
   //first load the data
   shared_ptr<Data> data;
   if (inFile == DEFAULT_IO)
-    data = ndn::io::load<ndn::Data>(std::cin);
+    data = ndn::io::load<ndn::Data>(std::cin, encoding);
   else
-    data = ndn::io::load<ndn::Data>(inFile);
+    data = ndn::io::load<ndn::Data>(inFile, encoding);
 
   if (data == nullptr) {
-    throw Error("input does not contain a valid Data packet (is it in base64 format?)");
+    throw Error("input does not contain a valid Data packet");
   }
 
   //determine whether the data is a self-signed certificate
diff --git a/src/mgmt/management-tool.hpp b/src/mgmt/management-tool.hpp
index 69fd355..5eabffe 100644
--- a/src/mgmt/management-tool.hpp
+++ b/src/mgmt/management-tool.hpp
@@ -31,6 +31,7 @@
 #include <ndn-cxx/common.hpp>
 #include <ndn-cxx/security/identity-certificate.hpp>
 #include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/util/io.hpp>
 
 namespace ndn {
 namespace ndns {
@@ -156,12 +157,14 @@
    *  @param dataPath the path to the supplied data
    *  @param ttl the ttl of the rrset
    *  @param dskName the DSK to signed the special case, default is the zone's DSK
+   *  @param encoding the encoding of the input file
     */
   void
   addRrSet(const Name& zoneName,
            const std::string& inFile = DEFAULT_IO,
            const time::seconds& ttl = DEFAULT_RR_TTL,
-           const Name& dskCertName = DEFAULT_CERT);
+           const Name& dskCertName = DEFAULT_CERT,
+           const ndn::io::IoEncoding encoding = ndn::io::BASE_64);
 
   /** @brief remove rrset from the NDNS local database
    *
@@ -178,7 +181,6 @@
    *  @param label rrset's label
    *  @param type rrset's type
    *  @param os the ostream to print information to
-   *  @param isPP indicate pretty print
    */
   void
   getRrSet(const Name& zoneName,
diff --git a/tests/unit/mgmt/management-tool.cpp b/tests/unit/mgmt/management-tool.cpp
index f5137e1..b6fb73c 100644
--- a/tests/unit/mgmt/management-tool.cpp
+++ b/tests/unit/mgmt/management-tool.cpp
@@ -702,6 +702,50 @@
   BOOST_CHECK_EQUAL(rrset.getVersion(), name::Component::fromVersion(version));
 }
 
+BOOST_FIXTURE_TEST_CASE(AddRrSet8, ManagementToolFixture)
+{
+  //check input with different formats
+  Name parentZoneName("/ndns-test");
+  Name zoneName = Name(parentZoneName).append("child-zone");
+  m_tool.createZone(zoneName, parentZoneName);
+
+  std::string output = TEST_CERTDIR.string() + "/a.cert";
+
+  // base64
+  Name dskName = m_keyChain.generateRsaKeyPair(zoneName, false);
+  shared_ptr<IdentityCertificate> dskCert = m_keyChain.selfSign(dskName);
+
+  ndn::io::save(*dskCert, output, ndn::io::BASE_64);
+  BOOST_CHECK_NO_THROW(
+    m_tool.addRrSet(zoneName, output, DEFAULT_CACHE_TTL, DEFAULT_CERT, ndn::io::BASE_64));
+
+  // raw
+  dskName = m_keyChain.generateRsaKeyPair(zoneName, false);
+  dskCert = m_keyChain.selfSign(dskName);
+
+  ndn::io::save(*dskCert, output, ndn::io::NO_ENCODING);
+  BOOST_CHECK_NO_THROW(
+    m_tool.addRrSet(zoneName, output, DEFAULT_CACHE_TTL, DEFAULT_CERT, ndn::io::NO_ENCODING));
+
+  // hex
+  dskName = m_keyChain.generateRsaKeyPair(zoneName, false);
+  dskCert = m_keyChain.selfSign(dskName);
+
+  ndn::io::save(*dskCert, output, ndn::io::HEX);
+  BOOST_CHECK_NO_THROW(
+    m_tool.addRrSet(zoneName, output, DEFAULT_CACHE_TTL, DEFAULT_CERT, ndn::io::HEX));
+
+  // incorrect encoding input
+  dskName = m_keyChain.generateRsaKeyPair(zoneName, false);
+  dskCert = m_keyChain.selfSign(dskName);
+
+  ndn::io::save(*dskCert, output, ndn::io::HEX);
+  BOOST_CHECK_THROW(
+    m_tool.addRrSet(zoneName, output, DEFAULT_CACHE_TTL, DEFAULT_CERT,
+                    static_cast<ndn::io::IoEncoding>(127)),
+    ndns::ManagementTool::Error);
+}
+
 BOOST_FIXTURE_TEST_CASE(ListAllZones, ManagementToolFixture)
 {
   m_tool.createZone(ROOT_ZONE, ROOT_ZONE, time::seconds(1), time::days(1), rootKsk, rootDsk);
diff --git a/tools/ndns-add-rr-from-file.cpp b/tools/ndns-add-rr-from-file.cpp
index 1753fd6..a08d26a 100644
--- a/tools/ndns-add-rr-from-file.cpp
+++ b/tools/ndns-add-rr-from-file.cpp
@@ -24,6 +24,8 @@
 #include <boost/filesystem.hpp>
 #include <string>
 
+#include <ndn-cxx/util/io.hpp>
+
 
 // @todo combine this command with ndns-add-rr
 int
@@ -39,6 +41,7 @@
   string dskStr;
   string db;
   string file = "-";
+  string encoding = "base64";
   try {
     namespace po = boost::program_options;
     po::variables_map vm;
@@ -56,6 +59,8 @@
       ("dsk,d", po::value<std::string>(&dskStr), "Set the name of DSK's certificate. "
         "Default: use default DSK and its default certificate")
       ("ttl,a", po::value<int>(&ttlInt), "Set ttl of the rrset. Default: 3600 seconds")
+      ("encoding,e", po::value<string>(&encoding),
+        "Set encoding format of input. Default: base64")
       ;
 
     options.add(config);
@@ -82,8 +87,8 @@
     po::notify(vm);
 
     if (vm.count("help")) {
-      std::cout << "Usage: ndns-add-rr-from-file [-b db] zone [-f file] [-d dskCert] [-a ttl]"
-        " [file]" << std::endl
+      std::cout << "Usage: ndns-add-rr-from-file [-b db] zone [-f file] [-d dskCert] [-a ttl] "
+          "[-e raw|base64|hex] [file]" << std::endl
                 << std::endl;
       std::cout << options << std::endl;
       return 0;
@@ -108,9 +113,25 @@
     else
       ttl = time::seconds(ttlInt);
 
+    ndn::io::IoEncoding ioEncoding;
+    if (encoding == "raw") {
+      ioEncoding = ndn::io::NO_ENCODING;
+    }
+    else if (encoding == "hex") {
+      ioEncoding = ndn::io::HEX;
+    }
+    else if (encoding == "base64") {
+      ioEncoding = ndn::io::BASE_64;
+    }
+    else {
+      std::cerr << "Error: not supported encoding format '" << encoding
+                << "' (valid options are: raw, hex, and base64)" << std::endl;
+      return 1;
+    }
+
     ndn::KeyChain keyChain;
     ndn::ndns::ManagementTool tool(db, keyChain);
-    tool.addRrSet(zoneName, file, ttl, dskName);
+    tool.addRrSet(zoneName, file, ttl, dskName, ioEncoding);
   }
   catch (const std::exception& ex) {
     std::cerr << "Error: " << ex.what() << std::endl;