blob: c9d8ece72ba8e798913ff4dc95eabd28aace59d3 [file] [log] [blame]
Junxiao Shie5adbfd2015-06-18 14:42:06 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2014 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 *
21 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
22 */
23
24#include <ndn-cxx/face.hpp>
25#include <ndn-cxx/encoding/block.hpp>
26
27#include <iomanip>
28#include <fstream>
29#include <map>
30
31namespace ndn {
32
33std::map<uint32_t, std::string> TLV_DICT = {
34 {tlv::Interest , "Interest"},
35 {tlv::Data , "Data"},
36 {tlv::Name , "Name"},
37 {tlv::NameComponent , "NameComponent"},
38 {tlv::ImplicitSha256DigestComponent, "ImplicitSha256DigestComponent"},
39 {tlv::Selectors , "Selectors"},
40 {tlv::Nonce , "Nonce"},
41 {tlv::InterestLifetime , "InterestLifetime"},
42 {tlv::MinSuffixComponents , "MinSuffixComponents"},
43 {tlv::MaxSuffixComponents , "MaxSuffixComponents"},
44 {tlv::PublisherPublicKeyLocator , "PublisherPublicKeyLocator"},
45 {tlv::Exclude , "Exclude"},
46 {tlv::ChildSelector , "ChildSelector"},
47 {tlv::MustBeFresh , "MustBeFresh"},
48 {tlv::Any , "Any"},
49 {tlv::MetaInfo , "MetaInfo"},
50 {tlv::Content , "Content"},
51 {tlv::SignatureInfo , "SignatureInfo"},
52 {tlv::SignatureValue , "SignatureValue"},
53 {tlv::ContentType , "ContentType"},
54 {tlv::FreshnessPeriod , "FreshnessPeriod"},
55 {tlv::FinalBlockId , "FinalBlockId"},
56 {tlv::SignatureType , "SignatureType"},
57 {tlv::KeyLocator , "KeyLocator"},
58 {tlv::KeyDigest , "KeyDigest"},
59};
60
61void
62printTypeInfo(uint32_t type)
63{
64 std::cout << type << " (";
65
66 if (TLV_DICT.count(type) != 0) {
67 std::cout << TLV_DICT[type];
68 }
69 else if (type < tlv::AppPrivateBlock1) {
70 std::cout << "RESERVED_1";
71 }
72 else if (tlv::AppPrivateBlock1 <= type && type < 253) {
73 std::cout << "APP_TAG_1";
74 }
75 else if (253 <= type && type < tlv::AppPrivateBlock2) {
76 std::cout << "RESERVED_3";
77 }
78 else {
79 std::cout << "APP_TAG_3";
80 }
81 std::cout << ")";
82}
83
84
85void
86BlockPrinter(const Block& block, const std::string& indent = "")
87{
88 std::cout << indent;
89 printTypeInfo(block.type());
90 std::cout << " (size: " << block.value_size() << ")";
91
92 try {
93 // if (block.type() != tlv::Content && block.type() != tlv::SignatureValue)
94 block.parse();
95 }
96 catch (tlv::Error& e) {
97 // pass (e.g., leaf block reached)
98
99 // @todo: Figure how to deterministically figure out that value is not recursive TLV block
100 }
101
102 if (block.elements().empty())
103 {
104 std::cout << " [[";
105 name::Component(block.value(), block.value_size()).toUri(std::cout);
106 std::cout<< "]]";
107 }
108 std::cout << std::endl;
109
110 for (Block::element_const_iterator i = block.elements_begin();
111 i != block.elements_end();
112 ++i)
113 {
114 BlockPrinter(*i, indent+" ");
115 }
116}
117
118void
119HexPrinter(const Block& block, const std::string& indent = "")
120{
121 std::cout << indent;
122 for (Buffer::const_iterator i = block.begin (); i != block.value_begin(); ++i)
123 {
124 std::cout << "0x";
125 std::cout << std::noshowbase << std::hex << std::setw(2) <<
126 std::setfill('0') << static_cast<int>(*i);
127 std::cout << ", ";
128 }
129 std::cout << "\n";
130
131 if (block.elements_size() == 0 && block.value_size() > 0)
132 {
133 std::cout << indent << " ";
134 for (Buffer::const_iterator i = block.value_begin (); i != block.value_end(); ++i)
135 {
136 std::cout << "0x";
137 std::cout << std::noshowbase << std::hex << std::setw(2) <<
138 std::setfill('0') << static_cast<int>(*i);
139 std::cout << ", ";
140 }
141 std::cout << "\n";
142 }
143 else
144 {
145 for (Block::element_const_iterator i = block.elements_begin();
146 i != block.elements_end();
147 ++i)
148 {
149 HexPrinter(*i, indent+" ");
150 }
151 }
152}
153
154void
155parseBlocksFromStream(std::istream& is)
156{
157 while (is.peek() != std::char_traits<char>::eof()) {
158 try {
159 Block block = Block::fromStream(is);
160 BlockPrinter(block, "");
161 // HexPrinter(block, "");
162 }
163 catch (std::exception& e) {
164 std::cerr << "ERROR: " << e.what() << std::endl;
165 }
166 }
167
168}
169
170} // namespace ndn
171
172int main(int argc, const char *argv[])
173{
174 if (argc == 1 ||
175 (argc == 2 && std::string(argv[1]) == "-"))
176 {
177 ndn::parseBlocksFromStream(std::cin);
178 }
179 else
180 {
181 std::ifstream file(argv[1]);
182 ndn::parseBlocksFromStream(file);
183 }
184
185 return 0;
186}