dissect: improve dissect program
This commit improves ndn-dissect program as follows:
* Functions are organized into NdnDissect class.
* The class is placed into namespace ndn::dissect.
* The main function is moved to main.cpp.
* Indentation is provided by ndn::util::IndentedStream.
* Command line parsing uses Boost.Program_options.
* -h and -V command line options are supported.
refs #2848
Change-Id: Ib12584f455910128662ed3f59631d13db52a2cf8
diff --git a/tools/dissect/main.cpp b/tools/dissect/main.cpp
new file mode 100644
index 0000000..fa1a962
--- /dev/null
+++ b/tools/dissect/main.cpp
@@ -0,0 +1,114 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015, Regents of the University of California.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ndn-dissect.hpp"
+#include "core/version.hpp"
+
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/variables_map.hpp>
+#include <boost/program_options/parsers.hpp>
+
+namespace po = boost::program_options;
+
+namespace ndn {
+namespace dissect {
+
+void
+usage(std::ostream& os, const std::string& appName, const po::options_description& options)
+{
+ os << "Usage:\n"
+ << " " << appName << " [input-file] \n"
+ << "\n"
+ << options;
+}
+
+int
+main(int argc, char* argv[])
+{
+ po::options_description visibleOptions;
+ visibleOptions.add_options()
+ ("help,h", "Print help and exit.")
+ ("version,V", "Print version and exit.")
+ ;
+
+ std::string inputFileName;
+ po::options_description hiddenOptions;
+ hiddenOptions.add_options()
+ ("input-file", po::value<std::string>(&inputFileName));
+ ;
+ po::positional_options_description positionalArguments;
+ positionalArguments
+ .add("input-file", -1);
+
+ po::options_description allOptions;
+ allOptions
+ .add(visibleOptions)
+ .add(hiddenOptions)
+ ;
+
+ po::variables_map vm;
+ try {
+ po::store(po::command_line_parser(argc, argv)
+ .options(allOptions)
+ .positional(positionalArguments)
+ .run(),
+ vm);
+ po::notify(vm);
+ }
+ catch (po::error& e) {
+ std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
+ usage(std::cerr, argv[0], visibleOptions);
+ return 2;
+ }
+
+ if (vm.count("help") > 0) {
+ usage(std::cout, argv[0], visibleOptions);
+ return 0;
+ }
+
+ if (vm.count("version") > 0) {
+ std::cout << "ndn-dissect " << tools::VERSION << std::endl;
+ return 0;
+ }
+
+ std::ifstream inputFile;
+ std::istream* inputStream;
+
+ if (vm.count("input-file") > 0 && inputFileName != "-") {
+ inputFile.open(inputFileName);
+ inputStream = &inputFile;
+ }
+ else {
+ inputStream = &std::cin;
+ }
+
+ NdnDissect program;
+ program.dissect(std::cout, *inputStream);
+
+ return 0;
+}
+
+} // namespace dissect
+} // namespace ndn
+
+int
+main(int argc, char** argv)
+{
+ return ndn::dissect::main(argc, argv);
+}
diff --git a/tools/dissect/ndn-dissect.cpp b/tools/dissect/ndn-dissect.cpp
index c9d8ece..f37195e 100644
--- a/tools/dissect/ndn-dissect.cpp
+++ b/tools/dissect/ndn-dissect.cpp
@@ -1,5 +1,22 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
+ * Copyright (c) 2014-2015, Regents of the University of California.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
@@ -21,14 +38,16 @@
* @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
*/
-#include <ndn-cxx/face.hpp>
-#include <ndn-cxx/encoding/block.hpp>
+#include "ndn-dissect.hpp"
-#include <iomanip>
-#include <fstream>
+#include <algorithm>
#include <map>
+#include <ndn-cxx/name-component.hpp>
+#include <ndn-cxx/util/indented-stream.hpp>
+
namespace ndn {
+namespace dissect {
std::map<uint32_t, std::string> TLV_DICT = {
{tlv::Interest , "Interest"},
@@ -59,35 +78,33 @@
};
void
-printTypeInfo(uint32_t type)
+NdnDissect::printType(std::ostream& os, uint32_t type)
{
- std::cout << type << " (";
+ os << type << " (";
if (TLV_DICT.count(type) != 0) {
- std::cout << TLV_DICT[type];
+ os << TLV_DICT[type];
}
else if (type < tlv::AppPrivateBlock1) {
- std::cout << "RESERVED_1";
+ os << "RESERVED_1";
}
else if (tlv::AppPrivateBlock1 <= type && type < 253) {
- std::cout << "APP_TAG_1";
+ os << "APP_TAG_1";
}
else if (253 <= type && type < tlv::AppPrivateBlock2) {
- std::cout << "RESERVED_3";
+ os << "RESERVED_3";
}
else {
- std::cout << "APP_TAG_3";
+ os << "APP_TAG_3";
}
- std::cout << ")";
+ os << ")";
}
-
void
-BlockPrinter(const Block& block, const std::string& indent = "")
+NdnDissect::printBlock(std::ostream& os, const Block& block)
{
- std::cout << indent;
- printTypeInfo(block.type());
- std::cout << " (size: " << block.value_size() << ")";
+ this->printType(os, block.type());
+ os << " (size: " << block.value_size() << ")";
try {
// if (block.type() != tlv::Content && block.type() != tlv::SignatureValue)
@@ -99,88 +116,33 @@
// @todo: Figure how to deterministically figure out that value is not recursive TLV block
}
- if (block.elements().empty())
- {
- std::cout << " [[";
- name::Component(block.value(), block.value_size()).toUri(std::cout);
- std::cout<< "]]";
- }
- std::cout << std::endl;
+ if (block.elements().empty()) {
+ os << " [[";
+ name::Component(block.value(), block.value_size()).toUri(os);
+ os<< "]]";
+ }
+ os << std::endl;
- for (Block::element_const_iterator i = block.elements_begin();
- i != block.elements_end();
- ++i)
- {
- BlockPrinter(*i, indent+" ");
- }
+ util::IndentedStream os2(os, " ");
+ std::for_each(block.elements_begin(), block.elements_end(),
+ [this, &os2] (const Block& element) {
+ this->printBlock(os2, element);
+ });
}
void
-HexPrinter(const Block& block, const std::string& indent = "")
-{
- std::cout << indent;
- for (Buffer::const_iterator i = block.begin (); i != block.value_begin(); ++i)
- {
- std::cout << "0x";
- std::cout << std::noshowbase << std::hex << std::setw(2) <<
- std::setfill('0') << static_cast<int>(*i);
- std::cout << ", ";
- }
- std::cout << "\n";
-
- if (block.elements_size() == 0 && block.value_size() > 0)
- {
- std::cout << indent << " ";
- for (Buffer::const_iterator i = block.value_begin (); i != block.value_end(); ++i)
- {
- std::cout << "0x";
- std::cout << std::noshowbase << std::hex << std::setw(2) <<
- std::setfill('0') << static_cast<int>(*i);
- std::cout << ", ";
- }
- std::cout << "\n";
- }
- else
- {
- for (Block::element_const_iterator i = block.elements_begin();
- i != block.elements_end();
- ++i)
- {
- HexPrinter(*i, indent+" ");
- }
- }
-}
-
-void
-parseBlocksFromStream(std::istream& is)
+NdnDissect::dissect(std::ostream& os, std::istream& is)
{
while (is.peek() != std::char_traits<char>::eof()) {
try {
Block block = Block::fromStream(is);
- BlockPrinter(block, "");
- // HexPrinter(block, "");
+ this->printBlock(os, block);
}
catch (std::exception& e) {
std::cerr << "ERROR: " << e.what() << std::endl;
}
}
-
}
+} // namespace dissect
} // namespace ndn
-
-int main(int argc, const char *argv[])
-{
- if (argc == 1 ||
- (argc == 2 && std::string(argv[1]) == "-"))
- {
- ndn::parseBlocksFromStream(std::cin);
- }
- else
- {
- std::ifstream file(argv[1]);
- ndn::parseBlocksFromStream(file);
- }
-
- return 0;
-}
diff --git a/tools/dissect/ndn-dissect.hpp b/tools/dissect/ndn-dissect.hpp
new file mode 100644
index 0000000..a90b845
--- /dev/null
+++ b/tools/dissect/ndn-dissect.hpp
@@ -0,0 +1,41 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015, Regents of the University of California.
+ *
+ * This file is part of ndn-tools (Named Data Networking Essential Tools).
+ * See AUTHORS.md for complete list of ndn-tools authors and contributors.
+ *
+ * ndn-tools is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <ndn-cxx/encoding/block.hpp>
+#include <fstream>
+
+namespace ndn {
+namespace dissect {
+
+class NdnDissect : noncopyable
+{
+public:
+ void
+ dissect(std::ostream& os, std::istream& is);
+
+private:
+ void
+ printType(std::ostream& os, uint32_t type);
+
+ void
+ printBlock(std::ostream& os, const Block& block);
+};
+
+} // namespace dissect
+} // namespace ndn
diff --git a/tools/dissect/wscript b/tools/dissect/wscript
index 748a292..070ece2 100644
--- a/tools/dissect/wscript
+++ b/tools/dissect/wscript
@@ -2,9 +2,16 @@
top = '../..'
def build(bld):
- bld.program(
- features='cxx',
- target='../../bin/ndn-dissect',
- source='ndn-dissect.cpp',
+ bld(features='cxx',
+ name='dissect-objects',
+ source=bld.path.ant_glob('*.cpp', excl='main.cpp'),
+ includes='.',
+ export_includes='.',
use='core-objects',
)
+
+ bld(features='cxx cxxprogram',
+ target='../../bin/ndn-dissect',
+ source='main.cpp',
+ use='dissect-objects',
+ )