diff --git a/examples/client_test.cpp b/examples/client_test.cpp index c3b462cb1..fa5f328da 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -1024,7 +1024,7 @@ bool handle_alert(libtorrent::session& ses, libtorrent::alert* a save_file(filename, buffer); files.insert(std::pair(filename, h)); - hash_to_filename.insert(std::make_pair(hash, filename)); + hash_to_filename[hash] = filename; non_files.erase(h); } } diff --git a/src/storage.cpp b/src/storage.cpp index 18cd4f641..64091f732 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -515,9 +515,9 @@ namespace libtorrent // don't do full file allocations on network drives #if TORRENT_USE_WSTRING std::wstring f = convert_to_wstring(m_save_path); - int drive_type = GetDriveTypeW(f.c_str()); + int const drive_type = GetDriveTypeW(f.c_str()); #else - int drive_type = GetDriveTypeA(m_save_path.c_str()); + int const drive_type = GetDriveTypeA(m_save_path.c_str()); #endif if (drive_type == DRIVE_REMOTE) @@ -581,7 +581,7 @@ namespace libtorrent | file::random_access, ec); if (ec) return; - boost::int64_t size = files().file_size(file_index); + boost::int64_t const size = files().file_size(file_index); f->set_size(size, ec.ec); if (ec) { @@ -589,7 +589,7 @@ namespace libtorrent ec.operation = storage_error::fallocate; break; } - size_t mtime = m_stat_cache.get_filetime(file_index); + size_t const mtime = m_stat_cache.get_filetime(file_index); m_stat_cache.set_cache(file_index, size, mtime); } ec.ec.clear(); @@ -621,12 +621,15 @@ namespace libtorrent file_path = files().file_path(i, m_save_path); stat_file(file_path, &s, ec.ec); boost::int64_t r = s.file_size; - if (ec.ec || !(s.mode & file_status::regular_file)) r = -1; + if (ec.ec || !(s.mode & file_status::regular_file)) + { + r = stat_cache::cache_error; + } if (ec && ec.ec == boost::system::errc::no_such_file_or_directory) { ec.ec.clear(); - r = -3; + r = stat_cache::no_exist; } m_stat_cache.set_cache(i, r, s.mtime); @@ -865,7 +868,7 @@ namespace libtorrent { boost::int64_t file_size = 0; time_t file_time = 0; - boost::int64_t cache_state = m_stat_cache.get_filesize(i); + boost::int64_t const cache_state = m_stat_cache.get_filesize(i); if (cache_state != stat_cache::not_in_cache) { if (cache_state >= 0) @@ -883,6 +886,7 @@ namespace libtorrent { file_size = s.file_size; file_time = s.mtime; + m_stat_cache.set_cache(i, file_size, file_time); } else if (error == error_code(boost::system::errc::no_such_file_or_directory , generic_category())) @@ -897,6 +901,21 @@ namespace libtorrent m_stat_cache.set_error(i); } } +#if TORRENT_USE_INVARIANT_CHECKS + { + file_status s; + error_code error; + stat_file(fs.file_path(i, m_save_path), &s, error); + if (s.file_size >= 0 && !error) + { + TORRENT_ASSERT(s.file_size == file_size); + } + else + { + TORRENT_ASSERT(file_size == 0); + } + } +#endif fl.push_back(entry(entry::list_t)); entry::list_type& p = fl.back().list(); @@ -1454,7 +1473,8 @@ namespace libtorrent if (m_file_created[file] == false) { error_code e; - h->set_size(files().file_size(file), e); + boost::int64_t const size = files().file_size(file); + h->set_size(size, e); m_file_created.set_bit(file); if (e) { @@ -1463,6 +1483,7 @@ namespace libtorrent ec.operation = storage_error::fallocate; return h; } + m_stat_cache.set_dirty(file); } } return h; diff --git a/test/test_resume.cpp b/test/test_resume.cpp index 4f6ef334f..de871d33a 100644 --- a/test/test_resume.cpp +++ b/test/test_resume.cpp @@ -192,6 +192,63 @@ void default_tests(torrent_status const& s) TEST_EQUAL(s.completed_time, 1348); } +void test_file_sizes(bool allocate) +{ + error_code ec; + remove_all("test_resume", ec); + + lt::settings_pack pack = settings(); + // we're not testing the hash check, just accept the data we write + pack.set_bool(settings_pack::disable_hash_checks, true); + lt::session ses(pack); + boost::shared_ptr ti = generate_torrent(); + add_torrent_params p; + p.ti = ti; + p.save_path = "."; + if (allocate) p.storage_mode = storage_mode_allocate; + torrent_handle h = ses.add_torrent(p); + + wait_for_downloading(ses, "ses"); + + std::vector piece(ti->piece_length(), 0); + h.add_piece(0, piece.data()); + + h.save_resume_data(); + alert const* a = wait_for_alert(ses, save_resume_data_alert::alert_type); + TEST_CHECK(a); + + save_resume_data_alert const* ra = alert_cast(a); + TEST_CHECK(ra); + if (ra) + { + fprintf(stderr, "%s\n", ra->resume_data->to_string().c_str()); + bool const has_file_sizes = ra->resume_data->dict().count("file sizes") == 1; + TEST_CHECK(has_file_sizes); + if (!has_file_sizes) return; + // { 'file sizes': [ [ size, timestamp], [...], ... ] } + boost::int64_t const file_size = (*ra->resume_data)["file sizes"].list() + .front().list().front().integer(); + if (allocate) + { + TEST_EQUAL(file_size, ti->files().file_size(0)); + } + else + { + TEST_EQUAL(file_size, ti->piece_length()); + } + } +} + +TORRENT_TEST(file_sizes_allocate) +{ + test_file_sizes(true); +} + +TORRENT_TEST(file_sizes) +{ + test_file_sizes(false); +} + TORRENT_TEST(piece_priorities) { lt::session ses(settings()); @@ -208,7 +265,9 @@ TORRENT_TEST(piece_priorities) alert const* a = wait_for_alert(ses, save_resume_data_alert::alert_type); TEST_CHECK(a); - if (save_resume_data_alert const* ra = alert_cast(a)) + save_resume_data_alert const* ra = alert_cast(a); + TEST_CHECK(ra); + if (ra) { fprintf(stderr, "%s\n", ra->resume_data->to_string().c_str()); entry::string_type prios = (*ra->resume_data)["piece_priority"].string();