deprecate file_entry (used by file_storage) and clean up the add_file overload that borrows memory (and improve implementation and documentation). The python bindings were updated to more closely match the c++ API (specifically actually using file_storage)

This commit is contained in:
Arvid Norberg 2015-01-21 15:46:12 +00:00
parent 5cfd662352
commit bc9281a27c
12 changed files with 324 additions and 299 deletions

View File

@ -54,10 +54,12 @@ namespace
ct.add_node(std::make_pair(addr, port)); ct.add_node(std::make_pair(addr, port));
} }
#if !defined TORRENT_NO_DEPRECATE
void add_file(file_storage& ct, file_entry const& fe) void add_file(file_storage& ct, file_entry const& fe)
{ {
ct.add_file(fe); ct.add_file(fe);
} }
#endif
char const* filestorage_name(file_storage const& fs) char const* filestorage_name(file_storage const& fs)
{ return fs.name().c_str(); } { return fs.name().c_str(); }
@ -76,10 +78,14 @@ namespace
void bind_create_torrent() void bind_create_torrent()
{ {
void (file_storage::*add_file0)(std::string const&, boost::int64_t, int, std::time_t, std::string const&) = &file_storage::add_file; void (file_storage::*add_file0)(std::string const&, boost::int64_t
#if TORRENT_USE_WSTRING && !defined TORRENT_NO_DEPRECATE , int, std::time_t, std::string const&) = &file_storage::add_file;
void (file_storage::*add_file1)(std::wstring const&, boost::int64_t, int, std::time_t, std::string const&) = &file_storage::add_file; #if !defined TORRENT_NO_DEPRECATE
#endif #if TORRENT_USE_WSTRING
void (file_storage::*add_file1)(std::wstring const&, boost::int64_t
, int, std::time_t, std::string const&) = &file_storage::add_file;
#endif // TORRENT_USE_WSTRING
#endif // TORRENT_NO_DEPRECATE
void (file_storage::*set_name0)(std::string const&) = &file_storage::set_name; void (file_storage::*set_name0)(std::string const&) = &file_storage::set_name;
void (file_storage::*rename_file0)(int, std::string const&) = &file_storage::rename_file; void (file_storage::*rename_file0)(int, std::string const&) = &file_storage::rename_file;
@ -93,23 +99,37 @@ void bind_create_torrent()
#endif #endif
void (*add_files0)(file_storage&, std::string const&, boost::uint32_t) = add_files; void (*add_files0)(file_storage&, std::string const&, boost::uint32_t) = add_files;
std::string const& (file_storage::*file_storage_symlink)(int) const = &file_storage::symlink;
sha1_hash (file_storage::*file_storage_hash)(int) const = &file_storage::hash;
std::string (file_storage::*file_storage_file_path)(int, std::string const&) const = &file_storage::file_path;
boost::int64_t (file_storage::*file_storage_file_size)(int) const = &file_storage::file_size;
boost::int64_t (file_storage::*file_storage_file_offset)(int) const = &file_storage::file_offset;
int (file_storage::*file_storage_file_flags)(int) const = &file_storage::file_flags;
#if !defined TORRENT_NO_DEPRECATE
file_entry (file_storage::*at)(int) const = &file_storage::at; file_entry (file_storage::*at)(int) const = &file_storage::at;
#endif
class_<file_storage>("file_storage") class_<file_storage>("file_storage")
.def("is_valid", &file_storage::is_valid) .def("is_valid", &file_storage::is_valid)
.def("add_file", add_file, arg("entry"))
.def("add_file", add_file0, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = "")) .def("add_file", add_file0, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
#if TORRENT_USE_WSTRING && !defined TORRENT_NO_DEPRECATE #if TORRENT_USE_WSTRING && !defined TORRENT_NO_DEPRECATE
.def("add_file", add_file1, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = "")) .def("add_file", add_file1, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
#endif #endif
.def("num_files", &file_storage::num_files) .def("num_files", &file_storage::num_files)
#if !defined TORRENT_NO_DEPRECATE
.def("at", at) .def("at", at)
// .def("hash", &file_storage::hash) .def("add_file", add_file, arg("entry"))
// .def("symlink", &file_storage::symlink, return_internal_reference<>()) #endif
// .def("file_index", &file_storage::file_index) .def("hash", file_storage_hash)
.def("symlink", file_storage_symlink, return_value_policy<copy_const_reference>())
// .def("file_base", &file_storage::file_base) // .def("file_base", &file_storage::file_base)
// .def("set_file_base", &file_storage::set_file_base) // .def("set_file_base", &file_storage::set_file_base)
// .def("file_path", &file_storage::file_path) .def("file_path", file_storage_file_path, (arg("idx"), arg("save_path") = ""))
.def("file_size", file_storage_file_size)
.def("file_offset", file_storage_file_offset)
.def("file_flags", file_storage_file_flags)
.def("total_size", &file_storage::total_size) .def("total_size", &file_storage::total_size)
.def("set_num_pieces", &file_storage::set_num_pieces) .def("set_num_pieces", &file_storage::set_num_pieces)
.def("num_pieces", &file_storage::num_pieces) .def("num_pieces", &file_storage::num_pieces)
@ -122,9 +142,16 @@ void bind_create_torrent()
.def("set_name", set_name1) .def("set_name", set_name1)
.def("rename_file", rename_file1) .def("rename_file", rename_file1)
#endif #endif
.def("name", &filestorage_name) .def("name", &file_storage::name, return_value_policy<copy_const_reference>())
; ;
enum_<file_storage::file_flags_t>("file_flags_t")
.value("flag_pad_file", file_storage::flag_pad_file)
.value("flag_hidden", file_storage::flag_hidden)
.value("flag_executable", file_storage::flag_executable)
.value("flag_symlink", file_storage::flag_symlink)
;
class_<create_torrent>("create_torrent", no_init) class_<create_torrent>("create_torrent", no_init)
.def(init<file_storage&>()) .def(init<file_storage&>())
.def(init<torrent_info const&>(arg("ti"))) .def(init<torrent_info const&>(arg("ti")))

View File

@ -96,14 +96,7 @@ namespace
} }
#endif #endif
void remap_files(torrent_info& ti, list files) { #if !defined TORRENT_NO_DEPRECATE
file_storage st;
for (int i = 0, e = len(files); i < e; ++i)
st.add_file(extract<file_entry>(files[i]));
ti.remap_files(st);
}
list files(torrent_info const& ti, bool storage) { list files(torrent_info const& ti, bool storage) {
list result; list result;
@ -123,6 +116,7 @@ namespace
return result; return result;
} }
#endif
std::string hash_for_piece(torrent_info const& ti, int i) std::string hash_for_piece(torrent_info const& ti, int i)
{ {
@ -157,7 +151,7 @@ namespace
bool get_complete_sent(announce_entry const& ae) { return ae.complete_sent; } bool get_complete_sent(announce_entry const& ae) { return ae.complete_sent; }
bool get_send_stats(announce_entry const& ae) { return ae.send_stats; } bool get_send_stats(announce_entry const& ae) { return ae.send_stats; }
#if !defined TORRENT_NO_DEPRECATE
boost::int64_t get_size(file_entry const& fe) { return fe.size; } boost::int64_t get_size(file_entry const& fe) { return fe.size; }
boost::int64_t get_offset(file_entry const& fe) { return fe.offset; } boost::int64_t get_offset(file_entry const& fe) { return fe.offset; }
boost::int64_t get_file_base(file_entry const& fe) { return fe.file_base; } boost::int64_t get_file_base(file_entry const& fe) { return fe.file_base; }
@ -166,6 +160,7 @@ namespace
bool get_executable_attribute(file_entry const& fe) { return fe.executable_attribute; } bool get_executable_attribute(file_entry const& fe) { return fe.executable_attribute; }
bool get_hidden_attribute(file_entry const& fe) { return fe.hidden_attribute; } bool get_hidden_attribute(file_entry const& fe) { return fe.hidden_attribute; }
bool get_symlink_attribute(file_entry const& fe) { return fe.symlink_attribute; } bool get_symlink_attribute(file_entry const& fe) { return fe.symlink_attribute; }
#endif
} // namespace unnamed } // namespace unnamed
@ -220,7 +215,6 @@ void bind_torrent_info()
.def(init<std::wstring, int>((arg("file"), arg("flags") = 0))) .def(init<std::wstring, int>((arg("file"), arg("flags") = 0)))
#endif #endif
.def("remap_files", &remap_files)
.def("add_tracker", &torrent_info::add_tracker, arg("url")) .def("add_tracker", &torrent_info::add_tracker, arg("url"))
.def("add_url_seed", &torrent_info::add_url_seed) .def("add_url_seed", &torrent_info::add_url_seed)
.def("add_http_seed", &torrent_info::add_http_seed) .def("add_http_seed", &torrent_info::add_http_seed)
@ -233,22 +227,23 @@ void bind_torrent_info()
.def("piece_length", &torrent_info::piece_length) .def("piece_length", &torrent_info::piece_length)
.def("num_pieces", &torrent_info::num_pieces) .def("num_pieces", &torrent_info::num_pieces)
.def("info_hash", &torrent_info::info_hash, copy) .def("info_hash", &torrent_info::info_hash, copy)
#ifndef TORRENT_NO_DEPRECATE
.def("file_at_offset", &torrent_info::file_at_offset)
#endif
.def("hash_for_piece", &hash_for_piece) .def("hash_for_piece", &hash_for_piece)
.def("merkle_tree", get_merkle_tree) .def("merkle_tree", get_merkle_tree)
.def("set_merkle_tree", set_merkle_tree) .def("set_merkle_tree", set_merkle_tree)
.def("piece_size", &torrent_info::piece_size) .def("piece_size", &torrent_info::piece_size)
.def("num_files", &torrent_info::num_files, (arg("storage")=false)) .def("num_files", &torrent_info::num_files)
.def("file_at", &torrent_info::file_at)
.def("files", &files, (arg("storage")=false))
.def("orig_files", &orig_files, (arg("storage")=false))
.def("rename_file", rename_file0) .def("rename_file", rename_file0)
#if TORRENT_USE_WSTRING && !defined TORRENT_NO_DEPRECATE .def("remap_files", &torrent_info::remap_files)
.def("files", &torrent_info::files, return_internal_reference<>())
.def("orig_files", &torrent_info::orig_files, return_internal_reference<>())
#if !defined TORRENT_NO_DEPRECATE
.def("file_at", &torrent_info::file_at)
.def("file_at_offset", &torrent_info::file_at_offset)
#if TORRENT_USE_WSTRING
.def("rename_file", rename_file1) .def("rename_file", rename_file1)
#endif #endif // TORRENT_USE_WSTRING
#endif // TORRENT_NO_DEPRECATE
.def("priv", &torrent_info::priv) .def("priv", &torrent_info::priv)
.def("trackers", range(begin_trackers, end_trackers)) .def("trackers", range(begin_trackers, end_trackers))
@ -263,6 +258,7 @@ void bind_torrent_info()
.def("map_file", &torrent_info::map_file) .def("map_file", &torrent_info::map_file)
; ;
#if !defined TORRENT_NO_DEPRECATE
class_<file_entry>("file_entry") class_<file_entry>("file_entry")
.def_readwrite("path", &file_entry::path) .def_readwrite("path", &file_entry::path)
.def_readwrite("symlink_path", &file_entry::symlink_path) .def_readwrite("symlink_path", &file_entry::symlink_path)
@ -276,6 +272,7 @@ void bind_torrent_info()
.add_property("size", &get_size) .add_property("size", &get_size)
.add_property("file_base", &get_file_base, &set_file_base) .add_property("file_base", &get_file_base, &set_file_base)
; ;
#endif
class_<announce_entry>("announce_entry", init<std::string const&>()) class_<announce_entry>("announce_entry", init<std::string const&>())
.def_readwrite("url", &announce_entry::url) .def_readwrite("url", &announce_entry::url)

View File

@ -46,9 +46,7 @@ namespace libtorrent
{ {
struct file; struct file;
// TODO: 3 the file_entry should be deprecated and add_file() should be #ifndef TORRENT_NO_DEPRECATE
// thought through a bit better
// information about a file in a file_storage // information about a file in a file_storage
struct TORRENT_EXPORT file_entry struct TORRENT_EXPORT file_entry
{ {
@ -106,6 +104,7 @@ namespace libtorrent
// where the data for this file was found. // where the data for this file was found.
bool symlink_attribute:1; bool symlink_attribute:1;
}; };
#endif // TORRENT_NO_DEPRECATE
// internal // internal
struct TORRENT_DEPRECATED_EXPORT internal_file_entry struct TORRENT_DEPRECATED_EXPORT internal_file_entry
@ -130,22 +129,6 @@ namespace libtorrent
, path_index(-1) , path_index(-1)
{} {}
internal_file_entry(file_entry const& e)
: offset(e.offset)
, symlink_index(not_a_symlink)
, no_root_dir(false)
, size(e.size)
, name_len(name_is_owned)
, pad_file(e.pad_file)
, hidden_attribute(e.hidden_attribute)
, executable_attribute(e.executable_attribute)
, symlink_attribute(e.symlink_attribute)
, name(NULL)
, path_index(-1)
{
set_name(e.path.c_str());
}
internal_file_entry(internal_file_entry const& fe); internal_file_entry(internal_file_entry const& fe);
internal_file_entry& operator=(internal_file_entry const& fe); internal_file_entry& operator=(internal_file_entry const& fe);
@ -265,11 +248,35 @@ namespace libtorrent
// of files to be added is known up-front. // of files to be added is known up-front.
void reserve(int num_files); void reserve(int num_files);
// Adds a file to the file storage. The ``flags`` argument sets // Adds a file to the file storage. The ``add_file_borrow`` version
// attributes on the file. The file attributes is an extension and may // expects that ``filename`` points to a string of ``filename_len``
// not work in all bittorrent clients. // bytes that is the file name (without a path) of the file that's
// being added. This memory is *borrowed*, i.e. it is the caller's
// responsibility to make sure it stays valid throughout the lifetime
// of this file_storage object or any copy of it. The same thing applies
// to ``filehash``, wich is an optional pointer to a 20 byte binary
// SHA-1 hash of the file.
//
// if ``filename`` is NULL, the filename from ``path`` is used and not
// borrowed. In this case ``filename_len`` is ignored.
//
// The ``path`` argument is the full path (in the torrent file) to
// the file to add. Note that this is not supposed to be an absolute
// path, but it is expected to include the name of the torrent as the
// first path element.
//
// ``file_size`` is the size of the file in bytes.
//
// The ``file_flags`` argument sets attributes on the file. The file
// attributes is an extension and may not work in all bittorrent clients.
// //
// For possible file attributes, see file_storage::flags_t. // For possible file attributes, see file_storage::flags_t.
//
// The ``mtime`` argument is optional and can be set to 0. If non-zero,
// it is the posix time of the last modification time of this file.
//
// ``symlink_path`` is the path the is a symlink to. To make this a
// symlink you also need to set the file_storage::flag_symlink file flag.
// //
// If more files than one are added, certain restrictions to their paths // If more files than one are added, certain restrictions to their paths
// apply. In a multi-file file storage (torrent), all files must share // apply. In a multi-file file storage (torrent), all files must share
@ -278,16 +285,12 @@ namespace libtorrent
// That is, the first path element of all files must be the same. // That is, the first path element of all files must be the same.
// This shared path element is also set to the name of the torrent. It // This shared path element is also set to the name of the torrent. It
// can be changed by calling ``set_name``. // can be changed by calling ``set_name``.
// void add_file_borrow(char const* filename, int filename_len
// The ``filehash`` argument is an optional pointer to a sha-1 hash (20 , std::string const& path, boost::int64_t file_size
// bytes) of the file. The hash is not copied into the file_storage , boost::uint32_t file_flags = 0, char const* filehash = 0
// object, but the pointer is expected to point to memory that stays , boost::int64_t mtime = 0, std::string const& symlink_path = "");
// valid throughout the life time of the file_storage. void add_file(std::string const& path, boost::int64_t file_size, int file_flags = 0
// , std::time_t mtime = 0, std::string const& symlink_path = "");
// Currently, the ``filehash`` from ``file_entry`` is not used.
void add_file(file_entry const& e, char const* filehash = 0);
void add_file(std::string const& p, boost::int64_t size, int flags = 0
, std::time_t mtime = 0, std::string const& s_p = "");
// renames the file at ``index`` to ``new_filename``. Keep in mind // renames the file at ``index`` to ``new_filename``. Keep in mind
// that filenames are expected to be UTF-8 encoded. // that filenames are expected to be UTF-8 encoded.
@ -299,11 +302,14 @@ namespace libtorrent
// duplicate names in memory. // duplicate names in memory.
void rename_file_borrow(int index, char const* new_filename, int len); void rename_file_borrow(int index, char const* new_filename, int len);
#ifndef TORRENT_NO_DEPRECATE
TORRENT_DEPRECATED_PREFIX
void add_file(file_entry const& fe, char const* infohash = NULL) TORRENT_DEPRECATED;
#if TORRENT_USE_WSTRING #if TORRENT_USE_WSTRING
// all wstring APIs are deprecated since 0.16.11 // all wstring APIs are deprecated since 0.16.11
// instead, use the wchar -> utf8 conversion functions // instead, use the wchar -> utf8 conversion functions
// and pass in utf8 strings // and pass in utf8 strings
#ifndef TORRENT_NO_DEPRECATE
TORRENT_DEPRECATED_PREFIX TORRENT_DEPRECATED_PREFIX
void add_file(std::wstring const& p, boost::int64_t size, int flags = 0 void add_file(std::wstring const& p, boost::int64_t size, int flags = 0
, std::time_t mtime = 0, std::string const& s_p = "") TORRENT_DEPRECATED; , std::time_t mtime = 0, std::string const& s_p = "") TORRENT_DEPRECATED;
@ -313,8 +319,8 @@ namespace libtorrent
void set_name(std::wstring const& n) TORRENT_DEPRECATED; void set_name(std::wstring const& n) TORRENT_DEPRECATED;
void rename_file_deprecated(int index, std::wstring const& new_filename); void rename_file_deprecated(int index, std::wstring const& new_filename);
#endif // TORRENT_NO_DEPRECATE
#endif // TORRENT_USE_WSTRING #endif // TORRENT_USE_WSTRING
#endif // TORRENT_NO_DEPRECATE
// returns a list of file_slice objects representing the portions of // returns a list of file_slice objects representing the portions of
// files the specified piece index, byte offset and size range overlaps. // files the specified piece index, byte offset and size range overlaps.
@ -354,6 +360,11 @@ namespace libtorrent
TORRENT_DEPRECATED_PREFIX TORRENT_DEPRECATED_PREFIX
file_entry at(iterator i) const TORRENT_DEPRECATED; file_entry at(iterator i) const TORRENT_DEPRECATED;
// returns a file_entry with information about the file
// at ``index``. Index must be in the range [0, ``num_files()`` ).
TORRENT_DEPRECATED_PREFIX
file_entry at(int index) const TORRENT_DEPRECATED;
iterator begin_deprecated() const { return m_files.begin(); } iterator begin_deprecated() const { return m_files.begin(); }
iterator end_deprecated() const { return m_files.end(); } iterator end_deprecated() const { return m_files.end(); }
reverse_iterator rbegin_deprecated() const { return m_files.rbegin(); } reverse_iterator rbegin_deprecated() const { return m_files.rbegin(); }
@ -365,10 +376,6 @@ namespace libtorrent
int num_files() const int num_files() const
{ return int(m_files.size()); } { return int(m_files.size()); }
// returns a file_entry with information about the file
// at ``index``. Index must be in the range [0, ``num_files()`` ).
file_entry at(int index) const;
// returns the total number of bytes all the files in this torrent spans // returns the total number of bytes all the files in this torrent spans
boost::int64_t total_size() const { return m_total_size; } boost::int64_t total_size() const { return m_total_size; }
@ -388,7 +395,7 @@ namespace libtorrent
// set and get the name of this torrent. For multi-file torrents, this is also // set and get the name of this torrent. For multi-file torrents, this is also
// the name of the root directory all the files are stored in. // the name of the root directory all the files are stored in.
void set_name(std::string const& n) { m_name = n; } void set_name(std::string const& n) { m_name = n; }
const std::string& name() const { return m_name; } std::string const& name() const { return m_name; }
// swap all content of *this* with *ti*. // swap all content of *this* with *ti*.
void swap(file_storage& ti) void swap(file_storage& ti)
@ -487,9 +494,9 @@ namespace libtorrent
int file_flags(int index) const; int file_flags(int index) const;
// The file base of a file is the offset within the file on the filsystem // 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 // where it starts to write. For the most part, this is 0. It's possible
// possible to map several files (in the torrent) into a single file on // to map several files (in the torrent) into a single file on the
// the filesystem by making them all point to the same filename, but with // filesystem by making them all point to the same filename, but with
// different file bases, so that they don't overlap. // different file bases, so that they don't overlap.
// torrent_info::remap_files() can be used to use a new file layout. // torrent_info::remap_files() can be used to use a new file layout.
boost::int64_t file_base(int index) const; boost::int64_t file_base(int index) const;
@ -549,12 +556,15 @@ namespace libtorrent
// the list of files that this torrent consists of // the list of files that this torrent consists of
std::vector<internal_file_entry> m_files; std::vector<internal_file_entry> m_files;
// if there are sha1 hashes for each individual file // if there are sha1 hashes for each individual file there are as many
// there are as many entries in this array as the // entries in this array as the m_files array. Each entry in m_files has
// m_files array. Each entry in m_files has a corresponding // a corresponding hash pointer in this array. The reason to split it up
// hash pointer in this array. The reason to split it up // in separate arrays is to save memory in case the torrent doesn't have
// in separate arrays is to save memory in case the torrent // file hashes
// doesn't have file hashes // the pointers in this vector are pointing into the .torrent file in
// memory which is _not_ owned by this file_storage object. It's simply
// a non-owning pointer. It is the user's responsibility that the hash
// stays valid throughout the lifetime of this file_storage object.
std::vector<char const*> m_file_hashes; std::vector<char const*> m_file_hashes;
// for files that are symlinks, the symlink // for files that are symlinks, the symlink

View File

@ -483,12 +483,13 @@ namespace libtorrent
file_iterator file_at_offset(boost::int64_t offset) const TORRENT_DEPRECATED file_iterator file_at_offset(boost::int64_t offset) const TORRENT_DEPRECATED
{ return m_files.file_at_offset_deprecated(offset); } { return m_files.file_at_offset_deprecated(offset); }
TORRENT_DEPRECATED_PREFIX
file_entry file_at(int index) const TORRENT_DEPRECATED{ return m_files.at(index); }
#endif // TORRENT_NO_DEPRECATE #endif // TORRENT_NO_DEPRECATE
// If you need index-access to files you can use the ``num_files()`` and // If you need index-access to files you can use the ``num_files()`` and
// ``file_at()`` to access files using indices. // ``file_at()`` to access files using indices.
int num_files() const { return m_files.num_files(); } int num_files() const { return m_files.num_files(); }
file_entry file_at(int index) const { return m_files.at(index); }
// This function will map a piece index, a byte offset within that piece // 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 // and a size (in bytes) into the corresponding files with offsets where

View File

@ -490,26 +490,26 @@ namespace libtorrent
if (!m_multifile) if (!m_multifile)
{ {
file_entry e = m_files.at(0); if (m_include_mtime) info["mtime"] = m_files.mtime(0);
if (m_include_mtime) info["mtime"] = e.mtime; info["length"] = m_files.file_size(0);
info["length"] = e.size; int flags = m_files.file_flags(0);
if (e.pad_file if (flags & (file_storage::flag_pad_file
|| e.hidden_attribute | file_storage::flag_hidden
|| e.executable_attribute | file_storage::flag_executable
|| e.symlink_attribute) | file_storage::flag_symlink))
{ {
std::string& attr = info["attr"].string(); std::string& attr = info["attr"].string();
if (e.pad_file) attr += 'p'; if (flags & file_storage::flag_pad_file) attr += 'p';
if (e.hidden_attribute) attr += 'h'; if (flags & file_storage::flag_hidden) attr += 'h';
if (e.executable_attribute) attr += 'x'; if (flags & file_storage::flag_executable) attr += 'x';
if (m_include_symlinks && e.symlink_attribute) attr += 'l'; if (m_include_symlinks && (flags & file_storage::flag_symlink)) attr += 'l';
} }
if (m_include_symlinks if (m_include_symlinks
&& e.symlink_attribute) && (flags & file_storage::flag_symlink))
{ {
entry& sympath_e = info["symlink path"]; entry& sympath_e = info["symlink path"];
std::string split = split_path(e.symlink_path); std::string split = split_path(m_files.symlink(0));
for (char const* e = split.c_str(); e != 0; e = next_path_element(e)) for (char const* e = split.c_str(); e != 0; e = next_path_element(e))
sympath_e.list().push_back(entry(e)); sympath_e.list().push_back(entry(e));
} }

View File

@ -835,7 +835,6 @@ namespace libtorrent
if (storage) if (storage)
{ {
boost::unordered_set<cached_piece_entry*> const& pieces = storage->cached_pieces(); boost::unordered_set<cached_piece_entry*> const& pieces = storage->cached_pieces();
// TODO: 2 should this be allocated on the stack?
std::vector<int> piece_index; std::vector<int> piece_index;
piece_index.reserve(pieces.size()); piece_index.reserve(pieces.size());
for (boost::unordered_set<cached_piece_entry*>::const_iterator i = pieces.begin() for (boost::unordered_set<cached_piece_entry*>::const_iterator i = pieces.begin()

View File

@ -132,6 +132,7 @@ namespace libtorrent
e.set_name(leaf); e.set_name(leaf);
} }
#ifndef TORRENT_NO_DEPRECATE
file_entry::file_entry(): offset(0), size(0), file_base(0) file_entry::file_entry(): offset(0), size(0), file_base(0)
, mtime(0), pad_file(false), hidden_attribute(false) , mtime(0), pad_file(false), hidden_attribute(false)
, executable_attribute(false) , executable_attribute(false)
@ -139,6 +140,7 @@ namespace libtorrent
{} {}
file_entry::~file_entry() {} file_entry::~file_entry() {}
#endif // TORRENT_NO_DEPRECATE
internal_file_entry::~internal_file_entry() internal_file_entry::~internal_file_entry()
{ {
@ -231,8 +233,21 @@ namespace libtorrent
} }
} }
#if TORRENT_USE_WSTRING
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
void file_storage::add_file(file_entry const& fe, char const* infohash)
{
int flags = 0;
if (fe.pad_file) flags |= file_storage::flag_pad_file;
if (fe.hidden_attribute) flags |= file_storage::flag_hidden;
if (fe.executable_attribute) flags |= file_storage::flag_executable;
if (fe.symlink_attribute) flags |= file_storage::flag_symlink;
add_file_borrow(NULL, 0, fe.path, fe.size, flags, NULL, fe.mtime
, fe.symlink_path);
}
#if TORRENT_USE_WSTRING
void file_storage::set_name(std::wstring const& n) void file_storage::set_name(std::wstring const& n)
{ {
std::string utf8; std::string utf8;
@ -249,20 +264,20 @@ namespace libtorrent
update_path_index(m_files[index]); update_path_index(m_files[index]);
} }
void file_storage::add_file(std::wstring const& file, boost::int64_t size, int flags void file_storage::add_file(std::wstring const& file, boost::int64_t file_size
, std::time_t mtime, std::string const& symlink_path) , int file_flags, std::time_t mtime, std::string const& symlink_path)
{ {
std::string utf8; std::string utf8;
wchar_utf8(file, utf8); wchar_utf8(file, utf8);
add_file(utf8, size, flags, mtime, symlink_path); add_file(utf8, file_size, file_flags, mtime, symlink_path);
} }
void file_storage::rename_file(int index, std::wstring const& new_filename) void file_storage::rename_file(int index, std::wstring const& new_filename)
{ {
rename_file_deprecated(index, new_filename); rename_file_deprecated(index, new_filename);
} }
#endif // TORRENT_NO_DEPRECATE
#endif // TORRENT_USE_WSTRING #endif // TORRENT_USE_WSTRING
#endif // TORRENT_NO_DEPRECATE
void file_storage::rename_file(int index, std::string const& new_filename) void file_storage::rename_file(int index, std::string const& new_filename)
{ {
@ -375,6 +390,7 @@ namespace libtorrent
return ret; return ret;
} }
#ifndef TORRENT_NO_DEPRECATE
file_entry file_storage::at(int index) const file_entry file_storage::at(int index) const
{ {
TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size())); TORRENT_ASSERT_PRECOND(index >= 0 && index < int(m_files.size()));
@ -394,6 +410,7 @@ namespace libtorrent
ret.filehash = hash(index); ret.filehash = hash(index);
return ret; return ret;
} }
#endif // TORRENT_NO_DEPRECATE
peer_request file_storage::map_file(int file_index, boost::int64_t file_offset peer_request file_storage::map_file(int file_index, boost::int64_t file_offset
, int size) const , int size) const
@ -430,99 +447,77 @@ namespace libtorrent
return ret; return ret;
} }
void file_storage::add_file(std::string const& file, boost::int64_t size, int flags void file_storage::add_file(std::string const& path, boost::int64_t file_size
, std::time_t mtime, std::string const& symlink_path) , int file_flags, std::time_t mtime, std::string const& symlink_path)
{ {
TORRENT_ASSERT_PRECOND(!is_complete(file)); add_file_borrow(NULL, 0, path, file_size, file_flags, NULL, mtime
TORRENT_ASSERT_PRECOND(size >= 0); , symlink_path);
if (size < 0) size = 0;
if (!has_parent_path(file))
{
// you have already added at least one file with a
// path to the file (branch_path), which means that
// all the other files need to be in the same top
// directory as the first file.
TORRENT_ASSERT_PRECOND(m_files.empty());
m_name = file;
}
else
{
if (m_files.empty())
m_name = split_path(file).c_str();
}
TORRENT_ASSERT_PRECOND(m_name == split_path(file).c_str());
m_files.push_back(internal_file_entry());
++m_num_files;
internal_file_entry& e = m_files.back();
e.set_name(file.c_str());
e.size = size;
e.offset = m_total_size;
e.pad_file = (flags & pad_file) != 0;
e.hidden_attribute = (flags & attribute_hidden) != 0;
e.executable_attribute = (flags & attribute_executable) != 0;
if ((flags & attribute_symlink) && m_symlinks.size() < internal_file_entry::not_a_symlink - 1)
{
e.symlink_attribute = 1;
e.symlink_index = m_symlinks.size();
m_symlinks.push_back(symlink_path);
}
else
e.symlink_attribute = 0;
if (mtime)
{
if (m_mtime.size() < m_files.size()) m_mtime.resize(m_files.size());
m_mtime[m_files.size() - 1] = mtime;
}
update_path_index(e);
m_total_size += size;
} }
// TODO: 2 it would be nice if file_entry::filehash could be taken into void file_storage::add_file_borrow(char const* filename, int filename_len
// account as well, and if the file_storage object could actually hold , std::string const& path, boost::int64_t file_size
// copies of filehash , boost::uint32_t file_flags, char const* filehash
void file_storage::add_file(file_entry const& ent, char const* filehash) , boost::int64_t mtime, std::string const& symlink_path)
{ {
TORRENT_ASSERT_PRECOND(ent.size >= 0); TORRENT_ASSERT_PRECOND(file_size >= 0);
if (!has_parent_path(ent.path)) if (!has_parent_path(path))
{ {
// you have already added at least one file with a // you have already added at least one file with a
// path to the file (branch_path), which means that // path to the file (branch_path), which means that
// all the other files need to be in the same top // all the other files need to be in the same top
// directory as the first file. // directory as the first file.
TORRENT_ASSERT_PRECOND(m_files.empty()); TORRENT_ASSERT_PRECOND(m_files.empty());
m_name = ent.path; m_name = path;
} }
else else
{ {
if (m_files.empty()) if (m_files.empty())
m_name = split_path(ent.path).c_str(); m_name = split_path(path).c_str();
} }
internal_file_entry ife(ent); internal_file_entry ife;
int file_index = m_files.size();
m_files.push_back(ife); m_files.push_back(ife);
++m_num_files;
internal_file_entry& e = m_files.back(); internal_file_entry& e = m_files.back();
// first set the filename to the full path so update_path_index()
// can do its thing, then rename it to point to the borrowed filename
// pointer
e.set_name(path.c_str());
update_path_index(e);
// filename is allowed to be NULL, in which case we just use path
if (filename)
e.set_name(filename, true, filename_len);
e.size = file_size;
e.offset = m_total_size; e.offset = m_total_size;
m_total_size += e.size; e.pad_file = file_flags & file_storage::flag_pad_file;
e.hidden_attribute = file_flags & file_storage::flag_hidden;
e.executable_attribute = file_flags & file_storage::flag_executable;
e.symlink_attribute = file_flags & file_storage::flag_symlink;
if (filehash) if (filehash)
{ {
if (m_file_hashes.size() < m_files.size()) m_file_hashes.resize(m_files.size()); if (m_file_hashes.size() < m_files.size()) m_file_hashes.resize(m_files.size());
m_file_hashes[m_files.size() - 1] = filehash; m_file_hashes[m_files.size() - 1] = filehash;
} }
if (!ent.symlink_path.empty() && m_symlinks.size() < internal_file_entry::not_a_symlink - 1) if (!symlink_path.empty()
&& m_symlinks.size() < internal_file_entry::not_a_symlink - 1)
{ {
e.symlink_index = m_symlinks.size(); e.symlink_index = m_symlinks.size();
m_symlinks.push_back(ent.symlink_path); m_symlinks.push_back(symlink_path);
} }
if (ent.mtime) else
{
e.symlink_attribute = false;
}
if (mtime)
{ {
if (m_mtime.size() < m_files.size()) m_mtime.resize(m_files.size()); if (m_mtime.size() < m_files.size()) m_mtime.resize(m_files.size());
m_mtime[m_files.size() - 1] = ent.mtime; m_mtime[m_files.size() - 1] = mtime;
} }
if (ent.file_base) set_file_base(file_index, ent.file_base);
update_path_index(e); ++m_num_files;
m_total_size += e.size;
} }
sha1_hash file_storage::hash(int index) const sha1_hash file_storage::hash(int index) const

View File

@ -357,47 +357,77 @@ namespace libtorrent
if (path.empty()) path = "_"; if (path.empty()) path = "_";
} }
bool extract_single_file(lazy_entry const& dict, file_entry& target // top level is extracting the file for a single-file torrent. The
, std::string const& root_dir, lazy_entry const** filehash // distinction is that the filename is found in "name" rather than
, lazy_entry const** filename, time_t* mtime) // "path"
bool extract_single_file(lazy_entry const& dict, file_storage& files
, std::string const& root_dir, ptrdiff_t info_ptr_diff, bool top_level
, error_code& ec)
{ {
if (dict.type() != lazy_entry::dict_t) return false; if (dict.type() != lazy_entry::dict_t) return false;
lazy_entry const* length = dict.dict_find("length"); boost::int64_t file_size = dict.dict_find_int_value("length", -1);
if (length == 0 || length->type() != lazy_entry::int_t) if (file_size < 0)
return false; {
target.size = length->int_value(); ec = errors::torrent_invalid_length;
if (target.size < 0)
return false; return false;
}
boost::int64_t ts = dict.dict_find_int_value("mtime", -1); boost::int64_t mtime = dict.dict_find_int_value("mtime", 0);
if (ts > 0) *mtime = std::time_t(ts);
// prefer the name.utf-8
// because if it exists, it is more
// likely to be correctly encoded
lazy_entry const* p = dict.dict_find("path.utf-8");
if (p == 0 || p->type() != lazy_entry::list_t)
p = dict.dict_find("path");
if (p == 0 || p->type() != lazy_entry::list_t)
return false;
// prefer the name.utf-8 because if it exists, it is more likely to be
// correctly encoded
std::string path = root_dir; std::string path = root_dir;
std::string path_element; std::string path_element;
for (int i = 0, end(p->list_size()); i < end; ++i) char const* filename = NULL;
int filename_len = 0;
if (top_level)
{ {
if (p->list_at(i)->type() != lazy_entry::string_t) lazy_entry const* p = dict.dict_find_string("name.utf-8");
if (p == 0) p = dict.dict_find_string("name");
if (p == 0 || p->string_length() == 0)
{
ec = errors::torrent_missing_name;
return false; return false;
if (i == end - 1) *filename = p->list_at(i); }
sanitize_append_path_element(path
, p->list_at(i)->string_ptr(), p->list_at(i)->string_length()); filename = p->string_ptr() + info_ptr_diff;
filename_len = p->string_length();
sanitize_append_path_element(path, p->string_ptr(), p->string_length());
// if (path.empty()) path = to_hex(files.info_hash().to_string());
}
else
{
lazy_entry const* p = dict.dict_find_list("path.utf-8");
if (p == 0) p = dict.dict_find_list("path");
if (p == 0 || p->list_size() == 0)
{
ec = errors::torrent_missing_name;
return false;
}
for (int i = 0, end(p->list_size()); i < end; ++i)
{
lazy_entry const* e = p->list_at(i);
if (e->type() != lazy_entry::string_t)
{
ec = errors::torrent_missing_name;
return false;
}
if (i == end - 1)
{
filename = e->string_ptr() + info_ptr_diff;
filename_len = e->string_length();
}
sanitize_append_path_element(path, e->string_ptr(), e->string_length());
}
} }
// bitcomet pad file // bitcomet pad file
boost::uint32_t file_flags = 0;
if (path.find("_____padding_file_") != std::string::npos) if (path.find("_____padding_file_") != std::string::npos)
target.pad_file = true; file_flags = file_storage::flag_pad_file;
target.path = path;
lazy_entry const* attr = dict.dict_find_string("attr"); lazy_entry const* attr = dict.dict_find_string("attr");
if (attr) if (attr)
@ -406,32 +436,45 @@ namespace libtorrent
{ {
switch (attr->string_ptr()[i]) switch (attr->string_ptr()[i])
{ {
case 'l': target.symlink_attribute = true; target.size = 0; break; case 'l': file_flags |= file_storage::flag_symlink; file_size = 0; break;
case 'x': target.executable_attribute = true; break; case 'x': file_flags |= file_storage::flag_executable; break;
case 'h': target.hidden_attribute = true; break; case 'h': file_flags |= file_storage::flag_hidden; break;
case 'p': target.pad_file = true; break; case 'p': file_flags |= file_storage::flag_pad_file; break;
} }
} }
} }
lazy_entry const* fh = dict.dict_find_string("sha1"); lazy_entry const* fh = dict.dict_find_string("sha1");
if (fh && fh->string_length() == 20 && filehash) char const* filehash = NULL;
*filehash = fh; if (fh && fh->string_length() == 20)
filehash = fh->string_ptr() + info_ptr_diff;
std::string symlink_path;
lazy_entry const* s_p = dict.dict_find("symlink path"); lazy_entry const* s_p = dict.dict_find("symlink path");
if (s_p != 0 && s_p->type() == lazy_entry::list_t && target.symlink_attribute) if (s_p != 0 && s_p->type() == lazy_entry::list_t
&& (file_flags & file_storage::flag_symlink))
{ {
for (int i = 0, end(s_p->list_size()); i < end; ++i) for (int i = 0, end(s_p->list_size()); i < end; ++i)
{ {
std::string path_element = s_p->list_at(i)->string_value(); std::string path_element = s_p->list_at(i)->string_value();
target.symlink_path = combine_path(target.symlink_path, path_element); symlink_path = combine_path(symlink_path, path_element);
} }
} }
else else
{ {
target.symlink_attribute = false; file_flags &= ~file_storage::flag_symlink;
} }
if (filename_len > path.length()
|| path.compare(path.size() - filename_len, filename_len, filename) != 0)
{
// if the filename was sanitized and differ, clear it to just use path
filename = NULL;
filename_len = 0;
}
files.add_file_borrow(filename, filename_len, path, file_size, file_flags, filehash
, mtime, symlink_path);
return true; return true;
} }
@ -495,32 +538,20 @@ namespace libtorrent
#endif #endif
bool extract_files(lazy_entry const& list, file_storage& target bool extract_files(lazy_entry const& list, file_storage& target
, std::string const& root_dir, ptrdiff_t info_ptr_diff) , std::string const& root_dir, ptrdiff_t info_ptr_diff, error_code& ec)
{ {
if (list.type() != lazy_entry::list_t) return false; if (list.type() != lazy_entry::list_t)
{
ec = errors::torrent_file_parse_failed;
return false;
}
target.reserve(list.list_size()); target.reserve(list.list_size());
for (int i = 0, end(list.list_size()); i < end; ++i) for (int i = 0, end(list.list_size()); i < end; ++i)
{ {
lazy_entry const* file_hash = 0; if (!extract_single_file(*list.list_at(i), target, root_dir
time_t mtime = 0; , info_ptr_diff, false, ec))
file_entry e;
lazy_entry const* fee = 0;
if (!extract_single_file(*list.list_at(i), e, root_dir
, &file_hash, &fee, &mtime))
return false; return false;
target.add_file(e, file_hash ? file_hash->string_ptr() + info_ptr_diff : 0);
// 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
int last_index = target.num_files() - 1;
// this string pointer does not necessarily point into
// the m_info_section buffer.
char const* str_ptr = fee->string_ptr() + info_ptr_diff;
target.rename_file_borrow(last_index, str_ptr, fee->string_length());
} }
return true; return true;
} }
@ -565,7 +596,7 @@ namespace libtorrent
if (ec) return -1; if (ec) return -1;
if (s > limit) if (s > limit)
{ {
ec = error_code(errors::metadata_too_large, get_libtorrent_category()); ec = errors::metadata_too_large;
return -2; return -2;
} }
v.resize((unsigned int)s); v.resize((unsigned int)s);
@ -1151,61 +1182,15 @@ namespace libtorrent
{ {
// if there's no list of files, there has to be a length // if there's no list of files, there has to be a length
// field. // field.
file_entry e; if (!extract_single_file(info, files, "", info_ptr_diff, true, ec))
e.path = name;
e.offset = 0;
e.size = info.dict_find_int_value("length", -1);
if (e.size < 0)
{
ec = errors::torrent_invalid_length;
return false; return false;
}
e.mtime = info.dict_find_int_value("mtime", 0);
lazy_entry const* attr = info.dict_find_string("attr");
if (attr)
{
for (int i = 0; i < attr->string_length(); ++i)
{
switch (attr->string_ptr()[i])
{
case 'l': e.symlink_attribute = true; e.size = 0; break;
case 'x': e.executable_attribute = true; break;
case 'h': e.hidden_attribute = true; break;
case 'p': e.pad_file = true; break;
}
}
}
lazy_entry const* s_p = info.dict_find("symlink path");
if (s_p != 0 && s_p->type() == lazy_entry::list_t)
{
for (int i = 0, end(s_p->list_size()); i < end; ++i)
{
std::string path_element = s_p->list_at(i)->string_value();
e.symlink_path = combine_path(e.symlink_path, path_element);
}
}
else
{
e.symlink_attribute = false;
}
lazy_entry const* fh = info.dict_find_string("sha1");
if (fh && fh->string_length() != 20) fh = 0;
// bitcomet pad file
if (e.path.find("_____padding_file_") != std::string::npos)
e.pad_file = true;
files.add_file(e, fh ? fh->string_ptr() + info_ptr_diff : 0);
m_multifile = false; m_multifile = false;
} }
else else
{ {
if (!extract_files(*i, files, name, info_ptr_diff)) if (!extract_files(*i, files, name, info_ptr_diff, ec))
{
ec = errors::torrent_file_parse_failed;
return false; return false;
}
m_multifile = true; m_multifile = true;
} }
TORRENT_ASSERT(!files.name().empty()); TORRENT_ASSERT(!files.name().empty());

