From 7c837be6511435a8415e05fffee501d5764d9e92 Mon Sep 17 00:00:00 2001 From: arvidn Date: Sun, 26 Aug 2018 22:15:05 +0200 Subject: [PATCH] make the print function for entry actually be json-like. when logging bencode entries, print it all on a single line. add test for entry print function --- include/libtorrent/entry.hpp | 3 +- src/bt_peer_connection.cpp | 4 +- src/entry.cpp | 96 +++++++++++++++++++----------------- test/test_bencoding.cpp | 81 ++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 49 deletions(-) diff --git a/include/libtorrent/entry.hpp b/include/libtorrent/entry.hpp index de09d9fbc..20bf88cda 100644 --- a/include/libtorrent/entry.hpp +++ b/include/libtorrent/entry.hpp @@ -256,6 +256,7 @@ namespace libtorrent // returns a pretty-printed string representation // of the bencoded structure, with JSON-style syntax std::string to_string() const; + std::string to_string(bool single_line) const; protected: @@ -265,7 +266,7 @@ namespace libtorrent private: - void to_string_impl(std::string& out, int indent) const; + void to_string_impl(std::string& out, int indent, bool single_line) const; #if (defined(_MSC_VER) && _MSC_VER < 1310) || TORRENT_COMPLETE_TYPES_REQUIRED // workaround for msvc-bug. diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index c29add0aa..fdf1900bc 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -1814,7 +1814,7 @@ namespace libtorrent #ifndef TORRENT_DISABLE_LOGGING peer_log(peer_log_alert::incoming_message, "EXTENDED_HANDSHAKE" - , "%s", print_entry(root).c_str()); + , "%s", print_entry(root, true).c_str()); #endif for (extension_list_t::iterator i = m_extensions.begin(); @@ -2355,7 +2355,7 @@ namespace libtorrent #ifndef TORRENT_DISABLE_LOGGING peer_log(peer_log_alert::outgoing_message, "EXTENDED_HANDSHAKE" - , "%s", handshake.to_string().c_str()); + , "%s", handshake.to_string(true).c_str()); #endif } #endif diff --git a/src/entry.cpp b/src/entry.cpp index c54bf305b..2e0991515 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -653,83 +653,87 @@ namespace libtorrent std::string entry::to_string() const { std::string ret; - to_string_impl(ret, 0); + to_string_impl(ret, 0, false); return ret; } - void entry::to_string_impl(std::string& out, int indent) const + std::string entry::to_string(bool single_line) const + { + std::string ret; + to_string_impl(ret, 0, single_line); + return ret; + } + +namespace { + bool is_binary(std::string const& str) + { + for (std::string::const_iterator i = str.begin(); i != str.end(); ++i) + { + if (!is_print(static_cast(*i))) + return true; + } + return false; + } + + void add_indent(std::string& out, int const indent) + { + out.resize(out.size() + indent, ' '); + } +} + + void entry::to_string_impl(std::string& out, int const indent + , bool const single_line) const { TORRENT_ASSERT(indent >= 0); - for (int i = 0; i < indent; ++i) out += " "; switch (m_type) { case int_t: out += libtorrent::to_string(integer()).elems; - out += "\n"; break; case string_t: { - bool binary_string = false; - for (std::string::const_iterator i = string().begin(); i != string().end(); ++i) - { - if (!is_print(static_cast(*i))) - { - binary_string = true; - break; - } - } - if (binary_string) - { - out += to_hex(string()); - out += "\n"; - } - else - { - out += string(); - out += "\n"; - } + out += "'"; + if (is_binary(string())) out += to_hex(string()); + else out += string(); + out += "'"; } break; case list_t: { - out += "list\n"; + out += single_line ? "[ " : "[\n"; + bool first = true; for (list_type::const_iterator i = list().begin(); i != list().end(); ++i) { - i->to_string_impl(out, indent+1); + if (!first) out += single_line ? ", " : ",\n"; + first = false; + if (!single_line) add_indent(out, indent+1); + i->to_string_impl(out, indent+1, single_line); } + out += " ]"; } break; case dictionary_t: { - out += "dictionary\n"; + out += single_line ? "{ " : "{\n"; + bool first = true; for (dictionary_type::const_iterator i = dict().begin(); i != dict().end(); ++i) { - bool binary_string = false; - for (std::string::const_iterator k = i->first.begin(); k != i->first.end(); ++k) - { - if (!is_print(static_cast(*k))) - { - binary_string = true; - break; - } - } - for (int j = 0; j < indent+1; ++j) out += " "; - out += "["; - if (binary_string) out += to_hex(i->first); + if (!first) out += single_line ? ", " : ",\n"; + first = false; + if (!single_line) add_indent(out, indent+1); + out += "'"; + if (is_binary(i->first)) out += to_hex(i->first); else out += i->first; - out += "]"; + out += "': "; - if (i->second.type() != entry::string_t - && i->second.type() != entry::int_t) - out += "\n"; - else out += " "; - i->second.to_string_impl(out, indent+2); + i->second.to_string_impl(out, indent+2, single_line); } + out += " }"; } break; case preformatted_t: - out += "\n"; + out += ""; break; case undefined_t: default: - out += "\n"; + out += ""; } } } diff --git a/test/test_bencoding.cpp b/test/test_bencoding.cpp index f94f953d0..c36321406 100644 --- a/test/test_bencoding.cpp +++ b/test/test_bencoding.cpp @@ -134,6 +134,87 @@ TORRENT_TEST(undefined_node2) TEST_EQUAL(encode(e), "d4:info0:e"); } +TORRENT_TEST(print_dict_single_line) +{ + entry e; + e["foo"] = "bar"; + e["bar"] = "foo"; + TEST_EQUAL(e.to_string(true), "{ 'bar': 'foo', 'foo': 'bar' }"); +} + +TORRENT_TEST(print_dict) +{ + entry e; + e["foo"] = "bar"; + e["bar"] = "foo"; + TEST_EQUAL(e.to_string(), "{\n 'bar': 'foo',\n 'foo': 'bar' }"); +} + +TORRENT_TEST(print_list_single_line) +{ + entry e; + e.list().push_back(entry("foo")); + e.list().push_back(entry("bar")); + TEST_EQUAL(e.to_string(true), "[ 'foo', 'bar' ]"); +} + + +TORRENT_TEST(print_list) +{ + entry e; + e.list().push_back(entry("foo")); + e.list().push_back(entry("bar")); + TEST_EQUAL(e.to_string(), "[\n 'foo',\n 'bar' ]"); +} + +TORRENT_TEST(print_int_single_line) +{ + entry e(1337); + TEST_EQUAL(e.to_string(true), "1337"); +} + +TORRENT_TEST(print_int) +{ + entry e(1337); + TEST_EQUAL(e.to_string(), "1337"); +} + +TORRENT_TEST(print_string_single_line) +{ + entry e("foobar"); + TEST_EQUAL(e.to_string(true), "'foobar'"); +} + +TORRENT_TEST(print_string) +{ + entry e("foobar"); + TEST_EQUAL(e.to_string(), "'foobar'"); +} + +TORRENT_TEST(print_deep_dict_single_line) +{ + entry e; + e["strings"].list().push_back(entry("foo")); + e["strings"].list().push_back(entry("bar")); + e["ints"].list().push_back(entry(1)); + e["ints"].list().push_back(entry(2)); + e["ints"].list().push_back(entry(3)); + e["a"] = "foobar"; + TEST_EQUAL(e.to_string(true), "{ 'a': 'foobar', 'ints': [ 1, 2, 3 ], 'strings': [ 'foo', 'bar' ] }"); +} + +TORRENT_TEST(print_deep_dict) +{ + entry e; + e["strings"].list().push_back(entry("foo")); + e["strings"].list().push_back(entry("bar")); + e["ints"].list().push_back(entry(1)); + e["ints"].list().push_back(entry(2)); + e["ints"].list().push_back(entry(3)); + e["a"] = "foobar"; + TEST_EQUAL(e.to_string(), "{\n 'a': 'foobar',\n 'ints': [\n 1,\n 2,\n 3 ],\n 'strings': [\n 'foo',\n 'bar' ] }"); +} + #ifndef TORRENT_NO_DEPRECATE TORRENT_TEST(lazy_entry) {