moved the resume data verification to the storage, since the storage may map the files differently. The creation of resume data should probably also be moved there

This commit is contained in:
Arvid Norberg 2007-03-27 23:49:05 +00:00
parent 3972e9ef55
commit 72fd437ff0
4 changed files with 72 additions and 47 deletions

View File

@ -97,6 +97,8 @@ namespace libtorrent
virtual bool move_storage(boost::filesystem::path save_path) = 0;
virtual bool verify_resume_data(entry& rd, std::string& error) = 0;
// this will close all open files that are opened for
// writing. This is called when a torrent has finished
// downloading.
@ -130,6 +132,8 @@ namespace libtorrent
void release_files();
bool verify_resume_data(entry& rd, std::string& error);
bool is_allocating() const;
void allocate_slots(int num_slots);
void mark_failed(int index);

View File

@ -145,7 +145,10 @@ namespace libtorrent
aux::session_impl& session() { return m_ses; }
void set_sequenced_download_threshold(int threshold);
bool verify_resume_data(entry& rd, std::string& error)
{ assert(m_storage); return m_storage->verify_resume_data(rd, error); }
// is called every second by session. This will
// caclulate the upload/download and number
// of connections this torrent needs. And prepare

View File

@ -1969,7 +1969,8 @@ namespace libtorrent { namespace detail
// crc's didn't match, don't use the resume data
if (ad.integer() != entry::integer_type(adler))
{
error = "checksum mismatch on piece " + boost::lexical_cast<std::string>(p.index);
error = "checksum mismatch on piece "
+ boost::lexical_cast<std::string>(p.index);
return;
}
@ -1978,62 +1979,21 @@ namespace libtorrent { namespace detail
}
// verify file sizes
std::vector<std::pair<size_type, std::time_t> > file_sizes;
entry::list_type& l = rd["file sizes"].list();
for (entry::list_type::iterator i = l.begin();
i != l.end(); ++i)
{
file_sizes.push_back(std::pair<size_type, std::time_t>(
i->list().front().integer()
, i->list().back().integer()));
}
if ((int)tmp_pieces.size() == info.num_pieces()
&& std::find_if(tmp_pieces.begin(), tmp_pieces.end()
, boost::bind<bool>(std::less<int>(), _1, 0)) == tmp_pieces.end())
{
if (info.num_files() != (int)file_sizes.size())
{
error = "the number of files does not match the torrent (num: "
+ boost::lexical_cast<std::string>(file_sizes.size()) + " actual: "
+ boost::lexical_cast<std::string>(info.num_files()) + ")";
return;
}
std::vector<std::pair<size_type, std::time_t> >::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->first)
{
error = "file size for '" + i->path.native_file_string() + "' was expected to be "
+ boost::lexical_cast<std::string>(i->size) + " bytes";
return;
}
}
}
if (!match_filesizes(info, save_path, file_sizes, &error))
if (!torrent_ptr->verify_resume_data(rd, error))
return;
piece_map.swap(tmp_pieces);
unfinished_pieces.swap(tmp_unfinished);
}
catch (invalid_encoding)
catch (invalid_encoding&)
{
return;
}
catch (type_error)
catch (type_error&)
{
return;
}
catch (file_error)
catch (file_error&)
{
return;
}

View File

@ -362,6 +362,8 @@ namespace libtorrent
size_type read(char* buf, int slot, int offset, int size);
void write(const char* buf, int slot, int offset, int size);
bool verify_resume_data(entry& rd, std::string& error);
~storage()
{
m_files.release(this);
@ -380,6 +382,57 @@ namespace libtorrent
m_files.release(this);
}
bool storage::verify_resume_data(entry& rd, std::string& error)
{
std::vector<std::pair<size_type, std::time_t> > file_sizes;
entry::list_type& l = rd["file sizes"].list();
for (entry::list_type::iterator i = l.begin();
i != l.end(); ++i)
{
file_sizes.push_back(std::pair<size_type, std::time_t>(
i->list().front().integer()
, i->list().back().integer()));
}
entry::list_type& slots = rd["slots"].list();
bool seed = int(slots.size()) == m_info.num_pieces()
&& std::find_if(slots.begin(), slots.end()
, boost::bind<bool>(std::less<int>()
, boost::bind((size_type const& (entry::*)() const)
&entry::integer, _1), 0)) == slots.end();
if (seed)
{
if (m_info.num_files() != (int)file_sizes.size())
{
error = "the number of files does not match the torrent (num: "
+ boost::lexical_cast<std::string>(file_sizes.size()) + " actual: "
+ boost::lexical_cast<std::string>(m_info.num_files()) + ")";
return false;
}
std::vector<std::pair<size_type, std::time_t> >::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 = m_info.begin_files()
, end(m_info.end_files()); i != end; ++i, ++fs)
{
if (i->size != fs->first)
{
error = "file size for '" + i->path.native_file_string()
+ "' was expected to be "
+ boost::lexical_cast<std::string>(i->size) + " bytes";
return false;
}
}
return true;
}
return match_filesizes(m_info, m_save_path, file_sizes, &error);
}
// returns true on success
bool storage::move_storage(path save_path)
{
@ -884,6 +937,11 @@ namespace libtorrent
{
}
bool piece_manager::verify_resume_data(entry& rd, std::string& error)
{
return m_pimpl->m_storage->verify_resume_data(rd, error);
}
void piece_manager::release_files()
{
m_pimpl->release_files();