fixes problem whith lexical_cast being locale dependent

This commit is contained in:
Arvid Norberg 2009-01-27 06:17:55 +00:00
parent 6c6af0c0a0
commit 8030454c96
21 changed files with 74 additions and 47 deletions

View File

@ -48,6 +48,7 @@ release 0.14.2
* fixed typo in python binding (torrent_handle::piece_prioritize should * fixed typo in python binding (torrent_handle::piece_prioritize should
be torrent_handle::piece_priorities) be torrent_handle::piece_priorities)
* fixed race condition when saving DHT state * fixed race condition when saving DHT state
* fixed bugs related to lexical_cast being locale dependent
release 0.14.1 release 0.14.1

View File

@ -34,11 +34,16 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_ESCAPE_STRING_HPP_INCLUDED #define TORRENT_ESCAPE_STRING_HPP_INCLUDED
#include <string> #include <string>
#include <limits>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <boost/array.hpp>
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#include "libtorrent/size_type.hpp"
namespace libtorrent namespace libtorrent
{ {
boost::array<char, 3 + std::numeric_limits<size_type>::digits10> to_string(size_type n);
std::string TORRENT_EXPORT unescape_string(std::string const& s); std::string TORRENT_EXPORT unescape_string(std::string const& s);
std::string TORRENT_EXPORT escape_string(const char* str, int len); std::string TORRENT_EXPORT escape_string(const char* str, int len);
std::string TORRENT_EXPORT escape_path(const char* str, int len); std::string TORRENT_EXPORT escape_path(const char* str, int len);

View File

@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent namespace libtorrent
{ {
typedef boost::int64_t size_type; typedef boost::int64_t size_type;
typedef boost::uint64_t unsigned_size_type;
} }

View File

@ -39,13 +39,35 @@ POSSIBILITY OF SUCH DAMAGE.
#include <cctype> #include <cctype>
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <limits>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <boost/array.hpp>
#include "libtorrent/assert.hpp" #include "libtorrent/assert.hpp"
#include "libtorrent/escape_string.hpp"
namespace libtorrent namespace libtorrent
{ {
// lexical_cast's result depends on the locale. We need
// a well defined result
boost::array<char, 3 + std::numeric_limits<size_type>::digits10> to_string(size_type n)
{
boost::array<char, 3 + std::numeric_limits<size_type>::digits10> ret;
char *p = &ret.back();;
*p = '\0';
unsigned_size_type un = n;
if (n < 0) un = -un;
do {
*--p = '0' + un % 10;
un /= 10;
} while (un);
if (n < 0) *--p = '-';
std::memmove(&ret.front(), p, sizeof(ret.elems));
return ret;
}
std::string unescape_string(std::string const& s) std::string unescape_string(std::string const& s)
{ {
std::string ret; std::string ret;

View File

@ -39,7 +39,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/connection_queue.hpp" #include "libtorrent/connection_queue.hpp"
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <string> #include <string>
#include <algorithm> #include <algorithm>
@ -118,7 +117,7 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri
sendbuffer = headers.str(); sendbuffer = headers.str();
m_url = url; m_url = url;
start(hostname, boost::lexical_cast<std::string>(port), timeout, prio start(hostname, to_string(port).elems, timeout, prio
, ps, ssl, handle_redirects, bind_addr); , ps, ssl, handle_redirects, bind_addr);
} }

View File

@ -196,17 +196,17 @@ namespace libtorrent
request += "?info_hash="; request += "?info_hash=";
request += escape_string((char const*)&t->torrent_file().info_hash()[0], 20); request += escape_string((char const*)&t->torrent_file().info_hash()[0], 20);
request += "&piece="; request += "&piece=";
request += boost::lexical_cast<std::string>(r.piece); request += to_string(r.piece).elems;
// if we're requesting less than an entire piece we need to // if we're requesting less than an entire piece we need to
// add ranges // add ranges
if (r.start > 0 || r.length != t->torrent_file().piece_size(r.piece)) if (r.start > 0 || r.length != t->torrent_file().piece_size(r.piece))
{ {
request += "&ranges="; request += "&ranges=";
request += boost::lexical_cast<std::string>(r.start); request += to_string(r.start).elems;
request += "-"; request += "-";
// TODO: are ranges inclusive? // TODO: are ranges inclusive?
request += boost::lexical_cast<std::string>(r.start + r.length); request += to_string(r.start + r.length).elems;
} }
request += " HTTP/1.1\r\n"; request += " HTTP/1.1\r\n";
@ -318,8 +318,8 @@ namespace libtorrent
&& m_parser.status_code() < 400)) && m_parser.status_code() < 400))
{ {
t->remove_web_seed(m_url, web_seed_entry::http_seed); t->remove_web_seed(m_url, web_seed_entry::http_seed);
std::string error_msg = boost::lexical_cast<std::string>(m_parser.status_code()) std::string error_msg = to_string(m_parser.status_code()).elems
+ " " + m_parser.message(); + (" " + m_parser.message());
if (m_ses.m_alerts.should_post<url_seed_alert>()) if (m_ses.m_alerts.should_post<url_seed_alert>())
{ {
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);

View File

@ -129,16 +129,16 @@ namespace libtorrent
reinterpret_cast<const char*>(tracker_req().pid.begin()), 20); reinterpret_cast<const char*>(tracker_req().pid.begin()), 20);
url += "&port="; url += "&port=";
url += boost::lexical_cast<std::string>(tracker_req().listen_port); url += to_string(tracker_req().listen_port).elems;
url += "&uploaded="; url += "&uploaded=";
url += boost::lexical_cast<std::string>(tracker_req().uploaded); url += to_string(tracker_req().uploaded).elems;
url += "&downloaded="; url += "&downloaded=";
url += boost::lexical_cast<std::string>(tracker_req().downloaded); url += to_string(tracker_req().downloaded).elems;
url += "&left="; url += "&left=";
url += boost::lexical_cast<std::string>(tracker_req().left); url += to_string(tracker_req().left).elems;
if (tracker_req().event != tracker_request::none) if (tracker_req().event != tracker_request::none)
{ {
@ -155,8 +155,7 @@ namespace libtorrent
url += "&compact=1"; url += "&compact=1";
url += "&numwant="; url += "&numwant=";
url += boost::lexical_cast<std::string>( url += to_string((std::min)(tracker_req().num_want, 999)).elems;
(std::min)(tracker_req().num_want, 999));
if (settings.announce_ip != address()) if (settings.announce_ip != address())
{ {

View File

@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
#endif #endif
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/convenience.hpp> #include <boost/filesystem/convenience.hpp>
@ -214,7 +213,7 @@ namespace
error_code ec; error_code ec;
return boost::shared_ptr<peer_plugin>(new logger_peer_plugin( return boost::shared_ptr<peer_plugin>(new logger_peer_plugin(
pc->remote().address().to_string(ec) + "_" pc->remote().address().to_string(ec) + "_"
+ boost::lexical_cast<std::string>(pc->remote().port()) + ".log")); + to_string(pc->remote().port()).elems + ".log"));
} }
}; };

View File

@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
#endif #endif
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)

