diff --git a/include/libtorrent/storage.hpp b/include/libtorrent/storage.hpp index 5e545186e..e56908c56 100755 --- a/include/libtorrent/storage.hpp +++ b/include/libtorrent/storage.hpp @@ -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); diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index ca5195a8b..83caf72a0 100755 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -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 diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 29066a3b6..cf2875622 100755 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -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(p.index); + error = "checksum mismatch on piece " + + boost::lexical_cast(p.index); return; } @@ -1978,62 +1979,21 @@ namespace libtorrent { namespace detail } // verify file sizes - - std::vector > 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( - 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(std::less(), _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(file_sizes.size()) + " actual: " - + boost::lexical_cast(info.num_files()) + ")"; - return; - } - - std::vector >::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(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; } diff --git a/src/storage.cpp b/src/storage.cpp index 59632263e..04fe4374a 100755 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -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 > 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( + 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(std::less() + , 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(file_sizes.size()) + " actual: " + + boost::lexical_cast(m_info.num_files()) + ")"; + return false; + } + + std::vector >::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(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();