*** empty log message ***

This commit is contained in:
Arvid Norberg 2004-11-18 22:33:50 +00:00
parent 0659b267cf
commit b29e378f22
17 changed files with 150 additions and 81 deletions

View File

@ -20,7 +20,7 @@ project torrent
<variant>release:<define>NDEBUG
<define>BOOST_ALL_NO_LIB
<define>_FILE_OFFSET_BITS=64
<library>/boost/thread//boost_thread/
<library>/boost/thread//boost_thread
<library>/boost/filesystem//boost_filesystem/<link>static
<library>/boost/date_time//boost_date_time/<link>static
<link>static

View File

@ -2193,7 +2193,7 @@ The file format is a bencoded dictionary containing the following fields:
| | greater than 4 megabytes, the block size will increase. |
| | |
+----------------------+--------------------------------------------------------------+
| ``slots`` | list of integers. The list mappes slots ti piece indices. It |
| ``slots`` | list of integers. The list mappes slots to piece indices. It |
| | tells which piece is on which slot. If piece index is -2 it |
| | means it is free, that there's no piece there. If it is -1, |
| | means the slot isn't allocated on disk yet. The pieces have |

View File

@ -23,5 +23,5 @@ exe make_torrent
;
stage bin : dump_torrent make_torrent simple_client client_test ;
stage . : dump_torrent make_torrent simple_client client_test ;

View File

@ -78,6 +78,7 @@ int main(int argc, char* argv[])
std::cout << "number of pieces: " << t.num_pieces() << "\n";
std::cout << "piece length: " << t.piece_length() << "\n";
std::cout << "info hash: " << t.info_hash() << "\n";
std::cout << "files:\n";
for (torrent_info::file_iterator i = t.begin_files();
i != t.end_files();

View File

@ -77,8 +77,7 @@ int main(int argc, char* argv[])
if (argc != 4)
{
std::cerr << "usage: make_torrent <output torrent-file> <announce url> <file or directory to create torrent from>\n\n"
"the torrent file will be written to stdout.\n";
std::cerr << "usage: make_torrent <output torrent-file> <announce url> <file or directory to create torrent from>\n";
return 1;
}
@ -112,7 +111,7 @@ int main(int argc, char* argv[])
t.set_creator(creator_str);
// create the torrent and print it to stdout
// create the torrent and print it to out
entry e = t.create_torrent();
libtorrent::bencode(std::ostream_iterator<char>(out), e);
}

View File

@ -57,10 +57,10 @@ namespace libtorrent
, tag_version(tag)
{
assert(id_string);
assert(major >= 0 && major < 10);
assert(minor >= 0 && minor < 10);
assert(revision >= 0 && revision < 10);
assert(tag >= 0 && tag < 10);
assert(major >= 0);
assert(minor >= 0);
assert(revision >= 0);
assert(tag >= 0);
assert(std::strlen(id_string) == 2);
id[0] = id_string[0];
id[1] = id_string[1];
@ -70,10 +70,10 @@ namespace libtorrent
{
std::stringstream s;
s << "-" << id[0] << id[1]
<< (int)major_version
<< (int)minor_version
<< (int)revision_version
<< (int)tag_version << "-";
<< version_to_char(major_version)
<< version_to_char(minor_version)
<< version_to_char(revision_version)
<< version_to_char(tag_version) << "-";
return s.str();
}
@ -83,6 +83,15 @@ namespace libtorrent
char revision_version;
char tag_version;
private:
char version_to_char(int v) const
{
if (v >= 0 && v < 10) return '0' + v;
else if (v >= 10) return 'A' + (v - 10);
assert(false);
}
};
}

View File