View File

@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
#endif #endif
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)

View File

@ -161,7 +161,7 @@ namespace libtorrent
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
error_code ec; error_code ec;
m_logger = m_ses.create_log(m_remote.address().to_string(ec) + "_" m_logger = m_ses.create_log(m_remote.address().to_string(ec) + "_"
+ boost::lexical_cast<std::string>(m_remote.port()), m_ses.listen_port()); + to_string(m_remote.port()).elems, m_ses.listen_port());
(*m_logger) << "*** OUTGOING CONNECTION\n"; (*m_logger) << "*** OUTGOING CONNECTION\n";
#endif #endif
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
@ -272,7 +272,7 @@ namespace libtorrent
error_code ec; error_code ec;
TORRENT_ASSERT(m_socket->remote_endpoint(ec) == m_remote || ec); TORRENT_ASSERT(m_socket->remote_endpoint(ec) == m_remote || ec);
m_logger = m_ses.create_log(remote().address().to_string(ec) + "_" m_logger = m_ses.create_log(remote().address().to_string(ec) + "_"
+ boost::lexical_cast<std::string>(remote().port()), m_ses.listen_port()); + to_string(remote().port()).elems, m_ses.listen_port());
(*m_logger) << "*** INCOMING CONNECTION\n"; (*m_logger) << "*** INCOMING CONNECTION\n";
#endif #endif

