From 7ef5cf7f24ccc4cdb5218caf72666684ed303bee Mon Sep 17 00:00:00 2001 From: Davide Pesavento Date: Fri, 29 Jan 2021 00:20:24 -0500 Subject: [PATCH] dissect: use Unicode characters to draw the TLV tree on the terminal Change-Id: If92176528361cb57f5e5a0a31a9c501d7fff54e7 --- tools/dissect/main.cpp | 5 +- tools/dissect/ndn-dissect.cpp | 103 ++++++++++++++++++++++------------ tools/dissect/ndn-dissect.hpp | 22 ++++++-- 3 files changed, 86 insertions(+), 44 deletions(-) diff --git a/tools/dissect/main.cpp b/tools/dissect/main.cpp index a7d1e3e..b5f2a68 100644 --- a/tools/dissect/main.cpp +++ b/tools/dissect/main.cpp @@ -82,7 +82,6 @@ main(int argc, char* argv[]) std::ifstream inputFile; std::istream* inputStream = &std::cin; - if (vm.count("input-file") > 0 && inputFileName != "-") { inputFile.open(inputFileName); if (!inputFile) { @@ -92,8 +91,8 @@ main(int argc, char* argv[]) inputStream = &inputFile; } - NdnDissect program; - program.dissect(std::cout, *inputStream); + NdnDissect program(*inputStream, std::cout); + program.dissect(); return 0; } diff --git a/tools/dissect/ndn-dissect.cpp b/tools/dissect/ndn-dissect.cpp index 4971d03..cf012d8 100644 --- a/tools/dissect/ndn-dissect.cpp +++ b/tools/dissect/ndn-dissect.cpp @@ -23,16 +23,55 @@ #include "ndn-dissect.hpp" -#include #include -#include #include -#include +#include namespace ndn { namespace dissect { +NdnDissect::NdnDissect(std::istream& input, std::ostream& output) + : m_in(input) + , m_out(output) +{ +} + +void +NdnDissect::dissect() +{ + size_t offset = 0; + try { + while (m_in.peek() != std::istream::traits_type::eof()) { + auto block = Block::fromStream(m_in); + printBlock(block); + offset += block.size(); + } + } + catch (const std::exception& e) { + std::cerr << "ERROR: " << e.what() << " at offset " << offset << "\n"; + } +} + +// http://git.altlinux.org/people/legion/packages/kbd.git?p=kbd.git;a=blob;f=data/consolefonts/README.eurlatgr +static const char GLYPH_VERTICAL[] = "\u2502 "; // "│ " +static const char GLYPH_VERTICAL_AND_RIGHT[] = "\u251c\u2500"; // "├─" +static const char GLYPH_UP_AND_RIGHT[] = "\u2514\u2500"; // "└─" +static const char GLYPH_SPACE[] = " "; + +void +NdnDissect::printBranches() +{ + for (size_t i = 0; i < m_branches.size(); ++i) { + if (i == m_branches.size() - 1) { + m_out << (m_branches[i] ? GLYPH_VERTICAL_AND_RIGHT : GLYPH_UP_AND_RIGHT); + } + else { + m_out << (m_branches[i] ? GLYPH_VERTICAL : GLYPH_SPACE); + } + } +} + static const std::map TLV_DICT = { {tlv::Interest , "Interest"}, {tlv::Data , "Data"}, @@ -75,35 +114,36 @@ static const std::map TLV_DICT = { }; void -NdnDissect::printType(std::ostream& os, uint32_t type) +NdnDissect::printType(uint32_t type) { - os << type << " ("; + m_out << type << " ("; auto it = TLV_DICT.find(type); if (it != TLV_DICT.end()) { - os << it->second; + m_out << it->second; } else if (type < tlv::AppPrivateBlock1) { - os << "RESERVED_1"; + m_out << "RESERVED_1"; } else if (tlv::AppPrivateBlock1 <= type && type < 253) { - os << "APP_TAG_1"; + m_out << "APP_TAG_1"; } else if (253 <= type && type < tlv::AppPrivateBlock2) { - os << "RESERVED_3"; + m_out << "RESERVED_3"; } else { - os << "APP_TAG_3"; + m_out << "APP_TAG_3"; } - os << ")"; + m_out << ")"; } void -NdnDissect::printBlock(std::ostream& os, const Block& block) +NdnDissect::printBlock(const Block& block) { - printType(os, block.type()); - os << " (size: " << block.value_size() << ")"; + printBranches(); + printType(block.type()); + m_out << " (size: " << block.value_size() << ")"; try { // if (block.type() != tlv::Content && block.type() != tlv::SignatureValue) @@ -115,32 +155,23 @@ NdnDissect::printBlock(std::ostream& os, const Block& block) // @todo: Figure how to deterministically figure out that value is not recursive TLV block } - if (block.elements().empty()) { - os << " [["; - name::Component(block.value(), block.value_size()).toUri(os); - os << "]]"; + const auto& elements = block.elements(); + if (elements.empty()) { + m_out << " [["; + name::Component(block.value(), block.value_size()).toUri(m_out); + m_out << "]]"; } - os << "\n"; + m_out << "\n"; - util::IndentedStream os2(os, " "); - std::for_each(block.elements_begin(), block.elements_end(), - [this, &os2] (const Block& element) { printBlock(os2, element); }); -} - -void -NdnDissect::dissect(std::ostream& os, std::istream& is) -{ - size_t offset = 0; - try { - while (is.peek() != std::istream::traits_type::eof()) { - auto block = Block::fromStream(is); - printBlock(os, block); - offset += block.size(); + m_branches.push_back(true); + for (size_t i = 0; i < elements.size(); ++i) { + if (i == elements.size() - 1) { + // no more branches to draw at this level of the tree + m_branches.back() = false; } + printBlock(elements[i]); } - catch (const std::exception& e) { - std::cerr << "ERROR: " << e.what() << " at offset " << offset << "\n"; - } + m_branches.pop_back(); } } // namespace dissect diff --git a/tools/dissect/ndn-dissect.hpp b/tools/dissect/ndn-dissect.hpp index 062d3f0..29c5e6a 100644 --- a/tools/dissect/ndn-dissect.hpp +++ b/tools/dissect/ndn-dissect.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-2021, 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. @@ -30,15 +30,27 @@ namespace dissect { class NdnDissect : noncopyable { public: + NdnDissect(std::istream& input, std::ostream& output); + void - dissect(std::ostream& os, std::istream& is); + dissect(); private: void - printType(std::ostream& os, uint32_t type); + printBranches(); void - printBlock(std::ostream& os, const Block& block); + printType(uint32_t type); + + void + printBlock(const Block& block); + +private: + std::istream& m_in; + std::ostream& m_out; + + // m_branches[i] is true iff the i-th level of the tree has more branches after the current one + std::vector m_branches; }; } // namespace dissect