View File

@ -244,7 +244,7 @@ void web_peer_connection::write_request(peer_request const& r)
if (m_path.empty()) m_path += "/" + t->torrent_file().name(); if (m_path.empty()) m_path += "/" + t->torrent_file().name();
else if (m_path[m_path.size() - 1] == '/') else if (m_path[m_path.size() - 1] == '/')
{ {
std::string tmp = t->torrent_file().files().at(0).path; std::string tmp = t->torrent_file().files().file_path(0);
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
convert_path_to_posix(tmp); convert_path_to_posix(tmp);
#endif #endif
@ -252,7 +252,7 @@ void web_peer_connection::write_request(peer_request const& r)
} }
else if (!m_url.empty() && m_url[m_url.size() - 1] == '/') else if (!m_url.empty() && m_url[m_url.size() - 1] == '/')
{ {
std::string tmp = t->torrent_file().files().at(0).path; std::string tmp = t->torrent_file().files().file_path(0);
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
convert_path_to_posix(tmp); convert_path_to_posix(tmp);
#endif #endif

View File

@ -85,10 +85,10 @@ void test_storage()
for (int i = 0; i < ti.num_files(); ++i) for (int i = 0; i < ti.num_files(); ++i)
{ {
std::string p = ti.file_at(i).path; std::string p = ti.files().file_path(i);
convert_path_to_posix(p); convert_path_to_posix(p);
fprintf(stderr, "%s == %s\n", p.c_str(), filenames[i]); fprintf(stderr, "%s == %s\n", p.c_str(), filenames[i]);
TEST_CHECK(p == filenames[i]); TEST_EQUAL(p, filenames[i]);
} }
} }
@ -100,17 +100,6 @@ void test_copy()
combine_path(parent_path(current_working_directory()) combine_path(parent_path(current_working_directory())
, combine_path("test_torrents", "sample.torrent")))); , combine_path("test_torrents", "sample.torrent"))));
boost::shared_ptr<torrent_info> b(boost::make_shared<torrent_info>(*a));
// clear out the buffer for a, just to make sure b doesn't have any
// references into it by mistake
int s = a->metadata_size();
memset(a->metadata().get(), 0, s);
a.reset();
TEST_EQUAL(b->num_files(), 3);
char const* expected_files[] = char const* expected_files[] =
{ {
"sample/text_file2.txt", "sample/text_file2.txt",
@ -125,9 +114,31 @@ void test_copy()
sha1_hash("abababababababababab") sha1_hash("abababababababababab")
}; };
for (int i = 0; i < a->num_files(); ++i)
{
std::string p = a->files().file_path(i);
convert_path_to_posix(p);
TEST_EQUAL(p, expected_files[i]);
fprintf(stderr, "%s\n", p.c_str());
TEST_EQUAL(a->files().hash(i), file_hashes[i]);
}
// copy the torrent_info object
boost::shared_ptr<torrent_info> b(boost::make_shared<torrent_info>(*a));
// clear out the buffer for a, just to make sure b doesn't have any
// references into it by mistake
int s = a->metadata_size();
memset(a->metadata().get(), 0, s);
a.reset();
TEST_EQUAL(b->num_files(), 3);
for (int i = 0; i < b->num_files(); ++i) for (int i = 0; i < b->num_files(); ++i)
{ {
std::string p = b->file_at(i).path; std::string p = b->files().file_path(i);
convert_path_to_posix(p); convert_path_to_posix(p);
TEST_EQUAL(p, expected_files[i]); TEST_EQUAL(p, expected_files[i]);
fprintf(stderr, "%s\n", p.c_str()); fprintf(stderr, "%s\n", p.c_str());

View File

@ -96,14 +96,14 @@ test_failing_torrent_t test_error_torrents[] =
{ "invalid_info.torrent", errors::torrent_missing_info }, { "invalid_info.torrent", errors::torrent_missing_info },
{ "string.torrent", errors::torrent_is_no_dict }, { "string.torrent", errors::torrent_is_no_dict },
{ "negative_size.torrent", errors::torrent_invalid_length }, { "negative_size.torrent", errors::torrent_invalid_length },
{ "negative_file_size.torrent", errors::torrent_file_parse_failed }, { "negative_file_size.torrent", errors::torrent_invalid_length },
{ "invalid_path_list.torrent", errors::torrent_file_parse_failed }, { "invalid_path_list.torrent", errors::torrent_missing_name},
{ "missing_path_list.torrent", errors::torrent_file_parse_failed }, { "missing_path_list.torrent", errors::torrent_missing_name },
{ "invalid_pieces.torrent", errors::torrent_missing_pieces }, { "invalid_pieces.torrent", errors::torrent_missing_pieces },
{ "unaligned_pieces.torrent", errors::torrent_invalid_hashes }, { "unaligned_pieces.torrent", errors::torrent_invalid_hashes },
{ "invalid_root_hash.torrent", errors::torrent_invalid_hashes }, { "invalid_root_hash.torrent", errors::torrent_invalid_hashes },
{ "invalid_root_hash2.torrent", errors::torrent_missing_pieces}, { "invalid_root_hash2.torrent", errors::torrent_missing_pieces },
{ "invalid_file_size.torrent", errors::torrent_file_parse_failed }, { "invalid_file_size.torrent", errors::torrent_invalid_length },
}; };
namespace libtorrent namespace libtorrent
@ -377,14 +377,14 @@ int test_main()
{ {
// make sure we disambiguated the files // make sure we disambiguated the files
TEST_EQUAL(ti->num_files(), 2); TEST_EQUAL(ti->num_files(), 2);
TEST_CHECK(ti->file_at(0).path == combine_path(combine_path("temp", "foo"), "bar.txt")); TEST_CHECK(ti->files().file_path(0) == combine_path(combine_path("temp", "foo"), "bar.txt"));
TEST_CHECK(ti->file_at(1).path == combine_path(combine_path("temp", "foo"), "bar.1.txt")); TEST_CHECK(ti->files().file_path(1) == combine_path(combine_path("temp", "foo"), "bar.1.txt"));
} }
else if (std::string(test_torrents[i].file) == "pad_file.torrent") else if (std::string(test_torrents[i].file) == "pad_file.torrent")
{ {
TEST_EQUAL(ti->num_files(), 2); TEST_EQUAL(ti->num_files(), 2);
TEST_EQUAL(ti->file_at(0).pad_file, false); TEST_EQUAL(ti->files().file_flags(0) & file_storage::flag_pad_file, false);
TEST_EQUAL(ti->file_at(1).pad_file, true); TEST_EQUAL(ti->files().file_flags(1) & file_storage::flag_pad_file, true);
} }
else if (std::string(test_torrents[i].file) == "creation_date.torrent") else if (std::string(test_torrents[i].file) == "creation_date.torrent")
{ {
@ -444,24 +444,24 @@ int test_main()
{ {
TEST_EQUAL(ti->num_files(), 1); TEST_EQUAL(ti->num_files(), 1);
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
TEST_EQUAL(ti->file_at(0).path, "temp\\bar"); TEST_EQUAL(ti->files().file_path(0), "temp\\bar");
#else #else
TEST_EQUAL(ti->file_at(0).path, "temp/bar"); TEST_EQUAL(ti->files().file_path(0), "temp/bar");
#endif #endif
} }
else if (std::string(test_torrents[i].file) == "slash_path2.torrent") else if (std::string(test_torrents[i].file) == "slash_path2.torrent")
{ {
TEST_EQUAL(ti->num_files(), 1); TEST_EQUAL(ti->num_files(), 1);
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
TEST_EQUAL(ti->file_at(0).path, "temp\\abc....def\\bar"); TEST_EQUAL(ti->files().file_path(0), "temp\\abc....def\\bar");
#else #else
TEST_EQUAL(ti->file_at(0).path, "temp/abc....def/bar"); TEST_EQUAL(ti->files().file_path(0), "temp/abc....def/bar");
#endif #endif
} }
else if (std::string(test_torrents[i].file) == "slash_path3.torrent") else if (std::string(test_torrents[i].file) == "slash_path3.torrent")
{ {
TEST_EQUAL(ti->num_files(), 1); TEST_EQUAL(ti->num_files(), 1);
TEST_EQUAL(ti->file_at(0).path, "temp....abc"); TEST_EQUAL(ti->files().file_path(0), "temp....abc");
} }
file_storage const& fs = ti->files(); file_storage const& fs = ti->files();

View File

@ -155,8 +155,8 @@ void test_transfer(lt::session& ses, boost::shared_ptr<torrent_info> torrent_fil
int pad_file_size = 0; int pad_file_size = 0;
for (int i = 0; i < fs.num_files(); ++i) for (int i = 0; i < fs.num_files(); ++i)
{ {
file_entry f = fs.at(i); if (fs.file_flags(i) & file_storage::flag_pad_file)
if (f.pad_file) pad_file_size += f.size; pad_file_size += fs.file_size(i);
} }
peer_disconnects = 0; peer_disconnects = 0;