View File

@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp> #include <boost/enable_shared_from_this.hpp>
#include <boost/lexical_cast.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)

View File

@ -49,7 +49,6 @@ POSSIBILITY OF SUCH DAMAGE.
#pragma warning(push, 1) #pragma warning(push, 1)
#endif #endif
#include <boost/lexical_cast.hpp>
#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>
@ -1244,7 +1243,7 @@ namespace libtorrent
// assume this is because we got a hostname instead of // assume this is because we got a hostname instead of
// an ip address from the tracker // an ip address from the tracker
tcp::resolver::query q(i->ip, boost::lexical_cast<std::string>(i->port)); tcp::resolver::query q(i->ip, to_string(i->port).elems);
m_host_resolver.async_resolve(q, m_host_resolver.async_resolve(q,
bind(&torrent::on_peer_name_lookup, shared_from_this(), _1, _2, i->pid)); bind(&torrent::on_peer_name_lookup, shared_from_this(), _1, _2, i->pid));
} }
@ -2611,8 +2610,7 @@ namespace libtorrent
|| ps.type == proxy_settings::http_pw) || ps.type == proxy_settings::http_pw)
{ {
// use proxy // use proxy
tcp::resolver::query q(ps.hostname tcp::resolver::query q(ps.hostname, to_string(ps.port).elems);
, boost::lexical_cast<std::string>(ps.port));
m_host_resolver.async_resolve(q, m_host_resolver.async_resolve(q,
bind(&torrent::on_proxy_name_lookup, shared_from_this(), _1, _2, web)); bind(&torrent::on_proxy_name_lookup, shared_from_this(), _1, _2, web));
} }
@ -2630,7 +2628,7 @@ namespace libtorrent
return; return;
} }
tcp::resolver::query q(hostname, boost::lexical_cast<std::string>(port)); tcp::resolver::query q(hostname, to_string(port).elems);
m_host_resolver.async_resolve(q, m_host_resolver.async_resolve(q,
bind(&torrent::on_name_lookup, shared_from_this(), _1, _2, web bind(&torrent::on_name_lookup, shared_from_this(), _1, _2, web
, tcp::endpoint())); , tcp::endpoint()));
@ -2694,7 +2692,7 @@ namespace libtorrent
return; return;
} }
tcp::resolver::query q(hostname, boost::lexical_cast<std::string>(port)); tcp::resolver::query q(hostname, to_string(port).elems);
m_host_resolver.async_resolve(q, m_host_resolver.async_resolve(q,
bind(&torrent::on_name_lookup, shared_from_this(), _1, _2, web, a)); bind(&torrent::on_name_lookup, shared_from_this(), _1, _2, web, a));
} }
@ -3657,6 +3655,8 @@ namespace libtorrent
int torrent::disconnect_peers(int num) int torrent::disconnect_peers(int num)
{ {
INVARIANT_CHECK;
int ret = 0; int ret = 0;
// buils a list of all connected peers and sort it by 'disconnectability'. // buils a list of all connected peers and sort it by 'disconnectability'.
std::vector<peer_connection*> peers(m_connections.size()); std::vector<peer_connection*> peers(m_connections.size());

View File

@ -46,7 +46,6 @@ POSSIBILITY OF SUCH DAMAGE.
#pragma warning(push, 1) #pragma warning(push, 1)
#endif #endif
#include <boost/lexical_cast.hpp>
#include <boost/filesystem/convenience.hpp> #include <boost/filesystem/convenience.hpp>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>

View File

@ -44,7 +44,6 @@ POSSIBILITY OF SUCH DAMAGE.
#pragma warning(push, 1) #pragma warning(push, 1)
#endif #endif
#include <boost/lexical_cast.hpp>
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>

View File

@ -1,6 +1,6 @@
/* /*
Copyright (c) 2007, Arvid Norberg, Magnus Jonsson Copyright (c) 2007, Arvid Norberg
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -32,9 +32,9 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/udp_socket.hpp" #include "libtorrent/udp_socket.hpp"
#include "libtorrent/connection_queue.hpp" #include "libtorrent/connection_queue.hpp"
#include "libtorrent/escape_string.hpp"
#include <stdlib.h> #include <stdlib.h>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/array.hpp> #include <boost/array.hpp>
#if BOOST_VERSION < 103500 #if BOOST_VERSION < 103500
#include <asio/read.hpp> #include <asio/read.hpp>
@ -394,8 +394,7 @@ void udp_socket::set_proxy_settings(proxy_settings const& ps)
|| ps.type == proxy_settings::socks5_pw) || ps.type == proxy_settings::socks5_pw)
{ {
// connect to socks5 server and open up the UDP tunnel // connect to socks5 server and open up the UDP tunnel
tcp::resolver::query q(ps.hostname tcp::resolver::query q(ps.hostname, to_string(ps.port).elems);
, boost::lexical_cast<std::string>(ps.port));
m_resolver.async_resolve(q, boost::bind( m_resolver.async_resolve(q, boost::bind(
&udp_socket::on_name_lookup, this, _1, _2)); &udp_socket::on_name_lookup, this, _1, _2));
} }

View File

@ -56,6 +56,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/udp_tracker_connection.hpp" #include "libtorrent/udp_tracker_connection.hpp"
#include "libtorrent/io.hpp" #include "libtorrent/io.hpp"
#include "libtorrent/aux_/session_impl.hpp" #include "libtorrent/aux_/session_impl.hpp"
#include "libtorrent/escape_string.hpp"
namespace namespace
{ {
@ -69,7 +70,6 @@ namespace
} }
using boost::bind; using boost::bind;
using boost::lexical_cast;
namespace libtorrent namespace libtorrent
{ {
@ -114,7 +114,7 @@ namespace libtorrent
session_settings const& settings = m_ses.settings(); session_settings const& settings = m_ses.settings();
udp::resolver::query q(hostname, boost::lexical_cast<std::string>(port)); udp::resolver::query q(hostname, to_string(port).elems);
m_name_lookup.async_resolve(q m_name_lookup.async_resolve(q
, boost::bind( , boost::bind(
&udp_tracker_connection::name_lookup, self(), _1, _2)); &udp_tracker_connection::name_lookup, self(), _1, _2));

View File

@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/xml_parse.hpp" #include "libtorrent/xml_parse.hpp"
#include "libtorrent/connection_queue.hpp" #include "libtorrent/connection_queue.hpp"
#include "libtorrent/enum_net.hpp" #include "libtorrent/enum_net.hpp"
#include "libtorrent/escape_string.hpp"
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
@ -661,7 +662,7 @@ void upnp::update_map(rootdevice& d, int i)
, boost::ref(d), i, _5), true , boost::ref(d), i, _5), true
, bind(&upnp::create_port_mapping, self(), _1, boost::ref(d), i))); , bind(&upnp::create_port_mapping, self(), _1, boost::ref(d), i)));
d.upnp_connection->start(d.hostname, boost::lexical_cast<std::string>(d.port) d.upnp_connection->start(d.hostname, to_string(d.port).elems
, seconds(10), 1); , seconds(10), 1);
} }
else if (m.action == mapping_t::action_delete) else if (m.action == mapping_t::action_delete)
@ -671,7 +672,7 @@ void upnp::update_map(rootdevice& d, int i)
, m_cc, bind(&upnp::on_upnp_unmap_response, self(), _1, _2 , m_cc, bind(&upnp::on_upnp_unmap_response, self(), _1, _2
, boost::ref(d), i, _5), true , boost::ref(d), i, _5), true
, bind(&upnp::delete_port_mapping, self(), boost::ref(d), i))); , bind(&upnp::delete_port_mapping, self(), boost::ref(d), i)));
d.upnp_connection->start(d.hostname, boost::lexical_cast<std::string>(d.port) d.upnp_connection->start(d.hostname, to_string(d.port).elems
, seconds(10), 1); , seconds(10), 1);
} }
@ -899,7 +900,7 @@ void upnp::on_upnp_xml(error_code const& e
boost::tie(protocol, auth, d.hostname, d.port, d.path, error) boost::tie(protocol, auth, d.hostname, d.port, d.path, error)
= parse_url_components(d.url); = parse_url_components(d.url);
d.control_url = protocol + "://" + d.hostname + ":" d.control_url = protocol + "://" + d.hostname + ":"
+ boost::lexical_cast<std::string>(d.port) + s.control_url; + to_string(d.port).elems + s.control_url;
} }
std::stringstream msg; std::stringstream msg;
@ -1136,7 +1137,7 @@ void upnp::return_error(int mapping, int code)
error_code_t* e = std::lower_bound(error_codes, end, tmp error_code_t* e = std::lower_bound(error_codes, end, tmp
, bind(&error_code_t::code, _1) < bind(&error_code_t::code, _2)); , bind(&error_code_t::code, _1) < bind(&error_code_t::code, _2));
std::string error_string = "UPnP mapping error "; std::string error_string = "UPnP mapping error ";
error_string += boost::lexical_cast<std::string>(code); error_string += to_string(code).elems;
if (e != end && e->code == code) if (e != end && e->code == code)
{ {
error_string += ": "; error_string += ": ";

View File

@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
#endif #endif
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)

View File

@ -230,11 +230,9 @@ namespace libtorrent
request += "\r\nProxy-Connection: keep-alive"; request += "\r\nProxy-Connection: keep-alive";
} }
request += "\r\nRange: bytes="; request += "\r\nRange: bytes=";
request += boost::lexical_cast<std::string>(size_type(r.piece) request += to_string(size_type(r.piece) * info.piece_length() + r.start).elems;
* info.piece_length() + r.start);
request += "-"; request += "-";
request += boost::lexical_cast<std::string>(r.piece request += to_string(r.piece * info.piece_length() + r.start + r.length - 1).elems;
* info.piece_length() + r.start + r.length - 1);
if (m_first_request || using_proxy) if (m_first_request || using_proxy)
request += "\r\nConnection: keep-alive"; request += "\r\nConnection: keep-alive";
request += "\r\n\r\n"; request += "\r\n\r\n";
@ -287,9 +285,9 @@ namespace libtorrent
request += "\r\nProxy-Connection: keep-alive"; request += "\r\nProxy-Connection: keep-alive";
} }
request += "\r\nRange: bytes="; request += "\r\nRange: bytes=";
request += boost::lexical_cast<std::string>(f.offset); request += to_string(f.offset).elems;
request += "-"; request += "-";
request += boost::lexical_cast<std::string>(f.offset + f.size - 1); request += to_string(f.offset + f.size - 1).elems;
if (m_first_request || using_proxy) if (m_first_request || using_proxy)
request += "\r\nConnection: keep-alive"; request += "\r\nConnection: keep-alive";
request += "\r\n\r\n"; request += "\r\n\r\n";
@ -384,8 +382,8 @@ namespace libtorrent
t->retry_web_seed(m_url, web_seed_entry::url_seed); t->retry_web_seed(m_url, web_seed_entry::url_seed);
} }
t->remove_web_seed(m_url, web_seed_entry::url_seed); t->remove_web_seed(m_url, web_seed_entry::url_seed);
std::string error_msg = boost::lexical_cast<std::string>(m_parser.status_code()) std::string error_msg = to_string(m_parser.status_code()).elems
+ " " + m_parser.message(); + (" " + m_parser.message());
if (m_ses.m_alerts.should_post<url_seed_alert>()) if (m_ses.m_alerts.should_post<url_seed_alert>())
{ {
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);

View File

@ -347,6 +347,15 @@ int test_main()
{ {
using namespace libtorrent; using namespace libtorrent;
// test itoa
TEST_CHECK(to_string(345).elems == std::string("345"));
TEST_CHECK(to_string(-345).elems == std::string("-345"));
TEST_CHECK(to_string(0).elems == std::string("0"));
TEST_CHECK(to_string(1000000000).elems == std::string("1000000000"));
// test url parsing
TEST_CHECK(parse_url_components("http://foo:bar@host.com:80/path/to/file") TEST_CHECK(parse_url_components("http://foo:bar@host.com:80/path/to/file")
== make_tuple("http", "foo:bar", "host.com", 80, "/path/to/file", (char const*)0)); == make_tuple("http", "foo:bar", "host.com", 80, "/path/to/file", (char const*)0));