@ -145,8 +145,8 @@ namespace libtorrent
mutable boost::mutex m_mutex;
boost::condition m_cond;
// a list of all torrents that are currently checking
// their files (in separate threads)
// a list of all torrents that are currently in queue
// or checking their files
std::deque<piece_checker_data> m_torrents;
bool m_abort;
@ -260,7 +260,6 @@ namespace libtorrent
boost::shared_ptr<logger> m_logger;
#endif
};
}
struct http_settings;
@ -296,6 +295,8 @@ namespace libtorrent
~session();
std::vector<torrent_handle> get_torrents();
// all torrent_handles must be destructed before the session is destructed!
torrent_handle add_torrent(
entry const& metadata

View File

@ -33,6 +33,6 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef TORRENT_VERSION_HPP_INCLUDED
#define TORRENT_VERSION_HPP_INCLUDED
#define LIBTORRENT_VERSION "0.1.0.0"
#define LIBTORRENT_VERSION "0.9.0.0"
#endif

View File

@ -97,24 +97,21 @@ namespace libtorrent
// section 2.3
// some trackers seems to require that ' is escaped
// static const char unreserved_chars[] = "-_.!~*'()";
static const char unreserved_chars[] = "-_.!~*()";
static const char unreserved_chars[] = "-_.!~*()"
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
"0123456789";
std::stringstream ret;
ret << std::hex << std::setfill('0');
for (int i = 0; i < len; ++i)
{
if (std::isalnum(static_cast<unsigned char>(*str))
|| std::count(
if (std::count(
unreserved_chars
, unreserved_chars+sizeof(unreserved_chars)-1
, *str))
{
ret << *str;
}
else if (*str == ' ')
{
ret << '+';
}
else
{
ret << '%'

View File

@ -1710,7 +1710,8 @@ namespace libtorrent
// if we have an infinite ratio, just say we have downloaded
// much more than we have uploaded. And we'll keep uploading.
if (ratio == 0.f) return std::numeric_limits<int>::max();
if (ratio == 0.f)
return std::numeric_limits<size_type>::max();
return m_free_upload
+ static_cast<size_type>(m_statistics.total_payload_download() * ratio)

View File

@ -133,7 +133,7 @@ namespace libtorrent
}
}
#ifndef NDEBUG
// integrity_check();
integrity_check();
#endif
}
@ -368,7 +368,7 @@ namespace libtorrent
move(true, m_piece_map[index].peer_count, m_piece_map[index].index);
#ifndef NDEBUG
// integrity_check();
integrity_check();
#endif
}
@ -389,7 +389,7 @@ namespace libtorrent
move(m_piece_map[i].downloading, peer_count, index);
#ifndef NDEBUG
// integrity_check();
integrity_check();
#endif
return;
}
@ -403,7 +403,8 @@ namespace libtorrent
int index = m_piece_map[i].index;
assert(m_piece_map[i].peer_count > 0);
m_piece_map[i].peer_count--;
if (m_piece_map[i].peer_count > 0)
m_piece_map[i].peer_count--;
if (index == 0xffffff) return;
move(m_piece_map[i].downloading, peer_count, index);
@ -422,7 +423,7 @@ namespace libtorrent
assert(info_index != 0xffffff);
remove(m_piece_map[index].downloading, peer_count, info_index);
#ifndef NDEBUG
// integrity_check();
integrity_check();
#endif
}
@ -434,7 +435,7 @@ namespace libtorrent
assert(pieces.size() == m_piece_map.size());
#ifndef NDEBUG
// integrity_check();
integrity_check();
#endif
// free refers to pieces that are free to download, noone else
@ -581,7 +582,7 @@ namespace libtorrent
void piece_picker::mark_as_downloading(piece_block block, const address& peer)
{
#ifndef NDEBUG
// integrity_check();
integrity_check();
#endif
assert(block.piece_index >= 0);
assert(block.block_index >= 0);
@ -610,14 +611,14 @@ namespace libtorrent
i->requested_blocks[block.block_index] = 1;
}
#ifndef NDEBUG
// integrity_check();
integrity_check();
#endif
}
void piece_picker::mark_as_finished(piece_block block, const address& peer)
{
#ifndef NDEBUG
// integrity_check();
integrity_check();
#endif
assert(block.piece_index >= 0);
assert(block.block_index >= 0);
@ -647,7 +648,7 @@ namespace libtorrent
i->finished_blocks[block.block_index] = 1;
}
#ifndef NDEBUG
// integrity_check();
integrity_check();
#endif
}
/*
@ -716,7 +717,7 @@ namespace libtorrent
void piece_picker::abort_download(piece_block block)
{
#ifndef NDEBUG
// integrity_check();
integrity_check();
#endif
assert(block.piece_index >= 0);
@ -751,7 +752,7 @@ namespace libtorrent
move(true, m_piece_map[block.piece_index].peer_count, m_piece_map[block.piece_index].index);
}
#ifndef NDEBUG
// integrity_check();
integrity_check();
#endif
}

View File

@ -237,9 +237,10 @@ namespace
{
// if the peer is interested in us, it means it may
// want to trade it's surplus uploads for downloads itself
// (and we should consider it free). If the share diff is
// (and we should not consider it free). If the share diff is
// negative, there's no free download to get from this peer.
size_type diff = i->second->share_diff();
assert(diff < std::numeric_limits<size_type>::max());
if (i->second->is_peer_interested() || diff <= 0)
continue;
@ -265,7 +266,9 @@ namespace
size_type total_diff = 0;
for (torrent::peer_iterator i = start; i != end; ++i)
{
total_diff += i->second->share_diff();
size_type d = i->second->share_diff();
assert(d < std::numeric_limits<size_type>::max());
total_diff += d;
if (!i->second->is_peer_interested() || i->second->share_diff() >= 0) continue;
++num_peers;
}
@ -481,14 +484,18 @@ namespace libtorrent
// first choice candidate.
// it is a candidate we owe nothing to and which has been unchoked
// the longest.
using namespace boost::posix_time;
using namespace boost::gregorian;
peer* candidate = 0;
boost::posix_time::ptime last_unchoke // not valid when candidate==0
= boost::posix_time::ptime(boost::posix_time::ptime(boost::gregorian::date(1970, boost::gregorian::Jan, 1)));
// not valid when candidate == 0
ptime last_unchoke = ptime(date(1970, Jan, 1));
// second choice candidate.
// if there is no first choice candidate, this candidate will be chosen.
// it is the candidate that we owe the least to.
peer* secondCandidate = 0;
peer* second_candidate = 0;
size_type lowest_share_diff = 0; // not valid when secondCandidate==0
for (std::vector<peer>::iterator i = m_peers.begin();
@ -502,14 +509,14 @@ namespace libtorrent
if (c->is_choked()) continue;
size_type share_diff=c->share_diff();
size_type share_diff = c->share_diff();
// select as second candidate the one that we owe the least
// to
if(!secondCandidate || share_diff <= lowest_share_diff)
if(!second_candidate || share_diff <= lowest_share_diff)
{
lowest_share_diff = share_diff;
secondCandidate=&(*i);
second_candidate = &(*i);
}
// select as first candidate the one that we don't owe anything to
@ -521,8 +528,8 @@ namespace libtorrent
candidate = &(*i);
}
}
if(candidate) return candidate;
if(secondCandidate) return secondCandidate;
if (candidate) return candidate;
if (second_candidate) return second_candidate;
assert(false);
return 0;
}
@ -700,22 +707,25 @@ namespace libtorrent
// ----------------------------
else
{
// choke peers that have leeched too much without giving anything back
for (std::vector<peer>::iterator i = m_peers.begin();
i != m_peers.end();
++i)
if (m_torrent->ratio() != 0)
{
peer_connection* c = i->connection;
if (c == 0) continue;
size_type diff = i->connection->share_diff();
if (diff < -free_upload_amount
&& !c->is_choked())
// choke peers that have leeched too much without giving anything back
for (std::vector<peer>::iterator i = m_peers.begin();
i != m_peers.end();
++i)
{
// if we have uploaded more than a piece for free, choke peer and
// wait until we catch up with our download.
c->send_choke();
--m_num_unchoked;
peer_connection* c = i->connection;
if (c == 0) continue;
size_type diff = i->connection->share_diff();
if (diff < -free_upload_amount
&& !c->is_choked())
{
// if we have uploaded more than a piece for free, choke peer and
// wait until we catch up with our download.
c->send_choke();
--m_num_unchoked;
}
}
}
@ -969,7 +979,7 @@ namespace libtorrent
{
if (m_torrent->ratio() != 0.f)
{
assert(c.share_diff() < std::numeric_limits<int>::max());
assert(c.share_diff() < std::numeric_limits<size_type>::max());
size_type diff = c.share_diff();
if (diff > 0 && c.is_seed())
{
@ -1076,7 +1086,8 @@ namespace libtorrent
// because it isn't necessary.
if (m_torrent->ratio() != 0.f)
{
assert(i->connection->share_diff() < std::numeric_limits<int>::max());
assert(i->connection->associated_torrent() == m_torrent);
assert(i->connection->share_diff() < std::numeric_limits<size_type>::max());
m_available_free_upload += i->connection->share_diff();
}
i->prev_amount_download += c.statistics().total_payload_download();

View File

@ -662,6 +662,7 @@ namespace libtorrent { namespace detail
if (t.is_aborted())
{
tracker_request req = t.generate_tracker_request();
assert(req.event == tracker_request::stopped);
req.listen_port = m_listen_interface.port;
req.key = m_key;
m_tracker_manager.queue_request(req);
@ -876,6 +877,35 @@ namespace libtorrent
m_impl.m_extension_enabled[i] = true;
}
std::vector<torrent_handle> session::get_torrents()
{
std::vector<torrent_handle> ret;
{
boost::mutex::scoped_lock l(m_checker_impl.m_mutex);
for (std::deque<detail::piece_checker_data>::iterator i
= m_checker_impl.m_torrents.begin()
, end(m_checker_impl.m_torrents.end()); i != end; ++i)
{
ret.push_back(torrent_handle(&m_impl, &m_checker_impl
, i->info_hash));
}
}
{
boost::mutex::scoped_lock l(m_impl.m_mutex);
for (detail::session_impl::torrent_map::iterator i
= m_impl.m_torrents.begin(), end(m_impl.m_torrents.end());
i != end; ++i)
{
if (i->second->is_aborted()) continue;
ret.push_back(torrent_handle(&m_impl, &m_checker_impl
, i->first));
}
}
return ret;
}
// TODO: add a check to see if filenames are accepted on the
// current platform.
// if the torrent already exists, this will throw duplicate_torrent
@ -1270,6 +1300,25 @@ namespace libtorrent
, std::back_inserter(file_sizes)
, boost::bind((mem_fun_type)&entry::integer, _1));
#endif
if (tmp_pieces.size() == info.num_pieces()
&& std::find_if(tmp_pieces.begin(), tmp_pieces.end()
, boost::bind(std::less<int>(), _1, 0)) == tmp_pieces.end())
{
if (info.num_files() != file_sizes.size())
return;
std::vector<size_type>::iterator fs = file_sizes.begin();
// the resume data says we have the entire torrent
// make sure the file sizes are the right ones
for (torrent_info::file_iterator i = info.begin_files()
, end(info.end_files()); i != end; ++i, ++fs)
{
if (i->size != *fs) return;
}
}
if (!match_filesizes(info, save_path, file_sizes))
return;

View File

@ -254,7 +254,8 @@ namespace libtorrent
}
int ret = std::rename(old_path.c_str(), new_path.c_str());
if (ret == 0)
// This seems to return -1 even when it successfully moves the file
// if (ret == 0)
{
m_pimpl->save_path = save_path;
return true;
@ -522,11 +523,9 @@ namespace libtorrent
bool move_storage(path save_path)
{
m_save_path = complete(save_path);
if (m_storage.move_storage(save_path))
{
m_save_path = save_path;
m_save_path = complete(save_path);
return true;
}
return false;

View File

@ -240,6 +240,8 @@ namespace libtorrent
void torrent::init()
{
assert(m_torrent_file.is_valid());
assert(m_torrent_file.num_files() > 0);
assert(m_torrent_file.total_size() > 0);
m_have_pieces.resize(m_torrent_file.num_pieces(), false);
m_storage = std::auto_ptr<piece_manager>(new piece_manager(m_torrent_file, m_save_path));
@ -542,6 +544,7 @@ namespace libtorrent
req.left = bytes_left();
if (req.left == -1) req.left = 1000;
req.event = m_event;
m_event = tracker_request::none;
req.url = m_trackers[m_currently_trying_tracker].url;
req.num_want = std::max(
(m_connections_quota.given
@ -743,7 +746,9 @@ namespace libtorrent
bool torrent::move_storage(boost::filesystem::path const& save_path)
{
return m_storage->move_storage(save_path);
bool ret = m_storage->move_storage(save_path);
m_save_path = m_storage->save_path();
return ret;
}
piece_manager& torrent::filesystem()

View File

@ -197,6 +197,8 @@ namespace libtorrent
{
INVARIANT_CHECK;
assert(max_connections >= 2 || max_connections == -1);
call_member<void>(m_ses, m_chk, m_info_hash
, bind(&torrent::set_max_connections, _1, max_connections));
}

View File

@ -293,20 +293,14 @@ namespace libtorrent
parse_info_section(info);
}
boost::optional<boost::posix_time::ptime>
boost::optional<ptime>
torrent_info::creation_date() const
{
if (m_creation_date !=
boost::posix_time::ptime(
boost::gregorian::date(
boost::date_time::not_a_date_time)))
if (m_creation_date != ptime(date(not_a_date_time)))
{
return boost::optional<boost::posix_time::ptime>(m_creation_date);
return boost::optional<ptime>(m_creation_date);
}
// if there's no timestamp in the torrent file, this will return a date of january 1:st 1970.
boost::optional<boost::posix_time::ptime> pt(boost::gregorian::date(1970,1,1));
return pt;
return boost::optional<ptime>();
}
void torrent_info::add_tracker(std::string const& url, int tier)
@ -515,8 +509,8 @@ namespace libtorrent
}
if (!m_comment.empty())
os << "comment: " << m_comment << "\n";
if (m_creation_date != boost::posix_time::ptime(boost::gregorian::date(1970, boost::gregorian::Jan, 1)))
os << "creation date: " << boost::posix_time::to_simple_string(m_creation_date) << "\n";
if (m_creation_date != ptime(date(not_a_date_time)))
os << "creation date: " << to_simple_string(m_creation_date) << "\n";
os << "number of pieces: " << num_pieces() << "\n";
os << "piece length: " << piece_length() << "\n";
os << "files:\n";