diff --git a/include/libtorrent/error_code.hpp b/include/libtorrent/error_code.hpp index dd5f14aa9..dc816afea 100644 --- a/include/libtorrent/error_code.hpp +++ b/include/libtorrent/error_code.hpp @@ -416,7 +416,7 @@ namespace libtorrent // invalid action field in udp tracker response invalid_tracker_action, - +#ifndef TORRENT_NO_DEPRECATE // expected string in bencoded string expected_string = 190, // expected colon in bencoded string @@ -429,6 +429,7 @@ namespace libtorrent depth_exceeded, // bencoded item count limit exceeded limit_exceeded, +#endif // the number of error codes error_code_max @@ -498,14 +499,6 @@ namespace libtorrent #else - struct TORRENT_EXPORT libtorrent_error_category : boost::system::error_category - { - virtual const char* name() const BOOST_SYSTEM_NOEXCEPT; - virtual std::string message(int ev) const BOOST_SYSTEM_NOEXCEPT; - virtual boost::system::error_condition default_error_condition(int ev) const BOOST_SYSTEM_NOEXCEPT - { return boost::system::error_condition(ev, *this); } - }; - struct TORRENT_EXPORT http_error_category : boost::system::error_category { virtual const char* name() const BOOST_SYSTEM_NOEXCEPT; diff --git a/include/libtorrent/lazy_entry.hpp b/include/libtorrent/lazy_entry.hpp index 9ae20c09b..d11a7c381 100644 --- a/include/libtorrent/lazy_entry.hpp +++ b/include/libtorrent/lazy_entry.hpp @@ -367,8 +367,41 @@ namespace libtorrent TORRENT_EXTRA_EXPORT std::string print_entry(lazy_entry const& e , bool single_line = false, int indent = 0); -} + TORRENT_EXPORT boost::system::error_category& get_bdecode_category(); + + namespace bdecode_errors + { + // libtorrent uses boost.system's ``error_code`` class to represent errors. libtorrent has + // its own error category get_bdecode_category() whith the error codes defined by error_code_enum. + enum error_code_enum + { + // Not an error + no_error = 0, + // expected string in bencoded string + expected_string, + // expected colon in bencoded string + expected_colon, + // unexpected end of file in bencoded string + unexpected_eof, + // expected value (list, dict, int or string) in bencoded string + expected_value, + // bencoded recursion depth limit exceeded + depth_exceeded, + // bencoded item count limit exceeded + limit_exceeded, + + // the number of error codes + error_code_max + }; + + // hidden + inline boost::system::error_code make_error_code(error_code_enum e) + { + return boost::system::error_code(e, get_bdecode_category()); + } + } +} #endif diff --git a/src/error_code.cpp b/src/error_code.cpp index f6dba63f0..546c4b7e3 100644 --- a/src/error_code.cpp +++ b/src/error_code.cpp @@ -40,6 +40,14 @@ namespace libtorrent { #if BOOST_VERSION >= 103500 + struct libtorrent_error_category : boost::system::error_category + { + virtual const char* name() const BOOST_SYSTEM_NOEXCEPT; + virtual std::string message(int ev) const BOOST_SYSTEM_NOEXCEPT; + virtual boost::system::error_condition default_error_condition(int ev) const BOOST_SYSTEM_NOEXCEPT + { return boost::system::error_condition(ev, *this); } + }; + const char* libtorrent_error_category::name() const BOOST_SYSTEM_NOEXCEPT { return "libtorrent error"; @@ -239,6 +247,7 @@ namespace libtorrent "udp tracker response packet has invalid size", "invalid transaction id in udp tracker response", "invalid action field in udp tracker response", +#ifndef TORRENT_NO_DEPRECATE "", "", "", @@ -257,6 +266,7 @@ namespace libtorrent "expected value (list, dict, int or string) in bencoded string", "bencoded nesting depth exceeded", "bencoded item count limit exceeded", +#endif }; if (ev < 0 || ev >= int(sizeof(msgs)/sizeof(msgs[0]))) return "Unknown error"; diff --git a/src/lazy_bdecode.cpp b/src/lazy_bdecode.cpp index ecc14747d..f0951bb35 100644 --- a/src/lazy_bdecode.cpp +++ b/src/lazy_bdecode.cpp @@ -45,7 +45,7 @@ namespace libtorrent #define TORRENT_FAIL_BDECODE(code) \ { \ - ec = code; \ + ec = make_error_code(code); \ while (!stack.empty()) { \ top = stack.back(); \ if (top->type() == lazy_entry::dict_t || top->type() == lazy_entry::list_t) top->pop(); \ @@ -103,11 +103,11 @@ namespace libtorrent lazy_entry* top = stack.back(); - if (int(stack.size()) > depth_limit) TORRENT_FAIL_BDECODE(errors::depth_exceeded); - if (start >= end) TORRENT_FAIL_BDECODE(errors::unexpected_eof); + if (int(stack.size()) > depth_limit) TORRENT_FAIL_BDECODE(bdecode_errors::depth_exceeded); + if (start >= end) TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof); char t = *start; ++start; - if (start >= end && t != 'e') TORRENT_FAIL_BDECODE(errors::unexpected_eof); + if (start >= end && t != 'e') TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof); switch (top->type()) { @@ -119,17 +119,17 @@ namespace libtorrent stack.pop_back(); continue; } - if (!is_digit(t)) TORRENT_FAIL_BDECODE(errors::expected_string); + if (!is_digit(t)) TORRENT_FAIL_BDECODE(bdecode_errors::expected_string); boost::int64_t len = t - '0'; start = parse_int(start, end, ':', len); if (start == 0 || start + len + 3 > end || *start != ':') - TORRENT_FAIL_BDECODE(errors::expected_colon); + TORRENT_FAIL_BDECODE(bdecode_errors::expected_colon); ++start; - if (start == end) TORRENT_FAIL_BDECODE(errors::unexpected_eof); + if (start == end) TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof); lazy_entry* ent = top->dict_append(start); - if (ent == 0) TORRENT_FAIL_BDECODE(errors::no_memory); + if (ent == 0) TORRENT_FAIL_BDECODE(boost::system::errc::not_enough_memory); start += len; - if (start >= end) TORRENT_FAIL_BDECODE(errors::unexpected_eof); + if (start >= end) TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof); stack.push_back(ent); t = *start; ++start; @@ -144,7 +144,7 @@ namespace libtorrent continue; } lazy_entry* ent = top->list_append(); - if (ent == 0) TORRENT_FAIL_BDECODE(errors::no_memory); + if (ent == 0) TORRENT_FAIL_BDECODE(boost::system::errc::not_enough_memory); stack.push_back(ent); break; } @@ -152,7 +152,7 @@ namespace libtorrent } --item_limit; - if (item_limit <= 0) TORRENT_FAIL_BDECODE(errors::limit_exceeded); + if (item_limit <= 0) TORRENT_FAIL_BDECODE(bdecode_errors::limit_exceeded); top = stack.back(); switch (t) @@ -168,7 +168,7 @@ namespace libtorrent char const* int_start = start; start = find_char(start, end, 'e'); top->construct_int(int_start, start - int_start); - if (start == end) TORRENT_FAIL_BDECODE(errors::unexpected_eof); + if (start == end) TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof); TORRENT_ASSERT(*start == 'e'); ++start; stack.pop_back(); @@ -177,12 +177,12 @@ namespace libtorrent default: { if (!is_digit(t)) - TORRENT_FAIL_BDECODE(errors::expected_value); + TORRENT_FAIL_BDECODE(bdecode_errors::expected_value); boost::int64_t len = t - '0'; start = parse_int(start, end, ':', len); if (start == 0 || start + len + 1 > end || *start != ':') - TORRENT_FAIL_BDECODE(errors::expected_colon); + TORRENT_FAIL_BDECODE(bdecode_errors::expected_colon); ++start; top->construct_string(start, int(len)); stack.pop_back(); @@ -555,5 +555,42 @@ namespace libtorrent } return ret; } + + struct bdecode_error_category : boost::system::error_category + { + virtual const char* name() const BOOST_SYSTEM_NOEXCEPT; + virtual std::string message(int ev) const BOOST_SYSTEM_NOEXCEPT; + virtual boost::system::error_condition default_error_condition(int ev) const BOOST_SYSTEM_NOEXCEPT + { return boost::system::error_condition(ev, *this); } + }; + + const char* bdecode_error_category::name() const BOOST_SYSTEM_NOEXCEPT + { + return "bdecode error"; + } + + std::string bdecode_error_category::message(int ev) const BOOST_SYSTEM_NOEXCEPT + { + static char const* msgs[] = + { + "no error", + "expected string in bencoded string", + "expected colon in bencoded string", + "unexpected end of file in bencoded string", + "expected value (list, dict, int or string) in bencoded string", + "bencoded nesting depth exceeded", + "bencoded item count limit exceeded", + }; + if (ev < 0 || ev >= int(sizeof(msgs)/sizeof(msgs[0]))) + return "Unknown error"; + return msgs[ev]; + } + + boost::system::error_category& get_bdecode_category() + { + static bdecode_error_category bdecode_category; + return bdecode_category; + } + };