From 3bd53f88ef7aeee88e13d8ab6522ff8f92d4ba7b Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Mon, 12 Aug 2013 07:30:57 +0000 Subject: [PATCH] fix build with internal_file_entry being deprecated without deprecated functions --- include/libtorrent/file_pool.hpp | 2 +- include/libtorrent/file_storage.hpp | 41 ++++++- include/libtorrent/storage.hpp | 2 +- include/libtorrent/torrent_info.hpp | 23 ++-- src/create_torrent.cpp | 38 +++---- src/file_pool.cpp | 10 +- src/file_storage.cpp | 83 ++++++++++---- src/storage.cpp | 167 +++++++++++++--------------- src/torrent.cpp | 86 +++++++------- src/torrent_info.cpp | 19 ++-- src/web_peer_connection.cpp | 12 +- test/test_storage.cpp | 2 +- test/test_torrent_parse.cpp | 30 ++--- test/test_web_seed.cpp | 3 +- 14 files changed, 288 insertions(+), 230 deletions(-) diff --git a/include/libtorrent/file_pool.hpp b/include/libtorrent/file_pool.hpp index 7ddb69b59..ae86df780 100644 --- a/include/libtorrent/file_pool.hpp +++ b/include/libtorrent/file_pool.hpp @@ -57,7 +57,7 @@ namespace libtorrent ~file_pool(); boost::intrusive_ptr open_file(void* st, std::string const& p - , file_storage::iterator fe, file_storage const& fs, int m, error_code& ec); + , int file_index, file_storage const& fs, int m, error_code& ec); void release(void* st); void release(void* st, int file_index); void resize(int size); diff --git a/include/libtorrent/file_storage.hpp b/include/libtorrent/file_storage.hpp index c20d9797d..e69ac892d 100644 --- a/include/libtorrent/file_storage.hpp +++ b/include/libtorrent/file_storage.hpp @@ -101,10 +101,15 @@ namespace libtorrent std::string symlink_path; }; + // only export this type if deprecated functions are enabled +#ifdef TORRENT_NO_DEPRECATED +#define TORRENT_DEPRECATED_EXPORT +#else +#define TORRENT_DEPRECATED_EXPORT TORRENT_EXPORT +#endif // internal - struct TORRENT_EXPORT internal_file_entry + struct TORRENT_DEPRECATED_EXPORT internal_file_entry { - // TODO: does this really need to be exported? friend class file_storage; #ifdef TORRENT_DEBUG // for torrent_info::invariant_check @@ -249,6 +254,12 @@ namespace libtorrent void rename_file(int index, std::string const& new_filename); + // this is a low-level function that sets the name of a file + // by making it reference a buffer that is not owned by the file_storage. + // it's an optimization used when loading .torrent files, to not + // duplicate names in memory. + void rename_file_borrow(int index, char const* new_filename, int len); + #if TORRENT_USE_WSTRING // all wstring APIs are deprecated since 0.16.11 // instead, use the wchar -> utf8 conversion functions @@ -267,7 +278,7 @@ namespace libtorrent std::vector map_block(int piece, size_type offset , int size) const; peer_request map_file(int file, size_type offset, int size) const; - + #ifndef TORRENT_NO_DEPRECATE // all functions depending on internal_file_entry // were deprecated in 1.0. Use the variants that take an @@ -292,13 +303,14 @@ namespace libtorrent TORRENT_ASSERT(index < int(m_files.size())); return m_files[index]; } + TORRENT_DEPRECATED_PREFIX + file_entry at(iterator i) const TORRENT_DEPRECATED; #endif // TORRENT_NO_DEPRECATE int num_files() const { return int(m_files.size()); } file_entry at(int index) const; - file_entry at(iterator i) const; size_type total_size() const { return m_total_size; } void set_num_pieces(int n) { m_num_pieces = n; } @@ -364,6 +376,18 @@ namespace libtorrent bool pad_file_at(int index) const; size_type file_offset(int index) const; + enum file_flags_t + { + flag_pad_file = 1, + flag_hidden = 2, + flag_executable = 4, + flag_symlink = 8, + }; + + // returns a bitmask of flags from file_flags_t that apply + // to file at ``index``. + int file_flags(int index) const; + // The file base of a file is the offset within the file on the filsystem // where it starts to write. For the most part, this is always 0. It's // possible to map several files (in the torrent) into a single file on @@ -373,6 +397,15 @@ namespace libtorrent size_type file_base(int index) const; void set_file_base(int index, size_type off); + // returns the index of the file at the given offset in the torrent + int file_index_at_offset(size_type offset) const; + + // low-level function. returns a pointer to the internal storage for + // the filename. This string may not be null terinated! + // the ``file_name_len()`` function returns the length of the filename. + char const* file_name_ptr(int index) const; + int file_name_len(int index) const; + #ifndef TORRENT_NO_DEPRECATE // these were deprecated in 1.0. Use the versions that take an index instead TORRENT_DEPRECATED_PREFIX diff --git a/include/libtorrent/storage.hpp b/include/libtorrent/storage.hpp index ef2f163b9..2f29d4bd4 100644 --- a/include/libtorrent/storage.hpp +++ b/include/libtorrent/storage.hpp @@ -431,7 +431,7 @@ namespace libtorrent file_storage const& m_files; // helper function to open a file in the file pool with the right mode - boost::intrusive_ptr open_file(file_storage::iterator fe, int mode + boost::intrusive_ptr open_file(int file, int mode , error_code& ec) const; std::vector m_file_priority; diff --git a/include/libtorrent/torrent_info.hpp b/include/libtorrent/torrent_info.hpp index 93c524870..afa1cc627 100644 --- a/include/libtorrent/torrent_info.hpp +++ b/include/libtorrent/torrent_info.hpp @@ -437,6 +437,9 @@ namespace libtorrent const sha1_hash& info_hash() const { return m_info_hash; } +#ifndef TORRENT_NO_DEPRECATE + // deprecated in 1.0. Use the variants that take an index instead + // internal_file_entry is no longer exposed in the API typedef file_storage::iterator file_iterator; typedef file_storage::reverse_iterator reverse_file_iterator; @@ -447,19 +450,25 @@ namespace libtorrent // // You can resolve it into the public representation of a file (``file_entry``) // using the ``file_storage::at`` function, which takes an index and an iterator. - file_iterator begin_files() const { return m_files.begin(); } - file_iterator end_files() const { return m_files.end(); } - reverse_file_iterator rbegin_files() const { return m_files.rbegin(); } - reverse_file_iterator rend_files() const { return m_files.rend(); } + TORRENT_DEPRECATED_PREFIX + file_iterator begin_files() const TORRENT_DEPRECATED { return m_files.begin(); } + TORRENT_DEPRECATED_PREFIX + file_iterator end_files() const TORRENT_DEPRECATED { return m_files.end(); } + reverse_file_iterator rbegin_files() const TORRENT_DEPRECATED { return m_files.rbegin(); } + TORRENT_DEPRECATED_PREFIX + reverse_file_iterator rend_files() const TORRENT_DEPRECATED { return m_files.rend(); } + + TORRENT_DEPRECATED_PREFIX + file_iterator file_at_offset(size_type offset) const TORRENT_DEPRECATED + { return m_files.file_at_offset(offset); } + +#endif // TORRENT_NO_DEPRECATE // If you need index-access to files you can use the ``num_files()`` and ``file_at()`` // to access files using indices. int num_files() const { return m_files.num_files(); } file_entry file_at(int index) const { return m_files.at(index); } - file_iterator file_at_offset(size_type offset) const - { return m_files.file_at_offset(offset); } - // This function will map a piece index, a byte offset within that piece and // a size (in bytes) into the corresponding files with offsets where that data // for that piece is supposed to be stored. See file_slice. diff --git a/src/create_torrent.cpp b/src/create_torrent.cpp index 5fa8f056c..f25b57043 100644 --- a/src/create_torrent.cpp +++ b/src/create_torrent.cpp @@ -273,7 +273,7 @@ namespace libtorrent // return instead of crash in release mode if (fs.num_files() == 0) return; - if (!m_multifile && has_parent_path(m_files.file_path(*m_files.begin()))) m_multifile = true; + if (!m_multifile && has_parent_path(m_files.file_path(0))) m_multifile = true; // a piece_size of 0 means automatic if (piece_size == 0 && !m_merkle_torrent) @@ -493,49 +493,45 @@ namespace libtorrent { entry& files = info["files"]; - for (file_storage::iterator i = m_files.begin(); - i != m_files.end(); ++i) + for (int i = 0; i < m_files.num_files(); ++i) { files.list().push_back(entry()); entry& file_e = files.list().back(); - if (m_include_mtime && m_files.mtime(*i)) file_e["mtime"] = m_files.mtime(*i); - file_e["length"] = i->size; + if (m_include_mtime && m_files.mtime(i)) file_e["mtime"] = m_files.mtime(i); + file_e["length"] = m_files.file_size(i); entry& path_e = file_e["path"]; - TORRENT_ASSERT(has_parent_path(m_files.file_path(*i))); + TORRENT_ASSERT(has_parent_path(m_files.file_path(i))); - std::string split = split_path(m_files.file_path(*i)); + std::string split = split_path(m_files.file_path(i)); TORRENT_ASSERT(split.c_str() == m_files.name()); for (char const* e = next_path_element(split.c_str()); e != 0; e = next_path_element(e)) path_e.list().push_back(entry(e)); - if (i->pad_file - || i->hidden_attribute - || i->executable_attribute - || i->symlink_attribute) + int flags = m_files.file_flags(i); + if (flags != 0) { std::string& attr = file_e["attr"].string(); - if (i->pad_file) attr += 'p'; - if (i->hidden_attribute) attr += 'h'; - if (i->executable_attribute) attr += 'x'; - if (m_include_symlinks && i->symlink_attribute) attr += 'l'; + if (flags & file_storage::flag_pad_file) attr += 'p'; + if (flags & file_storage::flag_hidden) attr += 'h'; + if (flags & file_storage::flag_executable) attr += 'x'; + if (m_include_symlinks && (flags & file_storage::flag_symlink)) attr += 'l'; } + if (m_include_symlinks - && i->symlink_attribute - && i->symlink_index != -1) + && (flags & file_storage::flag_symlink)) { entry& sympath_e = file_e["symlink path"]; - std::string split = split_path(m_files.symlink(*i)); + std::string split = split_path(m_files.symlink(i)); for (char const* e = split.c_str(); e != 0; e = next_path_element(e)) sympath_e.list().push_back(entry(e)); } - int file_index = i - m_files.begin(); - if (!m_filehashes.empty() && m_filehashes[file_index] != sha1_hash()) + if (!m_filehashes.empty() && m_filehashes[i] != sha1_hash()) { - file_e["sha1"] = m_filehashes[file_index].to_string(); + file_e["sha1"] = m_filehashes[i].to_string(); } } } diff --git a/src/file_pool.cpp b/src/file_pool.cpp index d68aa7a5b..91675dcd0 100644 --- a/src/file_pool.cpp +++ b/src/file_pool.cpp @@ -169,14 +169,14 @@ namespace libtorrent #endif // TORRENT_WINDOWS boost::intrusive_ptr file_pool::open_file(void* st, std::string const& p - , file_storage::iterator fe, file_storage const& fs, int m, error_code& ec) + , int file_index, file_storage const& fs, int m, error_code& ec) { TORRENT_ASSERT(st != 0); TORRENT_ASSERT(is_complete(p)); TORRENT_ASSERT((m & file::rw_mask) == file::read_only || (m & file::rw_mask) == file::read_write); mutex::scoped_lock l(m_mutex); - file_set::iterator i = m_files.find(std::make_pair(st, fs.file_index(*fe))); + file_set::iterator i = m_files.find(std::make_pair(st, file_index)); if (i != m_files.end()) { lru_file_entry& e = i->second; @@ -214,7 +214,7 @@ namespace libtorrent #else e.file_ptr->close(); #endif - std::string full_path = fs.file_path(*fe, p); + std::string full_path = fs.file_path(file_index, p); if (!e.file_ptr->open(full_path, m, ec)) { m_files.erase(i); @@ -244,7 +244,7 @@ namespace libtorrent ec = error_code(ENOMEM, get_posix_category()); return e.file_ptr; } - std::string full_path = fs.file_path(*fe, p); + std::string full_path = fs.file_path(file_index, p); if (!e.file_ptr->open(full_path, m, ec)) return boost::intrusive_ptr(); #ifdef TORRENT_WINDOWS @@ -253,7 +253,7 @@ namespace libtorrent #endif e.mode = m; e.key = st; - m_files.insert(std::make_pair(std::make_pair(st, fs.file_index(*fe)), e)); + m_files.insert(std::make_pair(std::make_pair(st, file_index), e)); TORRENT_ASSERT(e.file_ptr->is_open()); return e.file_ptr; } diff --git a/src/file_storage.cpp b/src/file_storage.cpp index 923c43202..db89cdf21 100644 --- a/src/file_storage.cpp +++ b/src/file_storage.cpp @@ -200,6 +200,12 @@ namespace libtorrent update_path_index(m_files[index]); } + void file_storage::rename_file_borrow(int index, char const* new_filename, int len) + { + TORRENT_ASSERT(index >= 0 && index < int(m_files.size())); + m_files[index].set_name(new_filename, len); + } + namespace { bool compare_file_offset(internal_file_entry const& lhs, internal_file_entry const& rhs) @@ -208,6 +214,7 @@ namespace libtorrent } } +#ifndef TORRENT_NO_DEPRECATE file_storage::iterator file_storage::file_at_offset(size_type offset) const { // find the file iterator and file offset @@ -222,6 +229,32 @@ namespace libtorrent --file_iter; return file_iter; } +#endif + + int file_storage::file_index_at_offset(size_type offset) const + { + // find the file iterator and file offset + internal_file_entry target; + target.offset = offset; + TORRENT_ASSERT(!compare_file_offset(target, m_files.front())); + + std::vector::const_iterator file_iter = std::upper_bound( + m_files.begin(), m_files.end(), target, compare_file_offset); + + TORRENT_ASSERT(file_iter != m_files.begin()); + --file_iter; + return file_iter - m_files.begin(); + } + + char const* file_storage::file_name_ptr(int index) const + { + return m_files[index].name; + } + + int file_storage::file_name_len(int index) const + { + return m_files[index].name_len; + } std::vector file_storage::map_block(int piece, size_type offset , int size) const @@ -238,20 +271,20 @@ namespace libtorrent TORRENT_ASSERT(!compare_file_offset(target, m_files.front())); std::vector::const_iterator file_iter = std::upper_bound( - begin(), end(), target, compare_file_offset); + m_files.begin(), m_files.end(), target, compare_file_offset); - TORRENT_ASSERT(file_iter != begin()); + TORRENT_ASSERT(file_iter != m_files.begin()); --file_iter; size_type file_offset = target.offset - file_iter->offset; for (; size > 0; file_offset -= file_iter->size, ++file_iter) { - TORRENT_ASSERT(file_iter != end()); + TORRENT_ASSERT(file_iter != m_files.end()); if (file_offset < file_iter->size) { file_slice f; - f.file_index = file_iter - begin(); - f.offset = file_offset + file_base(*file_iter); + f.file_index = file_iter - m_files.begin(); + f.offset = file_offset + file_base(f.file_index); f.size = (std::min)(file_iter->size - file_offset, (size_type)size); TORRENT_ASSERT(f.size <= size); size -= int(f.size); @@ -264,25 +297,22 @@ namespace libtorrent return ret; } - file_entry file_storage::at(file_storage::iterator i) const - { return at(i - begin()); } - file_entry file_storage::at(int index) const { TORRENT_ASSERT(index >= 0 && index < int(m_files.size())); file_entry ret; internal_file_entry const& ife = m_files[index]; - ret.path = file_path(ife); + ret.path = file_path(index); ret.offset = ife.offset; ret.size = ife.size; - ret.file_base = file_base(ife); - ret.mtime = mtime(ife); + ret.file_base = file_base(index); + ret.mtime = mtime(index); ret.pad_file = ife.pad_file; ret.hidden_attribute = ife.hidden_attribute; ret.executable_attribute = ife.executable_attribute; ret.symlink_attribute = ife.symlink_attribute; - if (ife.symlink_index >= 0) ret.symlink_path = symlink(ife); - ret.filehash = hash(ife); + if (ife.symlink_index >= 0) ret.symlink_path = symlink(index); + ret.filehash = hash(index); return ret; } @@ -382,6 +412,7 @@ namespace libtorrent m_name = split_path(ent.path).c_str(); } internal_file_entry ife(ent); + int file_index = m_files.size(); m_files.push_back(ife); internal_file_entry& e = m_files.back(); if (e.size < 0) e.size = 0; @@ -402,7 +433,7 @@ namespace libtorrent if (m_mtime.size() < m_files.size()) m_mtime.resize(m_files.size()); m_mtime[m_files.size() - 1] = ent.mtime; } - if (ent.file_base) set_file_base(e, ent.file_base); + if (ent.file_base) set_file_base(file_index, ent.file_base); update_path_index(e); } @@ -478,6 +509,15 @@ namespace libtorrent return m_files[index].offset; } + int file_storage::file_flags(int index) const + { + internal_file_entry const& fe = m_files[index]; + return (fe.pad_file ? flag_pad_file : 0) + | (fe.hidden_attribute ? flag_hidden : 0) + | (fe.executable_attribute ? flag_executable : 0) + | (fe.symlink_attribute ? flag_symlink : 0); + } + #ifndef TORRENT_NO_DEPRECATE sha1_hash file_storage::hash(internal_file_entry const& fe) const { @@ -552,7 +592,10 @@ namespace libtorrent { return fe.offset; } -#endif + + file_entry file_storage::at(file_storage::iterator i) const + { return at(i - begin()); } +#endif // TORRENT_NO_DEPRECATE bool compare_file_entry_size(internal_file_entry const& fe1, internal_file_entry const& fe2) { return fe1.size < fe2.size; } @@ -612,8 +655,8 @@ namespace libtorrent if (best_match != i) { - int index = file_index(*best_match); - int cur_index = file_index(*i); + int index = best_match - m_files.begin(); + int cur_index = i - m_files.begin(); reorder_file(index, cur_index); i = m_files.begin() + cur_index; } @@ -645,8 +688,8 @@ namespace libtorrent // look for files <= pad_size, which never is greater than // alignment TORRENT_ASSERT(best_match != i); - int index = file_index(*best_match); - int cur_index = file_index(*i); + int index = best_match - m_files.begin(); + int cur_index = i - m_files.begin(); reorder_file(index, cur_index); i = m_files.begin() + cur_index; i->offset = off; @@ -663,7 +706,7 @@ namespace libtorrent // then swap it in place. This minimizes the amount // of copying of internal_file_entry, which is somewhat // expensive (until we have move semantics) - int cur_index = file_index(*i); + int cur_index = i - m_files.begin(); int index = m_files.size(); m_files.push_back(internal_file_entry()); internal_file_entry& e = m_files.back(); diff --git a/src/storage.cpp b/src/storage.cpp index 12556ac64..1923886e4 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -100,17 +100,16 @@ namespace libtorrent { std::string save_path = complete(p); std::vector > sizes; - for (file_storage::iterator i = storage.begin() - , end(storage.end()); i != end; ++i) + for (int i = 0; i < storage.num_files(); ++i) { size_type size = 0; std::time_t time = 0; - if (!i->pad_file) + if (!storage.pad_file_at(i)) { file_status s; error_code ec; - stat_file(storage.file_path(*i, save_path), &s, ec); + stat_file(storage.file_path(i, save_path), &s, ec); if (!ec) { @@ -151,16 +150,15 @@ namespace libtorrent std::vector >::const_iterator size_iter = sizes.begin(); - for (file_storage::iterator i = fs.begin() - , end(fs.end());i != end; ++i, ++size_iter) + for (int i = 0; i < fs.num_files(); ++i, ++size_iter) { size_type size = 0; std::time_t time = 0; - if (i->pad_file) continue; + if (fs.pad_file_at(i)) continue; file_status s; error_code ec; - stat_file(fs.file_path(*i, p), &s, ec); + stat_file(fs.file_path(i, p), &s, ec); if (!ec) { @@ -393,7 +391,7 @@ namespace libtorrent { if (mapped) m_mapped_files.reset(new file_storage(*mapped)); - TORRENT_ASSERT(m_files.begin() != m_files.end()); + TORRENT_ASSERT(m_files.num_files() > 0); m_save_path = complete(path); } @@ -405,19 +403,16 @@ namespace libtorrent error_code ec; // first, create all missing directories std::string last_path; - for (file_storage::iterator file_iter = files().begin(), - end_iter = files().end(); file_iter != end_iter; ++file_iter) + for (int file_index = 0; file_index < files().num_files(); ++file_index) { - int file_index = files().file_index(*file_iter); - // ignore files that have priority 0 if (int(m_file_priority.size()) > file_index && m_file_priority[file_index] == 0) continue; // ignore pad files - if (file_iter->pad_file) continue; + if (files().pad_file_at(file_index)) continue; - std::string file_path = files().file_path(*file_iter, m_save_path); + std::string file_path = files().file_path(file_index, m_save_path); file_status s; stat_file(file_path, &s, ec); @@ -433,7 +428,7 @@ namespace libtorrent // if the file already exists, but is larger than what // it's supposed to be, also truncate it // if the file is empty, just create it either way. - if ((ec && allocate_files) || (!ec && s.file_size > file_iter->size) || file_iter->size == 0) + if ((ec && allocate_files) || (!ec && s.file_size > files().file_size(file_index)) || files().file_size(file_index) == 0) { std::string dir = parent_path(file_path); @@ -450,11 +445,11 @@ namespace libtorrent } ec.clear(); - boost::intrusive_ptr f = open_file(file_iter, file::read_write | file::random_access, ec); + boost::intrusive_ptr f = open_file(file_index, file::read_write | file::random_access, ec); if (ec) set_error(file_path, ec); else if (f) { - f->set_size(file_iter->size, ec); + f->set_size(files().file_size(file_index), ec); if (ec) set_error(file_path, ec); } if (ec) break; @@ -475,16 +470,13 @@ namespace libtorrent bool default_storage::has_any_file() { - file_storage::iterator i = files().begin(); - file_storage::iterator end = files().end(); - - for (; i != end; ++i) + for (int i = 0; i < files().num_files(); ++i) { error_code ec; file_status s; - stat_file(files().file_path(*i, m_save_path), &s, ec); + stat_file(files().file_path(i, m_save_path), &s, ec); if (ec) continue; - if (s.mode & file_status::regular_file && i->size > 0) + if (s.mode & file_status::regular_file && files().file_size(i) > 0) return true; } return false; @@ -554,10 +546,9 @@ namespace libtorrent // delete the files from disk std::set directories; typedef std::set::iterator iter_t; - for (file_storage::iterator i = files().begin() - , end(files().end()); i != end; ++i) + for (int i = 0; i < files().num_files(); ++i) { - std::string fp = files().file_path(*i); + std::string fp = files().file_path(i); bool complete = is_complete(fp); std::string p = complete ? fp : combine_path(m_save_path, fp); if (!complete) @@ -613,20 +604,20 @@ namespace libtorrent TORRENT_ASSERT(slot < m_files.num_pieces()); size_type file_offset = (size_type)slot * m_files.piece_length(); - file_storage::iterator file_iter; + int file_index = 0; - for (file_iter = files().begin();;) + for (;;) { - if (file_offset < file_iter->size) + if (file_offset < m_files.file_size(file_index)) break; - file_offset -= file_iter->size; - ++file_iter; - TORRENT_ASSERT(file_iter != files().end()); + file_offset -= m_files.file_size(file_index); + ++file_index; + TORRENT_ASSERT(file_index != files().num_files()); } error_code ec; - boost::intrusive_ptr file_handle = open_file(file_iter, file::read_only, ec); + boost::intrusive_ptr file_handle = open_file(file_index, file::read_only, ec); if (!file_handle || ec) return slot; size_type data_start = file_handle->sparse_end(file_offset); @@ -737,10 +728,9 @@ namespace libtorrent fs = file_sizes.begin(); // the resume data says we have the entire torrent // make sure the file sizes are the right ones - for (file_storage::iterator i = files().begin() - , end(files().end()); i != end; ++i, ++fs) + for (int i = 0; i < files().num_files(); ++i) { - if (!i->pad_file && i->size != fs->first) + if (!files().pad_file_at(i) && files().file_size(i) != fs->first) { error = errors::mismatching_file_size; return false; @@ -771,13 +761,12 @@ namespace libtorrent if (ec != boost::system::errc::no_such_file_or_directory) { // the directory exists, check all the files - for (file_storage::iterator i = f.begin() - , end(f.end()); i != end; ++i) + for (int i = 0; i < f.num_files(); ++i) { // files moved out to absolute paths are ignored - if (is_complete(f.file_path(*i))) continue; + if (is_complete(f.file_path(i))) continue; - std::string new_path = f.file_path(*i, save_path); + std::string new_path = f.file_path(i, save_path); stat_file(new_path, &s, ec); if (ec != boost::system::errc::no_such_file_or_directory) return piece_manager::file_exist; @@ -789,13 +778,12 @@ namespace libtorrent // try to move entire directories by default (instead of // files independently). std::set to_move; - for (file_storage::iterator i = f.begin() - , end(f.end()); i != end; ++i) + for (int i = 0; i < f.num_files(); ++i) { // files moved out to absolute paths are not moved - if (is_complete(f.file_path(*i))) continue; + if (is_complete(f.file_path(i))) continue; - std::string split = split_path(f.file_path(*i)); + std::string split = split_path(f.file_path(i)); to_move.insert(to_move.begin(), split); } @@ -1007,24 +995,25 @@ ret: // find the file and file size_type tor_off = size_type(slot) * files().piece_length() + offset; - file_storage::iterator file_iter = files().file_at_offset(tor_off); - while (file_iter->pad_file) + int file_index = files().file_index_at_offset(tor_off); + while (files().pad_file_at(file_index)) { - ++file_iter; - if (file_iter == files().end()) + ++file_index; + if (file_index == files().num_files()) return size_type(slot) * files().piece_length() + offset; // update offset as well, since we're moving it up ahead - tor_off = file_iter->offset; - } - TORRENT_ASSERT(!file_iter->pad_file); + tor_off = files().file_offset(file_index); - size_type file_offset = tor_off - file_iter->offset; + } + TORRENT_ASSERT(!files().pad_file_at(file_index)); + + size_type file_offset = tor_off - files().file_offset(file_index); TORRENT_ASSERT(file_offset >= 0); // open the file read only to avoid re-opening // it in case it's already opened in read-only mode error_code ec; - boost::intrusive_ptr f = open_file(file_iter, file::read_only | file::random_access, ec); + boost::intrusive_ptr f = open_file(file_index, file::read_only | file::random_access, ec); size_type ret = 0; if (f && !ec) ret = f->phys_offset(file_offset); @@ -1043,11 +1032,10 @@ ret: size_type start = slot * (size_type)m_files.piece_length() + offset; TORRENT_ASSERT(start + size <= m_files.total_size()); - file_storage::iterator file_iter = files().file_at_offset(start); - TORRENT_ASSERT(file_iter != files().end()); - TORRENT_ASSERT(start >= files().file_offset(*file_iter)); - TORRENT_ASSERT(start < files().file_offset(*file_iter) + files().file_size(*file_iter)); - size_type file_offset = start - files().file_offset(*file_iter); + int file_index = files().file_index_at_offset(start); + TORRENT_ASSERT(start >= files().file_offset(file_index)); + TORRENT_ASSERT(start < files().file_offset(file_index) + files().file_size(file_index)); + size_type file_offset = start - files().file_offset(file_index); boost::intrusive_ptr file_handle; int bytes_left = size; @@ -1059,20 +1047,20 @@ ret: TORRENT_ASSERT(bytes_left >= 0); int file_bytes_left; - for (;bytes_left > 0; ++file_iter, bytes_left -= file_bytes_left) + for (;bytes_left > 0; ++file_index, bytes_left -= file_bytes_left) { - TORRENT_ASSERT(file_iter != files().end()); + TORRENT_ASSERT(file_index < files().num_files()); file_bytes_left = bytes_left; - if (file_offset + file_bytes_left > file_iter->size) - file_bytes_left = (std::max)(static_cast(file_iter->size - file_offset), 0); + if (file_offset + file_bytes_left > files().file_size(file_index)) + file_bytes_left = (std::max)(static_cast(files().file_size(file_index) - file_offset), 0); if (file_bytes_left == 0) continue; - if (file_iter->pad_file) continue; + if (files().file_size(file_index)) continue; error_code ec; - file_handle = open_file(file_iter, file::read_only | file::random_access, ec); + file_handle = open_file(file_index, file::read_only | file::random_access, ec); // failing to hint that we want to read is not a big deal // just swollow the error and keep going @@ -1141,11 +1129,10 @@ ret: TORRENT_ASSERT(start + size <= m_files.total_size()); // find the file iterator and file offset - file_storage::iterator file_iter = files().file_at_offset(start); - TORRENT_ASSERT(file_iter != files().end()); - TORRENT_ASSERT(start >= files().file_offset(*file_iter)); - TORRENT_ASSERT(start < files().file_offset(*file_iter) + files().file_size(*file_iter)); - size_type file_offset = start - files().file_offset(*file_iter); + int file_index = files().file_index_at_offset(start); + TORRENT_ASSERT(start >= files().file_offset(file_index)); + TORRENT_ASSERT(start < files().file_offset(file_index) + files().file_size(file_index)); + size_type file_offset = start - files().file_offset(file_index); int buf_pos = 0; error_code ec; @@ -1168,15 +1155,15 @@ ret: copy_bufs(bufs, size, current_buf); TORRENT_ASSERT(count_bufs(current_buf, size) == num_bufs); int file_bytes_left; - for (;bytes_left > 0; ++file_iter, bytes_left -= file_bytes_left + for (;bytes_left > 0; ++file_index, bytes_left -= file_bytes_left , buf_pos += file_bytes_left) { - TORRENT_ASSERT(file_iter != files().end()); + TORRENT_ASSERT(file_index < files().num_files()); TORRENT_ASSERT(buf_pos >= 0); file_bytes_left = bytes_left; - if (file_offset + file_bytes_left > file_iter->size) - file_bytes_left = (std::max)(static_cast(file_iter->size - file_offset), 0); + if (file_offset + file_bytes_left > files().file_size(file_index)) + file_bytes_left = (std::max)(static_cast(files().file_size(file_index) - file_offset), 0); if (file_bytes_left == 0) continue; @@ -1184,12 +1171,11 @@ ret: TORRENT_ASSERT(int(slices.size()) > counter); size_type slice_size = slices[counter].size; TORRENT_ASSERT(slice_size == file_bytes_left); - TORRENT_ASSERT((files().begin() + slices[counter].file_index) - == file_iter); + TORRENT_ASSERT(slices[counter].file_index == file_index); ++counter; #endif - if (file_iter->pad_file) + if (files().pad_file_at(file_index)) { if ((op.mode & file::rw_mask) == file::read_only) { @@ -1205,22 +1191,22 @@ ret: } error_code ec; - file_handle = open_file(file_iter, op.mode, ec); + file_handle = open_file(file_index, op.mode, ec); if (((op.mode & file::rw_mask) == file::read_write) && ec == boost::system::errc::no_such_file_or_directory) { // this means the directory the file is in doesn't exist. // so create it ec.clear(); - std::string path = files().file_path(*file_iter, m_save_path); + std::string path = files().file_path(file_index, m_save_path); create_directories(parent_path(path), ec); // if the directory creation failed, don't try to open the file again // but actually just fail - if (!ec) file_handle = open_file(file_iter, op.mode, ec); + if (!ec) file_handle = open_file(file_index, op.mode, ec); } if (!file_handle || ec) { - std::string path = files().file_path(*file_iter, m_save_path); + std::string path = files().file_path(file_index, m_save_path); TORRENT_ASSERT(ec); set_error(path, ec); return -1; @@ -1234,7 +1220,7 @@ ret: // read is unaligned, we need to fall back on a slow // special read that reads aligned buffers and copies // it into the one supplied - size_type adjusted_offset = files().file_base(*file_iter) + file_offset; + size_type adjusted_offset = files().file_base(file_index) + file_offset; if ((file_handle->open_mode() & file::no_buffer) && ((adjusted_offset & (file_handle->pos_alignment()-1)) != 0 || (uintptr_t(tmp_bufs->iov_base) & (file_handle->buf_alignment()-1)) != 0)) @@ -1242,7 +1228,7 @@ ret: bytes_transferred = (int)(this->*op.unaligned_op)(file_handle, adjusted_offset , tmp_bufs, num_tmp_bufs, ec); if ((op.mode & file::rw_mask) == file::read_write - && adjusted_offset + bytes_transferred >= file_iter->size + && adjusted_offset + bytes_transferred >= files().file_size(file_index) && (file_handle->pos_alignment() > 0 || file_handle->size_alignment() > 0)) { // we were writing, and we just wrote the last block of the file @@ -1252,7 +1238,7 @@ ret: // TODO: 0 what if file_base is used to merge several virtual files // into a single physical file? We should probably disable this // if file_base is used. This is not a widely used feature though - file_handle->set_size(file_iter->size, ec); + file_handle->set_size(files().file_size(file_index), ec); } } else @@ -1265,7 +1251,7 @@ ret: if (ec) { - set_error(files().file_path(*file_iter, m_save_path), ec); + set_error(files().file_path(file_index, m_save_path), ec); return -1; } @@ -1398,20 +1384,20 @@ ret: return readv(&b, slot, offset, 1); } - boost::intrusive_ptr default_storage::open_file(file_storage::iterator fe, int mode + boost::intrusive_ptr default_storage::open_file(int file_index, int mode , error_code& ec) const { int cache_setting = m_settings ? settings().disk_io_write_mode : 0; if (cache_setting == session_settings::disable_os_cache || (cache_setting == session_settings::disable_os_cache_for_aligned_files - && ((fe->offset + files().file_base(*fe)) & (m_page_size-1)) == 0)) + && ((files().file_offset(file_index) + files().file_base(file_index)) & (m_page_size-1)) == 0)) mode |= file::no_buffer; bool lock_files = m_settings ? settings().lock_files : false; if (lock_files) mode |= file::lock_file; if (!m_allocate_files) mode |= file::sparse; if (m_settings && settings().no_atime_storage) mode |= file::no_atime; - return m_pool.open_file(const_cast(this), m_save_path, fe, files(), mode, ec); + return m_pool.open_file(const_cast(this), m_save_path, file_index, files(), mode, ec); } storage_interface* default_storage_constructor(file_storage const& fs @@ -2482,10 +2468,9 @@ ret: { size_type file_offset = 0; size_type current_offset = size_type(m_current_slot) * m_files.piece_length(); - for (file_storage::iterator i = m_files.begin() - , end(m_files.end()); i != end; ++i) + for (int i = 0; i < m_files.num_files(); ++i) { - file_offset += i->size; + file_offset += m_files.file_size(i); if (file_offset > current_offset) break; } diff --git a/src/torrent.cpp b/src/torrent.cpp index 2a919b0a9..fc8633167 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1717,14 +1717,13 @@ namespace libtorrent #endif TORRENT_ASSERT(block_size() > 0); - int file = 0; - for (file_storage::iterator i = m_torrent_file->files().begin() - , end(m_torrent_file->files().end()); i != end; ++i, ++file) + file_storage const& fs = m_torrent_file->files(); + for (int i = 0; i < fs.num_files(); ++i) { - if (!i->pad_file || i->size == 0) continue; - m_padding += i->size; + if (!fs.pad_file_at(i) || fs.file_size(i) == 0) continue; + m_padding += fs.file_size(i); - peer_request pr = m_torrent_file->map_file(file, 0, m_torrent_file->file_at(file).size); + peer_request pr = m_torrent_file->map_file(i, 0, fs.file_size(i)); int off = pr.start & (block_size()-1); if (off != 0) { pr.length -= block_size() - off; pr.start += block_size() - off; } TORRENT_ASSERT((pr.start & (block_size()-1)) == 0); @@ -1740,8 +1739,8 @@ namespace libtorrent // ugly edge case where padfiles are not used they way they're // supposed to be. i.e. added back-to back or at the end if (int(pb.block_index) == blocks_per_piece) { pb.block_index = 0; ++pb.piece_index; } - if (pr.length > 0 && ((boost::next(i) != end && boost::next(i)->pad_file) - || boost::next(i) == end)) + if (pr.length > 0 && ((i+1 != fs.num_files() && fs.pad_file_at(i+1)) + || i + 1 == fs.num_files())) { m_picker->mark_as_finished(pb, 0); } @@ -2991,12 +2990,10 @@ namespace libtorrent if (m_padding > 0 && accurate) { file_storage const& files = m_torrent_file->files(); - int fileno = 0; - for (file_storage::iterator i = files.begin() - , end(files.end()); i != end; ++i, ++fileno) + for (int i = 0; i < files.num_files(); ++i) { - if (!i->pad_file) continue; - peer_request p = files.map_file(fileno, 0, i->size); + if (!files.pad_file_at(i)) continue; + peer_request p = files.map_file(i, 0, files.file_size(i)); for (int j = p.piece; p.length > 0; ++j) { int deduction = (std::min)(p.length, piece_size - p.start); @@ -3233,15 +3230,15 @@ namespace libtorrent const int piece_size = m_torrent_file->piece_length(); size_type off = size_type(index) * piece_size; - file_storage::iterator f = m_torrent_file->files().file_at_offset(off); + int file_index = m_torrent_file->files().file_index_at_offset(off); int size = m_torrent_file->piece_size(index); - int file_index = f - m_torrent_file->files().begin(); - for (; size > 0; ++f, ++file_index) + file_storage const& fs = m_torrent_file->files(); + for (; size > 0; ++file_index) { - size_type file_offset = off - f->offset; - TORRENT_ASSERT(f != m_torrent_file->files().end()); - TORRENT_ASSERT(file_offset <= f->size); - int add = (std::min)(f->size - file_offset, (size_type)size); + size_type file_offset = off - fs.file_offset(file_index); + TORRENT_ASSERT(file_index != fs.num_files()); + TORRENT_ASSERT(file_offset <= fs.file_size(file_index)); + int add = (std::min)(fs.file_size(file_index) - file_offset, (size_type)size); m_file_progress[file_index] += add; TORRENT_ASSERT(m_file_progress[file_index] @@ -4130,16 +4127,15 @@ namespace libtorrent // initialize the piece priorities to 0, then only allow // setting higher priorities std::vector pieces(m_torrent_file->num_pieces(), 0); - int index = 0; - for (file_storage::iterator i = m_torrent_file->files().begin() - , end(m_torrent_file->files().end()); i != end; ++i, ++index) + file_storage const& fs = m_torrent_file->files(); + for (int i = 0; i < fs.num_files(); ++i) { - if (index >= m_torrent_file->num_files()) break; + if (i >= m_torrent_file->num_files()) break; size_type start = position; - size_type size = m_torrent_file->files().file_size(*i); + size_type size = m_torrent_file->files().file_size(i); if (size == 0) continue; position += size; - if (m_file_priority[index] == 0) continue; + if (m_file_priority[i] == 0) continue; // mark all pieces of the file with this file's priority // but only if the priority is higher than the pieces @@ -4151,7 +4147,7 @@ namespace libtorrent // come here several times with the same start_piece, end_piece std::for_each(pieces.begin() + start_piece , pieces.begin() + last_piece + 1 - , boost::bind(&set_if_greater, _1, m_file_priority[index])); + , boost::bind(&set_if_greater, _1, m_file_priority[i])); } prioritize_pieces(pieces); } @@ -5484,10 +5480,10 @@ namespace libtorrent && m_torrent_file->files().num_files() == m_torrent_file->orig_files().num_files()) { entry::list_type& fl = ret["mapped_files"].list(); - for (torrent_info::file_iterator i = m_torrent_file->begin_files() - , end(m_torrent_file->end_files()); i != end; ++i) + file_storage const& fs = m_torrent_file->files(); + for (int i = 0; i < fs.num_files(); ++i) { - fl.push_back(m_torrent_file->files().file_path(*i)); + fl.push_back(fs.file_path(i)); } } @@ -8536,26 +8532,25 @@ namespace libtorrent const std::vector& q = m_picker->get_download_queue(); + file_storage const& fs = m_torrent_file->files(); for (std::vector::const_iterator i = q.begin(), end(q.end()); i != end; ++i) { size_type offset = size_type(i->index) * m_torrent_file->piece_length(); - torrent_info::file_iterator file = m_torrent_file->file_at_offset(offset); - int file_index = file - m_torrent_file->begin_files(); + int file = fs.file_index_at_offset(offset); int num_blocks = m_picker->blocks_in_piece(i->index); piece_picker::block_info const* info = i->info; for (int k = 0; k < num_blocks; ++k) { - TORRENT_ASSERT(file != m_torrent_file->end_files()); + TORRENT_ASSERT(file < fs.num_files()); TORRENT_ASSERT(offset == size_type(i->index) * m_torrent_file->piece_length() + k * block_size()); TORRENT_ASSERT(offset < m_torrent_file->total_size()); - while (offset >= file->offset + file->size) + while (offset >= fs.file_offset(file) + fs.file_size(file)) { ++file; - ++file_index; } - TORRENT_ASSERT(file != m_torrent_file->end_files()); + TORRENT_ASSERT(file < fs.num_files()); size_type block = block_size(); @@ -8585,24 +8580,23 @@ namespace libtorrent } } - if (offset + block > file->offset + file->size) + if (offset + block > fs.file_offset(file) + fs.file_size(file)) { int left_over = int(block_size() - block); // split the block on multiple files while (block > 0) { - TORRENT_ASSERT(offset <= file->offset + file->size); - size_type slice = (std::min)(file->offset + file->size - offset + TORRENT_ASSERT(offset <= fs.file_offset(file) + fs.file_size(file)); + size_type slice = (std::min)(fs.file_offset(file) + fs.file_size(file) - offset , block); - fp[file_index] += slice; + fp[file] += slice; offset += slice; block -= slice; - TORRENT_ASSERT(offset <= file->offset + file->size); - if (offset == file->offset + file->size) + TORRENT_ASSERT(offset <= fs.file_offset(file) + fs.file_size(file)); + if (offset == fs.file_offset(file) + fs.file_size(file)) { ++file; - ++file_index; - if (file == m_torrent_file->end_files()) + if (file == fs.num_files()) { offset += block; break; @@ -8615,10 +8609,10 @@ namespace libtorrent } else { - fp[file_index] += block; + fp[file] += block; offset += block_size(); } - TORRENT_ASSERT(file_index <= m_torrent_file->num_files()); + TORRENT_ASSERT(file <= m_torrent_file->num_files()); } } } diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 00a2e7994..8ddaadfc9 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -412,15 +412,15 @@ namespace libtorrent // This is a memory optimization! Instead of having // each entry keep a string for its filename, make it // simply point into the info-section buffer - internal_file_entry const& fe = *target.rbegin(); + int last_index = target.num_files() - 1; // TODO: 1 once the filename renaming is removed from here // this check can be removed as well - if (fee && fe.filename() == fee->string_value()) + if (fee && target.file_name(last_index) == fee->string_value()) { // this string pointer does not necessarily point into // the m_info_section buffer. char const* str_ptr = fee->string_ptr() + info_ptr_diff; - const_cast(fe).set_name(str_ptr, fee->string_length()); + target.rename_file_borrow(last_index, str_ptr, fee->string_length()); } } return true; @@ -1396,20 +1396,19 @@ namespace libtorrent #if defined TORRENT_DEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS void torrent_info::check_invariant() const { - for (file_storage::iterator i = m_files.begin() - , end(m_files.end()); i != end; ++i) + for (int i = 0; i < m_files.num_files(); ++i) { - TORRENT_ASSERT(i->name != 0); - if (i->name_len > 0) + TORRENT_ASSERT(m_files.file_name_ptr(i) != 0); + if (m_files.file_name_len(i) > 0) { // name needs to point into the allocated info section buffer - TORRENT_ASSERT(i->name >= m_info_section.get()); - TORRENT_ASSERT(i->name < m_info_section.get() + m_info_section_size); + TORRENT_ASSERT(m_files.file_name_ptr(i) >= m_info_section.get()); + TORRENT_ASSERT(m_files.file_name_ptr(i) < m_info_section.get() + m_info_section_size); } else { // name must be a valid string - TORRENT_ASSERT(strlen(i->name) < 2048); + TORRENT_ASSERT(strlen(m_files.file_name_ptr(i)) < 2048); } } diff --git a/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index 5a81b62bf..2b176fb89 100644 --- a/src/web_peer_connection.cpp +++ b/src/web_peer_connection.cpp @@ -225,7 +225,7 @@ namespace libtorrent i != files.end(); ++i) { file_slice const& f = *i; - if (info.orig_files().internal_at(f.file_index).pad_file) + if (info.orig_files().pad_file_at(f.file_index)) { m_file_requests.push_back(f.file_index); continue; @@ -235,7 +235,7 @@ namespace libtorrent if (using_proxy) { request += m_url; - std::string path = info.orig_files().file_path(info.orig_files().internal_at(f.file_index)); + std::string path = info.orig_files().file_path(f.file_index); #ifdef TORRENT_WINDOWS convert_path_to_posix(path); #endif @@ -244,7 +244,7 @@ namespace libtorrent else { std::string path = m_path; - path += info.orig_files().file_path(info.orig_files().internal_at(f.file_index)); + path += info.orig_files().file_path(f.file_index); #ifdef TORRENT_WINDOWS convert_path_to_posix(path); #endif @@ -522,7 +522,7 @@ namespace libtorrent int file_index = m_file_requests.front(); torrent_info const& info = t->torrent_file(); - std::string path = info.orig_files().file_path(info.orig_files().at(file_index)); + std::string path = info.orig_files().file_path(file_index); #ifdef TORRENT_WINDOWS convert_path_to_posix(path); #endif @@ -866,7 +866,7 @@ namespace libtorrent torrent_info const& info = t->torrent_file(); while (!m_file_requests.empty() - && info.orig_files().internal_at(m_file_requests.front()).pad_file) + && info.orig_files().pad_file_at(m_file_requests.front())) { // the next file is a pad file. We didn't actually send // a request for this since it most likely doesn't exist on @@ -874,7 +874,7 @@ namespace libtorrent // bunch of zeroes here and pop it again int file_index = m_file_requests.front(); m_file_requests.pop_front(); - size_type file_size = info.orig_files().file_size(info.orig_files().internal_at(file_index)); + size_type file_size = info.orig_files().file_size(file_index); TORRENT_ASSERT(m_block_pos < front_request.length); int pad_size = (std::min)(file_size, size_type(front_request.length - m_block_pos)); diff --git a/test/test_storage.cpp b/test/test_storage.cpp index 6152a66e9..fd301bf7e 100644 --- a/test/test_storage.cpp +++ b/test/test_storage.cpp @@ -872,7 +872,7 @@ void run_test(std::string const& test_path, bool unbuffered) file_storage fs; fs.add_file(combine_path("temp_storage", "test1.tmp"), 3 * piece_size); libtorrent::create_torrent t(fs, piece_size, -1, 0); - TEST_CHECK(fs.file_path(*fs.begin()) == combine_path("temp_storage", "test1.tmp")); + TEST_CHECK(fs.file_path(0) == combine_path("temp_storage", "test1.tmp")); t.set_hash(0, hasher(piece0, piece_size).final()); t.set_hash(1, hasher(piece1, piece_size).final()); t.set_hash(2, hasher(piece2, piece_size).final()); diff --git a/test/test_torrent_parse.cpp b/test/test_torrent_parse.cpp index c3e345058..7f16615e5 100644 --- a/test/test_torrent_parse.cpp +++ b/test/test_torrent_parse.cpp @@ -179,24 +179,24 @@ int test_main() #endif } - int index = 0; - for (torrent_info::file_iterator i = ti->begin_files(); - i != ti->end_files(); ++i, ++index) + file_storage const& fs = ti->files(); + for (int i = 0; i < fs.num_files(); ++i) { - int first = ti->map_file(index, 0, 0).piece; - int last = ti->map_file(index, (std::max)(size_type(i->size)-1, size_type(0)), 0).piece; + int first = ti->map_file(i, 0, 0).piece; + int last = ti->map_file(i, (std::max)(fs.file_size(i)-1, size_type(0)), 0).piece; + int flags = fs.file_flags(i); fprintf(stderr, " %11"PRId64" %c%c%c%c [ %4d, %4d ] %7u %s %s %s%s\n" - , i->size - , (i->pad_file?'p':'-') - , (i->executable_attribute?'x':'-') - , (i->hidden_attribute?'h':'-') - , (i->symlink_attribute?'l':'-') + , fs.file_size(i) + , (flags & file_storage::flag_pad_file)?'p':'-' + , (flags & file_storage::flag_executable)?'x':'-' + , (flags & file_storage::flag_hidden)?'h':'-' + , (flags & file_storage::flag_symlink)?'l':'-' , first, last - , boost::uint32_t(ti->files().mtime(*i)) - , ti->files().hash(*i) != sha1_hash(0) ? to_hex(ti->files().hash(*i).to_string()).c_str() : "" - , ti->files().file_path(*i).c_str() - , i->symlink_attribute ? "-> ": "" - , i->symlink_attribute && i->symlink_index != -1 ? ti->files().symlink(*i).c_str() : ""); + , boost::uint32_t(fs.mtime(i)) + , fs.hash(i) != sha1_hash(0) ? to_hex(fs.hash(i).to_string()).c_str() : "" + , fs.file_path(i).c_str() + , flags & file_storage::flag_symlink ? "-> ": "" + , flags & file_storage::flag_symlink ? fs.symlink(i).c_str() : ""); } // test swap diff --git a/test/test_web_seed.cpp b/test/test_web_seed.cpp index 32923e086..f19b6388e 100644 --- a/test/test_web_seed.cpp +++ b/test/test_web_seed.cpp @@ -174,8 +174,7 @@ void test_transfer(boost::intrusive_ptr torrent_file if (proxy) stop_proxy(8002); - TEST_CHECK(exists(combine_path("tmp2_web_seed", torrent_file->files().file_path( - torrent_file->file_at(0)))) || test_ban); + TEST_CHECK(exists(combine_path("tmp2_web_seed", torrent_file->files().file_path(0))) || test_ban); remove_all("tmp2_web_seed", ec); }