lt exception tweaks 1719
This commit is contained in:
parent
2eec0a766d
commit
b144525cab
|
@ -135,26 +135,38 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class InIt>
|
template <class InIt>
|
||||||
std::string read_until(InIt& in, InIt end, char end_token)
|
std::string read_until(InIt& in, InIt end, char end_token, bool& err)
|
||||||
{
|
{
|
||||||
if (in == end) throw invalid_encoding();
|
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
if (in == end)
|
||||||
|
{
|
||||||
|
err = true;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
while (*in != end_token)
|
while (*in != end_token)
|
||||||
{
|
{
|
||||||
ret += *in;
|
ret += *in;
|
||||||
++in;
|
++in;
|
||||||
if (in == end) throw invalid_encoding();
|
if (in == end)
|
||||||
|
{
|
||||||
|
err = true;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class InIt>
|
template<class InIt>
|
||||||
void read_string(InIt& in, InIt end, int len, std::string& str)
|
void read_string(InIt& in, InIt end, int len, std::string& str, bool& err)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(len >= 0);
|
TORRENT_ASSERT(len >= 0);
|
||||||
for (int i = 0; i < len; ++i)
|
for (int i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
if (in == end) throw invalid_encoding();
|
if (in == end)
|
||||||
|
{
|
||||||
|
err = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
str += *in;
|
str += *in;
|
||||||
++in;
|
++in;
|
||||||
}
|
}
|
||||||
|
@ -202,9 +214,13 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class InIt>
|
template<class InIt>
|
||||||
void bdecode_recursive(InIt& in, InIt end, entry& ret)
|
void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err)
|
||||||
{
|
{
|
||||||
if (in == end) throw invalid_encoding();
|
if (in == end)
|
||||||
|
{
|
||||||
|
err = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (*in)
|
switch (*in)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -213,7 +229,8 @@ namespace libtorrent
|
||||||
case 'i':
|
case 'i':
|
||||||
{
|
{
|
||||||
++in; // 'i'
|
++in; // 'i'
|
||||||
std::string val = read_until(in, end, 'e');
|
std::string val = read_until(in, end, 'e', err);
|
||||||
|
if (err) return;
|
||||||
TORRENT_ASSERT(*in == 'e');
|
TORRENT_ASSERT(*in == 'e');
|
||||||
++in; // 'e'
|
++in; // 'e'
|
||||||
ret = entry(entry::int_t);
|
ret = entry(entry::int_t);
|
||||||
|
@ -230,8 +247,13 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
ret.list().push_back(entry());
|
ret.list().push_back(entry());
|
||||||
entry& e = ret.list().back();
|
entry& e = ret.list().back();
|
||||||
bdecode_recursive(in, end, e);
|
bdecode_recursive(in, end, e, err);
|
||||||
if (in == end) throw invalid_encoding();
|
if (err) return;
|
||||||
|
if (in == end)
|
||||||
|
{
|
||||||
|
err = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TORRENT_ASSERT(*in == 'e');
|
TORRENT_ASSERT(*in == 'e');
|
||||||
++in; // 'e'
|
++in; // 'e'
|
||||||
|
@ -246,10 +268,16 @@ namespace libtorrent
|
||||||
while (*in != 'e')
|
while (*in != 'e')
|
||||||
{
|
{
|
||||||
entry key;
|
entry key;
|
||||||
bdecode_recursive(in, end, key);
|
bdecode_recursive(in, end, key, err);
|
||||||
|
if (err) return;
|
||||||
entry& e = ret[key.string()];
|
entry& e = ret[key.string()];
|
||||||
bdecode_recursive(in, end, e);
|
bdecode_recursive(in, end, e, err);
|
||||||
if (in == end) throw invalid_encoding();
|
if (err) return;
|
||||||
|
if (in == end)
|
||||||
|
{
|
||||||
|
err = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
TORRENT_ASSERT(*in == 'e');
|
TORRENT_ASSERT(*in == 'e');
|
||||||
++in; // 'e'
|
++in; // 'e'
|
||||||
|
@ -260,16 +288,19 @@ namespace libtorrent
|
||||||
default:
|
default:
|
||||||
if (isdigit((unsigned char)*in))
|
if (isdigit((unsigned char)*in))
|
||||||
{
|
{
|
||||||
std::string len_s = read_until(in, end, ':');
|
std::string len_s = read_until(in, end, ':', err);
|
||||||
|
if (err) return;
|
||||||
TORRENT_ASSERT(*in == ':');
|
TORRENT_ASSERT(*in == ':');
|
||||||
++in; // ':'
|
++in; // ':'
|
||||||
int len = std::atoi(len_s.c_str());
|
int len = std::atoi(len_s.c_str());
|
||||||
ret = entry(entry::string_t);
|
ret = entry(entry::string_t);
|
||||||
read_string(in, end, len, ret.string());
|
read_string(in, end, len, ret.string(), err);
|
||||||
|
if (err) return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw invalid_encoding();
|
err = true;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,17 +314,19 @@ namespace libtorrent
|
||||||
|
|
||||||
template<class InIt>
|
template<class InIt>
|
||||||
entry bdecode(InIt start, InIt end)
|
entry bdecode(InIt start, InIt end)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
entry e;
|
entry e;
|
||||||
detail::bdecode_recursive(start, end, e);
|
bool err = false;
|
||||||
return e;
|
detail::bdecode_recursive(start, end, e, err);
|
||||||
}
|
if (err)
|
||||||
catch(type_error&)
|
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_NO_EXCEPTIONS
|
||||||
|
return entry();
|
||||||
|
#else
|
||||||
throw invalid_encoding();
|
throw invalid_encoding();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,8 +161,10 @@ namespace libtorrent
|
||||||
// is a dictionary, otherwise they will throw
|
// is a dictionary, otherwise they will throw
|
||||||
entry& operator[](char const* key);
|
entry& operator[](char const* key);
|
||||||
entry& operator[](std::string const& key);
|
entry& operator[](std::string const& key);
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
const entry& operator[](char const* key) const;
|
const entry& operator[](char const* key) const;
|
||||||
const entry& operator[](std::string const& key) const;
|
const entry& operator[](std::string const& key) const;
|
||||||
|
#endif
|
||||||
entry* find_key(char const* key);
|
entry* find_key(char const* key);
|
||||||
entry const* find_key(char const* key) const;
|
entry const* find_key(char const* key) const;
|
||||||
|
|
||||||
|
@ -221,55 +223,80 @@ namespace libtorrent
|
||||||
copy(e);
|
copy(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline entry::integer_type& entry::integer()
|
inline entry::integer_type& entry::integer()
|
||||||
{
|
{
|
||||||
if (m_type == undefined_t) construct(int_t);
|
if (m_type == undefined_t) construct(int_t);
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
if (m_type != int_t) throw type_error("invalid type requested from entry");
|
if (m_type != int_t) throw type_error("invalid type requested from entry");
|
||||||
|
#endif
|
||||||
|
TORRENT_ASSERT(m_type == int_t);
|
||||||
return *reinterpret_cast<integer_type*>(data);
|
return *reinterpret_cast<integer_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::integer_type const& entry::integer() const
|
inline entry::integer_type const& entry::integer() const
|
||||||
{
|
{
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
if (m_type != int_t) throw type_error("invalid type requested from entry");
|
if (m_type != int_t) throw type_error("invalid type requested from entry");
|
||||||
|
#endif
|
||||||
|
TORRENT_ASSERT(m_type == int_t);
|
||||||
return *reinterpret_cast<const integer_type*>(data);
|
return *reinterpret_cast<const integer_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::string_type& entry::string()
|
inline entry::string_type& entry::string()
|
||||||
{
|
{
|
||||||
if (m_type == undefined_t) construct(string_t);
|
if (m_type == undefined_t) construct(string_t);
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
if (m_type != string_t) throw type_error("invalid type requested from entry");
|
if (m_type != string_t) throw type_error("invalid type requested from entry");
|
||||||
|
#endif
|
||||||
|
TORRENT_ASSERT(m_type == string_t);
|
||||||
return *reinterpret_cast<string_type*>(data);
|
return *reinterpret_cast<string_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::string_type const& entry::string() const
|
inline entry::string_type const& entry::string() const
|
||||||
{
|
{
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
if (m_type != string_t) throw type_error("invalid type requested from entry");
|
if (m_type != string_t) throw type_error("invalid type requested from entry");
|
||||||
|
#endif
|
||||||
|
TORRENT_ASSERT(m_type == string_t);
|
||||||
return *reinterpret_cast<const string_type*>(data);
|
return *reinterpret_cast<const string_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::list_type& entry::list()
|
inline entry::list_type& entry::list()
|
||||||
{
|
{
|
||||||
if (m_type == undefined_t) construct(list_t);
|
if (m_type == undefined_t) construct(list_t);
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
if (m_type != list_t) throw type_error("invalid type requested from entry");
|
if (m_type != list_t) throw type_error("invalid type requested from entry");
|
||||||
|
#endif
|
||||||
|
TORRENT_ASSERT(m_type == list_t);
|
||||||
return *reinterpret_cast<list_type*>(data);
|
return *reinterpret_cast<list_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::list_type const& entry::list() const
|
inline entry::list_type const& entry::list() const
|
||||||
{
|
{
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
if (m_type != list_t) throw type_error("invalid type requested from entry");
|
if (m_type != list_t) throw type_error("invalid type requested from entry");
|
||||||
|
#endif
|
||||||
|
TORRENT_ASSERT(m_type == list_t);
|
||||||
return *reinterpret_cast<const list_type*>(data);
|
return *reinterpret_cast<const list_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::dictionary_type& entry::dict()
|
inline entry::dictionary_type& entry::dict()
|
||||||
{
|
{
|
||||||
if (m_type == undefined_t) construct(dictionary_t);
|
if (m_type == undefined_t) construct(dictionary_t);
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
if (m_type != dictionary_t) throw type_error("invalid type requested from entry");
|
if (m_type != dictionary_t) throw type_error("invalid type requested from entry");
|
||||||
|
#endif
|
||||||
|
TORRENT_ASSERT(m_type == dictionary_t);
|
||||||
return *reinterpret_cast<dictionary_type*>(data);
|
return *reinterpret_cast<dictionary_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline entry::dictionary_type const& entry::dict() const
|
inline entry::dictionary_type const& entry::dict() const
|
||||||
{
|
{
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
if (m_type != dictionary_t) throw type_error("invalid type requested from entry");
|
if (m_type != dictionary_t) throw type_error("invalid type requested from entry");
|
||||||
|
#endif
|
||||||
|
TORRENT_ASSERT(m_type == dictionary_t);
|
||||||
return *reinterpret_cast<const dictionary_type*>(data);
|
return *reinterpret_cast<const dictionary_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,7 @@ namespace libtorrent
|
||||||
return &i->second;
|
return &i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
const entry& entry::operator[](char const* key) const
|
const entry& entry::operator[](char const* key) const
|
||||||
{
|
{
|
||||||
dictionary_type::const_iterator i = dict().find(key);
|
dictionary_type::const_iterator i = dict().find(key);
|
||||||
|
@ -138,6 +139,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
return (*this)[key.c_str()];
|
return (*this)[key.c_str()];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
entry::entry(dictionary_type const& v)
|
entry::entry(dictionary_type const& v)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue