libtorrent sync 1436

This commit is contained in:
Marcos Pinto 2007-08-07 07:39:08 +00:00
parent 9dd7f6c6cf
commit c06b63b027
6 changed files with 151 additions and 42 deletions

View File

@ -33,11 +33,25 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef TORRENT_XML_PARSE_HPP #ifndef TORRENT_XML_PARSE_HPP
#define TORRENT_XML_PARSE_HPP #define TORRENT_XML_PARSE_HPP
#include <cctype>
namespace libtorrent namespace libtorrent
{ {
const int xml_start_tag = 0; enum
const int xml_end_tag = 1; {
const int xml_string = 2; xml_start_tag,
xml_end_tag,
xml_empty_tag,
xml_declaration_tag,
xml_string,
xml_attribute,
xml_comment,
xml_parse_error
};
// callback(int type, char const* name, char const* val)
// str2 is only used for attributes. name is element or attribute
// name and val is attribute value
template <class CallbackType> template <class CallbackType>
void xml_parse(char* p, char* end, CallbackType callback) void xml_parse(char* p, char* end, CallbackType callback)
@ -45,6 +59,8 @@ namespace libtorrent
for(;p != end; ++p) for(;p != end; ++p)
{ {
char const* start = p; char const* start = p;
char const* val_start = 0;
int token;
// look for tag start // look for tag start
for(; *p != '<' && p != end; ++p); for(; *p != '<' && p != end; ++p);
@ -55,39 +71,135 @@ namespace libtorrent
assert(*p == '<'); assert(*p == '<');
*p = 0; *p = 0;
} }
callback(xml_string, start); token = xml_string;
callback(token, start, val_start);
if (p != end) *p = '<'; if (p != end) *p = '<';
} }
if (p == end) break; if (p == end) break;
// skip '<' // skip '<'
++p; ++p;
// parse the name of the tag. Ignore attributes // parse the name of the tag.
for (start = p; p != end && *p != '>'; ++p) for (start = p; p != end && *p != '>' && !std::isspace(*p); ++p);
{
// terminate the string at the first space char* tag_name_end = p;
// to ignore tag attributes
if (*p == ' ') *p = 0; // skip the attributes for now
} for (; p != end && *p != '>'; ++p);
// parse error // parse error
if (p == end) break; if (p == end)
{
token = xml_parse_error;
start = "unexpected end of file";
callback(token, start, val_start);
break;
}
assert(*p == '>'); assert(*p == '>');
*p = 0; // save the character that terminated the tag name
// it could be both '>' and ' '.
char save = *tag_name_end;
*tag_name_end = 0;
char* tag_end = p;
if (*start == '/') if (*start == '/')
{ {
++start; ++start;
callback(xml_end_tag, start); token = xml_end_tag;
callback(token, start, val_start);
}
else if (*(p-1) == '/')
{
*(p-1) = 0;
token = xml_empty_tag;
callback(token, start, val_start);
*(p-1) = '/';
tag_end = p - 1;
}
else if (*start == '?' && *(p-1) == '?')
{
*(p-1) = 0;
++start;
token = xml_declaration_tag;
callback(token, start, val_start);
*(p-1) = '?';
tag_end = p - 1;
}
else if (start + 5 < p && memcmp(start, "!--", 3) == 0 && memcmp(p-2, "--", 2) == 0)
{
start += 3;
*(p-2) = 0;
token = xml_comment;
callback(token, start, val_start);
*(p-2) = '-';
tag_end = p - 2;
} }
else else
{ {
callback(xml_start_tag, start); token = xml_start_tag;
callback(token, start, val_start);
}
*tag_name_end = save;
// parse attributes
for (char* i = tag_name_end; i < tag_end; ++i)
{
// find start of attribute name
for (; i != tag_end && std::isspace(*i); ++i);
if (i == tag_end) break;
start = i;
// find end of attribute name
for (; i != tag_end && *i != '=' && !std::isspace(*i); ++i);
char* name_end = i;
// look for equality sign
for (; i != tag_end && *i != '='; ++i);
if (i == tag_end)
{
token = xml_parse_error;
val_start = 0;
start = "garbage inside element brackets";
callback(token, start, val_start);
break;
}
++i;
for (; i != tag_end && std::isspace(*i); ++i);
// check for parse error (values must be quoted)
if (i == tag_end || (*i != '\'' && *i != '\"'))
{
token = xml_parse_error;
val_start = 0;
start = "unquoted attribute value";
callback(token, start, val_start);
break;
}
char quote = *i;
++i;
val_start = i;
for (; i != tag_end && *i != quote; ++i);
// parse error (missing end quote)
if (i == tag_end)
{
token = xml_parse_error;
val_start = 0;
start = "missing end quote on attribute";
callback(token, start, val_start);
break;
}
save = *i;
*i = 0;
*name_end = 0;
token = xml_attribute;
callback(token, start, val_start);
*name_end = '=';
*i = save;
} }
*p = '>';
} }
} }

View File

@ -35,7 +35,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/lsd.hpp" #include "libtorrent/lsd.hpp"
#include "libtorrent/io.hpp" #include "libtorrent/io.hpp"
#include "libtorrent/http_tracker_connection.hpp" #include "libtorrent/http_tracker_connection.hpp"
#include "libtorrent/xml_parse.hpp"
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
#include <asio/ip/host_name.hpp> #include <asio/ip/host_name.hpp>

View File

@ -1901,13 +1901,15 @@ namespace detail
int session_impl::upload_rate_limit() const int session_impl::upload_rate_limit() const
{ {
mutex_t::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
return m_bandwidth_manager[peer_connection::upload_channel]->throttle(); int ret = m_bandwidth_manager[peer_connection::upload_channel]->throttle();
return ret == std::numeric_limits<int>::max() ? -1 : ret;
} }
int session_impl::download_rate_limit() const int session_impl::download_rate_limit() const
{ {
mutex_t::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
return m_bandwidth_manager[peer_connection::download_channel]->throttle(); int ret = m_bandwidth_manager[peer_connection::download_channel]->throttle();
return ret == std::numeric_limits<int>::max() ? -1 : ret;
} }
void session_impl::start_lsd() void session_impl::start_lsd()

View File

@ -1060,9 +1060,9 @@ namespace libtorrent
// TODO: POSIX implementation // TODO: POSIX implementation
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
return true; return true;
#else #else
return false; return false;
#endif #endif
} }

View File

@ -50,7 +50,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/filesystem/convenience.hpp> #include <boost/filesystem/convenience.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <boost/tokenizer.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
@ -1659,30 +1658,26 @@ namespace libtorrent
}; };
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
namespace
{
unsigned long swap_bytes(unsigned long a)
{
return (a >> 24) | ((a & 0xff0000) >> 8) | ((a & 0xff00) << 8) | (a << 24);
}
}
void torrent::resolve_peer_country(boost::intrusive_ptr<peer_connection> const& p) const void torrent::resolve_peer_country(boost::intrusive_ptr<peer_connection> const& p) const
{ {
if (m_resolving_country if (m_resolving_country
|| p->has_country() || p->has_country()
|| p->is_connecting() || p->is_connecting()
|| p->is_queued() || p->is_queued()
|| p->in_handshake()) return; || p->in_handshake()
|| p->remote().address().is_v6()) return;
m_resolving_country = true; m_resolving_country = true;
asio::ip::address_v4 reversed(swap_bytes(p->remote().address().to_v4().to_ulong()));
std::string ip_address = boost::lexical_cast<std::string>(p->remote().address()); tcp::resolver::query q(reversed.to_string() + ".zz.countries.nerd.dk", "0");
std::string ip_address_reversed = "";
boost::char_separator<char> sep(".");
boost::tokenizer< boost::char_separator<char> > tokens(ip_address, sep);
for (boost::tokenizer< boost::char_separator<char> >::const_iterator it = tokens.begin(); it != tokens.end(); ++it)
{
if(ip_address_reversed != "")
ip_address_reversed = "." + ip_address_reversed;
ip_address_reversed = *it + ip_address_reversed;
}
tcp::resolver::query q(ip_address_reversed
+ ".zz.countries.nerd.dk", "0");
m_host_resolver.async_resolve(q, m_ses.m_strand.wrap( m_host_resolver.async_resolve(q, m_ses.m_strand.wrap(
bind(&torrent::on_country_lookup, shared_from_this(), _1, _2, p))); bind(&torrent::on_country_lookup, shared_from_this(), _1, _2, p)));
} }

View File

@ -62,9 +62,10 @@ namespace libtorrent
{ {
if (a.is_v6()) return false; if (a.is_v6()) return false;
address_v4 a4 = a.to_v4(); address_v4 a4 = a.to_v4();
return ((a4.to_ulong() & 0xff000000) == 0x0a000000 unsigned long ip = htonl(a4.to_ulong());
|| (a4.to_ulong() & 0xfff00000) == 0xac100000 return ((ip & 0xff000000) == 0x0a000000
|| (a4.to_ulong() & 0xffff0000) == 0xc0a80000); || (ip & 0xfff00000) == 0xac100000
|| (ip & 0xffff0000) == 0xc0a80000);
} }
address_v4 guess_local_address(asio::io_service& ios) address_v4 guess_local_address(asio::io_service& ios)