*** empty log message ***
This commit is contained in:
parent
bbd2d04038
commit
06ad07cea7
11
Jamfile
11
Jamfile
|
@ -20,6 +20,9 @@ project torrent
|
||||||
<include>$(BOOST_ROOT)
|
<include>$(BOOST_ROOT)
|
||||||
<variant>release:<define>NDEBUG
|
<variant>release:<define>NDEBUG
|
||||||
<define>BOOST_ALL_NO_LIB
|
<define>BOOST_ALL_NO_LIB
|
||||||
|
<library>/boost/thread//boost_thread
|
||||||
|
<library>/boost/filesystem//boost_filesystem/<link>static
|
||||||
|
<library>/boost/date_time//boost_date_time/<link>static
|
||||||
|
|
||||||
# devstudio switches
|
# devstudio switches
|
||||||
|
|
||||||
|
@ -31,6 +34,10 @@ project torrent
|
||||||
|
|
||||||
<toolset>gcc:<cxxflags>-Wno-unused-variable
|
<toolset>gcc:<cxxflags>-Wno-unused-variable
|
||||||
|
|
||||||
|
# darwin switches
|
||||||
|
|
||||||
|
<toolset>darwin:<cxxflags>-Wno-unused-variable
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,13 +82,11 @@ lib torrent
|
||||||
:
|
:
|
||||||
zlib//zlib
|
zlib//zlib
|
||||||
src/$(SOURCES)
|
src/$(SOURCES)
|
||||||
/boost/thread//boost_thread/<link>shared
|
|
||||||
/boost/date_time//boost_date_time/<link>static
|
|
||||||
/boost/filesystem//boost_filesystem/<link>static
|
|
||||||
$(LIBS)
|
$(LIBS)
|
||||||
:
|
:
|
||||||
<threading>multi
|
<threading>multi
|
||||||
<link>static
|
<link>static
|
||||||
|
<variant>debug:<define>TORRENT_VERBOSE_LOGGING
|
||||||
: debug release
|
: debug release
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -22,4 +22,5 @@ exe dump_torrent
|
||||||
:
|
:
|
||||||
: debug release
|
: debug release
|
||||||
;
|
;
|
||||||
|
stage bin : dump_torrent simple_client client_test ;
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,7 @@ int main(int argc, char* argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::path::default_name_check(boost::filesystem::native);
|
boost::filesystem::path::default_name_check(boost::filesystem::no_check);
|
||||||
|
|
||||||
http_settings settings;
|
http_settings settings;
|
||||||
// settings.proxy_ip = "192.168.0.1";
|
// settings.proxy_ip = "192.168.0.1";
|
||||||
|
|
|
@ -50,6 +50,8 @@ int main(int argc, char* argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::filesystem::path::default_name_check(boost::filesystem::no_check);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::ifstream in(argv[1], std::ios_base::binary);
|
std::ifstream in(argv[1], std::ios_base::binary);
|
||||||
|
|
|
@ -107,7 +107,11 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef std::map<std::string, entry> dictionary_type;
|
// we need a vector here to maintain the order
|
||||||
|
// of elements. Since the info-hash is reconstructed
|
||||||
|
// from an entry, it's important that the order is
|
||||||
|
// preserved.
|
||||||
|
typedef std::vector<std::pair<std::string, entry> > dictionary_type;
|
||||||
typedef std::string string_type;
|
typedef std::string string_type;
|
||||||
typedef std::vector<entry> list_type;
|
typedef std::vector<entry> list_type;
|
||||||
typedef size_type integer_type;
|
typedef size_type integer_type;
|
||||||
|
@ -192,31 +196,14 @@ namespace libtorrent
|
||||||
return *reinterpret_cast<const dictionary_type*>(data);
|
return *reinterpret_cast<const dictionary_type*>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
entry& operator[](const char* key)
|
// these functions requires that the entry
|
||||||
{
|
// is a dictionary, otherwise they will throw
|
||||||
return dict()[key];
|
entry& operator[](char const* key);
|
||||||
}
|
entry& operator[](std::string const& key);
|
||||||
|
const entry& operator[](char const* key) const;
|
||||||
entry& operator[](const std::string& key)
|
const entry& operator[](std::string const& key) const;
|
||||||
{
|
entry* find_key(char const* key);
|
||||||
return dict()[key.c_str()];
|
entry const* find_key(char const* key) const;
|
||||||
}
|
|
||||||
|
|
||||||
const entry& operator[](const char* key) const
|
|
||||||
{
|
|
||||||
dictionary_type::const_iterator i =
|
|
||||||
dict().find(key);
|
|
||||||
if (i == dict().end()) throw type_error("key not found");
|
|
||||||
return i->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
const entry& operator[](const std::string& key) const
|
|
||||||
{
|
|
||||||
dictionary_type::const_iterator i =
|
|
||||||
dict().find(key);
|
|
||||||
if (i == dict().end()) throw type_error("key not found");
|
|
||||||
return i->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void print(std::ostream& os, int indent = 0) const;
|
void print(std::ostream& os, int indent = 0) const;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
namespace std
|
namespace std
|
||||||
|
@ -48,10 +49,79 @@ namespace
|
||||||
assert(o);
|
assert(o);
|
||||||
o->~T();
|
o->~T();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct compare_string
|
||||||
|
{
|
||||||
|
compare_string(char const* s): m_str(s) {}
|
||||||
|
|
||||||
|
bool operator()(
|
||||||
|
std::pair<std::string
|
||||||
|
, libtorrent::entry> const& e) const
|
||||||
|
{
|
||||||
|
return e.first == m_str;
|
||||||
|
}
|
||||||
|
char const* m_str;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
entry& entry::operator[](char const* key)
|
||||||
|
{
|
||||||
|
dictionary_type::iterator i = std::find_if(
|
||||||
|
dict().begin()
|
||||||
|
, dict().end()
|
||||||
|
, compare_string(key));
|
||||||
|
if (i != dict().end()) return i->second;
|
||||||
|
dictionary_type::iterator ret = dict().insert(
|
||||||
|
dict().end()
|
||||||
|
, std::make_pair(std::string(key), entry()));
|
||||||
|
return ret->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
entry& entry::operator[](std::string const& key)
|
||||||
|
{
|
||||||
|
return (*this)[key.c_str()];
|
||||||
|
}
|
||||||
|
|
||||||
|
entry* entry::find_key(char const* key)
|
||||||
|
{
|
||||||
|
dictionary_type::iterator i = std::find_if(
|
||||||
|
dict().begin()
|
||||||
|
, dict().end()
|
||||||
|
, compare_string(key));
|
||||||
|
if (i == dict().end()) return 0;
|
||||||
|
return &i->second;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
entry const* entry::find_key(char const* key) const
|
||||||
|
{
|
||||||
|
dictionary_type::const_iterator i = std::find_if(
|
||||||
|
dict().begin()
|
||||||
|
, dict().end()
|
||||||
|
, compare_string(key));
|
||||||
|
if (i == dict().end()) return 0;
|
||||||
|
return &i->second;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const entry& entry::operator[](char const* key) const
|
||||||
|
{
|
||||||
|
dictionary_type::const_iterator i = std::find_if(
|
||||||
|
dict().begin()
|
||||||
|
, dict().end()
|
||||||
|
, compare_string(key));
|
||||||
|
if (i == dict().end()) throw type_error("key not found");
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const entry& entry::operator[](std::string const& key) const
|
||||||
|
{
|
||||||
|
return (*this)[key.c_str()];
|
||||||
|
}
|
||||||
|
|
||||||
entry::entry(const dictionary_type& v)
|
entry::entry(const dictionary_type& v)
|
||||||
{
|
{
|
||||||
|
|
|
@ -454,18 +454,17 @@ namespace libtorrent
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
peer_entry http_tracker_connection::extract_peer_info(const entry& e)
|
peer_entry http_tracker_connection::extract_peer_info(const entry& info)
|
||||||
{
|
{
|
||||||
peer_entry ret;
|
peer_entry ret;
|
||||||
|
|
||||||
const entry::dictionary_type& info = e.dict();
|
|
||||||
|
|
||||||
// extract peer id (if any)
|
// extract peer id (if any)
|
||||||
entry::dictionary_type::const_iterator i = info.find("peer id");
|
entry const* i = info.find_key("peer id");
|
||||||
if (i != info.end())
|
if (i != 0)
|
||||||
{
|
{
|
||||||
if (i->second.string().length() != 20) throw std::runtime_error("invalid response from tracker");
|
if (i->string().length() != 20)
|
||||||
std::copy(i->second.string().begin(), i->second.string().end(), ret.id.begin());
|
throw std::runtime_error("invalid response from tracker");
|
||||||
|
std::copy(i->string().begin(), i->string().end(), ret.id.begin());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -474,14 +473,14 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract ip
|
// extract ip
|
||||||
i = info.find("ip");
|
i = info.find_key("ip");
|
||||||
if (i == info.end()) throw std::runtime_error("invalid response from tracker");
|
if (i == 0) throw std::runtime_error("invalid response from tracker");
|
||||||
ret.ip = i->second.string();
|
ret.ip = i->string();
|
||||||
|
|
||||||
// extract port
|
// extract port
|
||||||
i = info.find("port");
|
i = info.find_key("port");
|
||||||
if (i == info.end()) throw std::runtime_error("invalid response from tracker");
|
if (i == 0) throw std::runtime_error("invalid response from tracker");
|
||||||
ret.port = (unsigned short)i->second.integer();
|
ret.port = (unsigned short)i->integer();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -886,11 +886,10 @@ namespace libtorrent
|
||||||
|
|
||||||
for (int i = 0; i < num_supported_extensions; ++i)
|
for (int i = 0; i < num_supported_extensions; ++i)
|
||||||
{
|
{
|
||||||
entry::dictionary_type::iterator f =
|
entry* f = e.find_key(extension_names[i]);
|
||||||
extensions.find(extension_names[i]);
|
if (f)
|
||||||
if (f != extensions.end())
|
|
||||||
{
|
{
|
||||||
m_extension_messages[i] = (int)f->second.integer();
|
m_extension_messages[i] = (int)f->integer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -1132,7 +1131,7 @@ namespace libtorrent
|
||||||
if (m_extension_messages[extended_chat_message] == -1) return;
|
if (m_extension_messages[extended_chat_message] == -1) return;
|
||||||
|
|
||||||
entry e(entry::dictionary_t);
|
entry e(entry::dictionary_t);
|
||||||
e.dict()["msg"] = msg;
|
e["msg"] = msg;
|
||||||
|
|
||||||
std::vector<char> message;
|
std::vector<char> message;
|
||||||
bencode(std::back_inserter(message), e);
|
bencode(std::back_inserter(message), e);
|
||||||
|
@ -1182,7 +1181,7 @@ namespace libtorrent
|
||||||
|
|
||||||
for (int i = 0; i < num_supported_extensions; ++i)
|
for (int i = 0; i < num_supported_extensions; ++i)
|
||||||
{
|
{
|
||||||
extension_list.dict()[extension_names[i]] = i;
|
extension_list[extension_names[i]] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make room for message size
|
// make room for message size
|
||||||
|
|
|
@ -1069,13 +1069,13 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int num_blocks_per_piece = (int)rd.dict()["blocks per piece"].integer();
|
int num_blocks_per_piece = (int)rd["blocks per piece"].integer();
|
||||||
if (num_blocks_per_piece != info.piece_length() / torrent_ptr->block_size())
|
if (num_blocks_per_piece != info.piece_length() / torrent_ptr->block_size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// the unfinished pieces
|
// the unfinished pieces
|
||||||
|
|
||||||
entry::list_type& unfinished = rd.dict()["unfinished"].list();
|
entry::list_type& unfinished = rd["unfinished"].list();
|
||||||
|
|
||||||
std::vector<piece_picker::downloading_piece> tmp_unfinished;
|
std::vector<piece_picker::downloading_piece> tmp_unfinished;
|
||||||
tmp_unfinished.reserve(unfinished.size());
|
tmp_unfinished.reserve(unfinished.size());
|
||||||
|
@ -1085,11 +1085,11 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
piece_picker::downloading_piece p;
|
piece_picker::downloading_piece p;
|
||||||
|
|
||||||
p.index = (int)i->dict()["piece"].integer();
|
p.index = (int)(*i)["piece"].integer();
|
||||||
if (p.index < 0 || p.index >= info.num_pieces())
|
if (p.index < 0 || p.index >= info.num_pieces())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const std::string& bitmask = i->dict()["bitmask"].string();
|
const std::string& bitmask = (*i)["bitmask"].string();
|
||||||
|
|
||||||
const int num_bitmask_bytes = std::max(num_blocks_per_piece / 8, 1);
|
const int num_bitmask_bytes = std::max(num_blocks_per_piece / 8, 1);
|
||||||
if ((int)bitmask.size() != num_bitmask_bytes) return;
|
if ((int)bitmask.size() != num_bitmask_bytes) return;
|
||||||
|
|
|
@ -310,7 +310,7 @@ namespace libtorrent
|
||||||
ret["info-hash"] = std::string((char*)info_hash.begin(), (char*)info_hash.end());
|
ret["info-hash"] = std::string((char*)info_hash.begin(), (char*)info_hash.end());
|
||||||
|
|
||||||
ret["slots"] = entry(entry::list_t);
|
ret["slots"] = entry(entry::list_t);
|
||||||
entry::list_type& slots = ret.dict()["slots"].list();
|
entry::list_type& slots = ret["slots"].list();
|
||||||
std::copy(piece_index.begin(), piece_index.end(), std::back_inserter(slots));
|
std::copy(piece_index.begin(), piece_index.end(), std::back_inserter(slots));
|
||||||
|
|
||||||
const piece_picker& p = t->picker();
|
const piece_picker& p = t->picker();
|
||||||
|
@ -321,7 +321,7 @@ namespace libtorrent
|
||||||
// blocks per piece
|
// blocks per piece
|
||||||
int num_blocks_per_piece =
|
int num_blocks_per_piece =
|
||||||
static_cast<int>(t->torrent_file().piece_length()) / t->block_size();
|
static_cast<int>(t->torrent_file().piece_length()) / t->block_size();
|
||||||
ret.dict()["blocks per piece"] = num_blocks_per_piece;
|
ret["blocks per piece"] = num_blocks_per_piece;
|
||||||
|
|
||||||
// num unfinished pieces
|
// num unfinished pieces
|
||||||
int num_unfinished = (int)q.size();
|
int num_unfinished = (int)q.size();
|
||||||
|
@ -336,7 +336,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
if (i->finished_blocks.count() == 0) continue;
|
if (i->finished_blocks.count() == 0) continue;
|
||||||
|
|
||||||
entry::dictionary_type piece_struct;
|
entry piece_struct(entry::dictionary_t);
|
||||||
|
|
||||||
// the unfinished piece's index
|
// the unfinished piece's index
|
||||||
piece_struct["piece"] = i->index;
|
piece_struct["piece"] = i->index;
|
||||||
|
@ -381,7 +381,7 @@ namespace libtorrent
|
||||||
if (!i->second->is_local()) continue;
|
if (!i->second->is_local()) continue;
|
||||||
|
|
||||||
address ip = i->second->get_socket()->sender();
|
address ip = i->second->get_socket()->sender();
|
||||||
entry::dictionary_type peer;
|
entry peer(entry::dictionary_t);
|
||||||
peer["ip"] = ip.as_string();
|
peer["ip"] = ip.as_string();
|
||||||
peer["port"] = ip.port;
|
peer["port"] = ip.port;
|
||||||
peer_list.push_back(peer);
|
peer_list.push_back(peer);
|
||||||
|
|
|
@ -132,11 +132,11 @@ namespace libtorrent
|
||||||
void torrent_info::read_torrent_info(const entry& torrent_file)
|
void torrent_info::read_torrent_info(const entry& torrent_file)
|
||||||
{
|
{
|
||||||
// extract the url of the tracker
|
// extract the url of the tracker
|
||||||
const entry::dictionary_type& dict = torrent_file.dict();
|
// const entry::dictionary_type& dict = torrent_file.dict();
|
||||||
entry::dictionary_type::const_iterator i = dict.find("announce-list");
|
entry const* i = torrent_file.find_key("announce-list");
|
||||||
if (i != dict.end())
|
if (i)
|
||||||
{
|
{
|
||||||
const entry::list_type& l = i->second.list();
|
const entry::list_type& l = i->list();
|
||||||
for (entry::list_type::const_iterator j = l.begin(); j != l.end(); ++j)
|
for (entry::list_type::const_iterator j = l.begin(); j != l.end(); ++j)
|
||||||
{
|
{
|
||||||
const entry::list_type& ll = j->list();
|
const entry::list_type& ll = j->list();
|
||||||
|
@ -167,33 +167,33 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i = dict.find("announce");
|
i = torrent_file.find_key("announce");
|
||||||
if (i == dict.end()) throw invalid_torrent_file();
|
if (i == 0) throw invalid_torrent_file();
|
||||||
announce_entry e;
|
announce_entry e;
|
||||||
e.tier = 0;
|
e.tier = 0;
|
||||||
e.url = i->second.string();
|
e.url = i->string();
|
||||||
m_urls.push_back(e);
|
m_urls.push_back(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract creation date
|
// extract creation date
|
||||||
i = dict.find("creation date");
|
i = torrent_file.find_key("creation date");
|
||||||
if (i != dict.end() && i->second.type() == entry::int_t)
|
if (i != 0 && i->type() == entry::int_t)
|
||||||
{
|
{
|
||||||
m_creation_date
|
m_creation_date
|
||||||
= ptime(date(1970, Jan, 1))
|
= ptime(date(1970, Jan, 1))
|
||||||
+ seconds((long)i->second.integer());
|
+ seconds((long)i->integer());
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract comment
|
// extract comment
|
||||||
i = dict.find("comment");
|
i = torrent_file.find_key("comment");
|
||||||
if (i != dict.end() && i->second.type() == entry::string_t)
|
if (i != 0 && i->type() == entry::string_t)
|
||||||
{
|
{
|
||||||
m_comment = i->second.string();
|
m_comment = i->string();
|
||||||
}
|
}
|
||||||
|
|
||||||
i = dict.find("info");
|
i = torrent_file.find_key("info");
|
||||||
if (i == dict.end()) throw invalid_torrent_file();
|
if (i == 0) throw invalid_torrent_file();
|
||||||
entry info = i->second;
|
entry const& info = *i;
|
||||||
|
|
||||||
// encode the info-field in order to calculate it's sha1-hash
|
// encode the info-field in order to calculate it's sha1-hash
|
||||||
std::vector<char> buf;
|
std::vector<char> buf;
|
||||||
|
@ -209,8 +209,8 @@ namespace libtorrent
|
||||||
m_name = info["name"].string();
|
m_name = info["name"].string();
|
||||||
|
|
||||||
// extract file list
|
// extract file list
|
||||||
i = info.dict().find("files");
|
i = info.find_key("files");
|
||||||
if (i == info.dict().end())
|
if (i == 0)
|
||||||
{
|
{
|
||||||
// if there's no list of files, there has to be a length
|
// if there's no list of files, there has to be a length
|
||||||
// field.
|
// field.
|
||||||
|
@ -221,7 +221,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
extract_files(i->second.list(), m_files);
|
extract_files(i->list(), m_files);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate total size of all pieces
|
// calculate total size of all pieces
|
||||||
|
@ -241,7 +241,10 @@ namespace libtorrent
|
||||||
throw invalid_torrent_file();
|
throw invalid_torrent_file();
|
||||||
|
|
||||||
for (int i = 0; i < num_pieces; ++i)
|
for (int i = 0; i < num_pieces; ++i)
|
||||||
std::copy(hash_string.begin() + i*20, hash_string.begin() + (i+1)*20, m_piece_hash[i].begin());
|
std::copy(
|
||||||
|
hash_string.begin() + i*20
|
||||||
|
, hash_string.begin() + (i+1)*20
|
||||||
|
, m_piece_hash[i].begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<boost::posix_time::ptime>
|
boost::optional<boost::posix_time::ptime>
|
||||||
|
|
Loading…
Reference in New Issue