forked from premiere/premiere-libtorrent
optimized memory usage of torrent_info
This commit is contained in:
parent
79f6b5856b
commit
8c404cc5c1
|
@ -47,14 +47,20 @@ namespace
|
|||
{
|
||||
ct.add_node(std::make_pair(addr, port));
|
||||
}
|
||||
|
||||
void add_file(file_storage& ct, file_entry const& fe
|
||||
, std::string const& hash, std::string const& linkpath)
|
||||
{
|
||||
ct.add_file(fe, hash.empty() ? 0 : &sha1_hash(hash)
|
||||
, linkpath.empty() ? 0 : &linkpath);
|
||||
}
|
||||
}
|
||||
|
||||
void bind_create_torrent()
|
||||
{
|
||||
void (file_storage::*add_file0)(file_entry const&) = &file_storage::add_file;
|
||||
void (file_storage::*add_file1)(std::string const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
|
||||
void (file_storage::*add_file0)(std::string const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
|
||||
#if TORRENT_USE_WSTRING
|
||||
void (file_storage::*add_file2)(std::wstring const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
|
||||
void (file_storage::*add_file1)(std::wstring const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
|
||||
#endif
|
||||
|
||||
void (file_storage::*set_name0)(std::string const&) = &file_storage::set_name;
|
||||
|
@ -69,10 +75,10 @@ void bind_create_torrent()
|
|||
|
||||
class_<file_storage>("file_storage")
|
||||
.def("is_valid", &file_storage::is_valid)
|
||||
.def("add_file", add_file0)
|
||||
.def("add_file", add_file1, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
|
||||
.def("add_file", add_file, (arg("entry"), arg("hash") = std::string(), arg("symlink") = std::string()))
|
||||
.def("add_file", add_file0, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
|
||||
#if TORRENT_USE_WSTRING
|
||||
.def("add_file", add_file2, (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
|
||||
.def("num_files", &file_storage::num_files)
|
||||
.def("at", &file_storage::at, return_internal_reference<>())
|
||||
|
|
|
@ -172,6 +172,9 @@ file structure. Its synopsis::
|
|||
int piece_length() const;
|
||||
int piece_size(int index) const;
|
||||
|
||||
sha1_hash const& hash(int index) const;
|
||||
std::string const& symlink(int index) const;
|
||||
|
||||
void set_name(std::string const& n);
|
||||
void set_name(std::wstring const& n);
|
||||
const std::string& name() const;
|
||||
|
@ -215,6 +218,17 @@ can be changed by calling ``set_name``.
|
|||
The built in functions to traverse a directory to add files will
|
||||
make sure this requirement is fulfilled.
|
||||
|
||||
hash() symlink()
|
||||
----------------
|
||||
|
||||
::
|
||||
|
||||
sha1_hash const& hash(int index) const;
|
||||
std::string const& symlink(int index) const;
|
||||
|
||||
These functions are used to resolve the symlink index and file hash
|
||||
index in ``file_entry``.
|
||||
|
||||
|
||||
create_torrent
|
||||
==============
|
||||
|
|
|
@ -1345,19 +1345,22 @@ The ``torrent_info`` has the following synopsis::
|
|||
{
|
||||
public:
|
||||
|
||||
// flags for torrent_info constructor
|
||||
enum flags_t { ommit_filehashes = 1 };
|
||||
|
||||
// these constructors throws exceptions on error
|
||||
torrent_info(sha1_hash const& info_hash);
|
||||
torrent_info(lazy_entry const& torrent_file);
|
||||
torrent_info(char const* buffer, int size);
|
||||
torrent_info(boost::filesystem::path const& filename);
|
||||
torrent_info(boost::filesystem::wpath const& filename);
|
||||
torrent_info(sha1_hash const& info_hash, int flags = 0);
|
||||
torrent_info(lazy_entry const& torrent_file, int flags = 0);
|
||||
torrent_info(char const* buffer, int size, int flags = 0);
|
||||
torrent_info(boost::filesystem::path const& filename, int flags = 0);
|
||||
torrent_info(boost::filesystem::wpath const& filename, int flags = 0);
|
||||
|
||||
// these constructors sets the error code on error
|
||||
torrent_info(sha1_hash const& info_hash, error_code& ec);
|
||||
torrent_info(lazy_entry const& torrent_file, error_code& ec);
|
||||
torrent_info(char const* buffer, int size, error_code& ec);
|
||||
torrent_info(fs::path const& filename, error_code& ec);
|
||||
torrent_info(fs::wpath const& filename, error_code& ec);
|
||||
torrent_info(sha1_hash const& info_hash, error_code& ec, int flags = 0);
|
||||
torrent_info(lazy_entry const& torrent_file, error_code& ec, int flags = 0);
|
||||
torrent_info(char const* buffer, int size, error_code& ec, int flags = 0);
|
||||
torrent_info(fs::path const& filename, error_code& ec, int flags = 0);
|
||||
torrent_info(fs::wpath const& filename, error_code& ec, int flags = 0);
|
||||
|
||||
void add_tracker(std::string const& url, int tier = 0);
|
||||
std::vector<announce_entry> const& trackers() const;
|
||||
|
@ -1418,17 +1421,17 @@ torrent_info()
|
|||
|
||||
::
|
||||
|
||||
torrent_info(sha1_hash const& info_hash);
|
||||
torrent_info(lazy_entry const& torrent_file);
|
||||
torrent_info(char const* buffer, int size);
|
||||
torrent_info(boost::filesystem::path const& filename);
|
||||
torrent_info(boost::filesystem::wpath const& filename);
|
||||
torrent_info(sha1_hash const& info_hash, int flags = 0);
|
||||
torrent_info(lazy_entry const& torrent_file, int flags = 0);
|
||||
torrent_info(char const* buffer, int size, int flags = 0);
|
||||
torrent_info(boost::filesystem::path const& filename, int flags = 0);
|
||||
torrent_info(boost::filesystem::wpath const& filename, int flags = 0);
|
||||
|
||||
torrent_info(sha1_hash const& info_hash, error_code& ec);
|
||||
torrent_info(lazy_entry const& torrent_file, error_code& ec);
|
||||
torrent_info(char const* buffer, int size, error_code& ec);
|
||||
torrent_info(fs::path const& filename, error_code& ec);
|
||||
torrent_info(fs::wpath const& filename, error_code& ec);
|
||||
torrent_info(sha1_hash const& info_hash, error_code& ec, int flags = 0);
|
||||
torrent_info(lazy_entry const& torrent_file, error_code& ec, int flags = 0);
|
||||
torrent_info(char const* buffer, int size, error_code& ec, int flags = 0);
|
||||
torrent_info(fs::path const& filename, error_code& ec, int flags = 0);
|
||||
torrent_info(fs::wpath const& filename, error_code& ec, int flags = 0);
|
||||
|
||||
The constructor that takes an info-hash will initialize the info-hash to the given value,
|
||||
but leave all other fields empty. This is used internally when downloading torrents without
|
||||
|
@ -1453,6 +1456,11 @@ torrent_info object. The overloads that do not take the extra error_code_ parame
|
|||
always throw if an error occurs. These overloads are not available when building without
|
||||
exception support.
|
||||
|
||||
The ``flags`` argument can be used to disable loading of potentially unnecessary hashes
|
||||
for individual files (if included in the torrent file). This is especially useful if
|
||||
you're loading torrents with thousands of files on a memory constrained system. If so,
|
||||
pass in ``torrent_info::ommit_filehashes`` as the flags argument.
|
||||
|
||||
|
||||
add_tracker()
|
||||
-------------
|
||||
|
@ -1534,12 +1542,13 @@ iterators with the type ``file_entry``.
|
|||
|
||||
struct file_entry
|
||||
{
|
||||
boost::filesystem::path path;
|
||||
std::string path;
|
||||
size_type offset;
|
||||
size_type size;
|
||||
size_type file_base;
|
||||
std::string symlink_path;
|
||||
boost::shared_ptr<sha1_hash> filehash;
|
||||
time_t mtime;
|
||||
int symlink_index;
|
||||
int filehash_index;
|
||||
bool pad_file:1;
|
||||
bool hidden_attribute:1;
|
||||
bool executable_attribute:1;
|
||||
|
@ -1561,6 +1570,17 @@ the ``file_base`` should be set to an offset so that the different regions do
|
|||
not overlap. This is used when mapping "unselected" files into a so-called part
|
||||
file.
|
||||
|
||||
``mtime`` is the modification time of this file specified in posix time.
|
||||
|
||||
``symlink_index`` is an index into an array of paths in ``file_storage``, or
|
||||
-1 if this file is not a symlink. This field is only used if the ``symlink_attribute``
|
||||
is set. To resolve the symlink, call ``file_storage::symlink(e.symlink_index)``.
|
||||
|
||||
``filehash_index`` is an index into an array of sha-1 hashes in ``file_storage``, or
|
||||
-1 if this file doesn't have a hash specified. The hash is the hash of the actual
|
||||
content of the file, and can be used to potentially find alternative sources for it.
|
||||
To resolve the hash, use ``file_storage::hash(e.filehash_index)``.
|
||||
|
||||
``pad_file`` is set to true for files that are not part of the data of the torrent.
|
||||
They are just there to make sure the next file is aligned to a particular byte offset
|
||||
or piece boundry. These files should typically be hidden from an end user. They are
|
||||
|
@ -1571,11 +1591,8 @@ not written to disk.
|
|||
``executable_attribute`` is true if the file was marked as executable (posix)
|
||||
|
||||
``symlink_attribute`` is true if the file was a symlink. If this is the case
|
||||
the ``symlink_path`` specifies the original location where the data for this file
|
||||
was found.
|
||||
|
||||
``filehash`` is a pointer that is set in case the torrent file included a sha1 hash
|
||||
for this file. This may be use to look up more sources for this file on other networks.
|
||||
the ``symlink_index`` refers to a string which specifies the original location
|
||||
where the data for this file was found.
|
||||
|
||||
num_files() file_at()
|
||||
---------------------
|
||||
|
|
|
@ -127,10 +127,10 @@ int main(int argc, char* argv[])
|
|||
, (i->hidden_attribute?'h':'-')
|
||||
, (i->symlink_attribute?'l':'-')
|
||||
, first, last
|
||||
, i->filehash ? to_hex(i->filehash->to_string()).c_str() : ""
|
||||
, i->filehash_index != -1 ? to_hex(t.files().hash(i->filehash_index).to_string()).c_str() : ""
|
||||
, i->path.c_str()
|
||||
, i->symlink_attribute ? "-> ": ""
|
||||
, i->symlink_attribute ? i->symlink_path.c_str() : "");
|
||||
, i->symlink_attribute && i->symlink_index != -1 ? t.files().symlink(i->symlink_index).c_str() : "");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -49,15 +49,21 @@ namespace libtorrent
|
|||
|
||||
struct TORRENT_EXPORT file_entry
|
||||
{
|
||||
file_entry(): offset(0), size(0), file_base(0), file_index(0)
|
||||
, mtime(0), pad_file(false), hidden_attribute(false)
|
||||
file_entry()
|
||||
: offset(0)
|
||||
, size(0)
|
||||
, file_base(0)
|
||||
, mtime(0)
|
||||
, file_index(0)
|
||||
, filehash_index(-1)
|
||||
, symlink_index(-1)
|
||||
, pad_file(false)
|
||||
, hidden_attribute(false)
|
||||
, executable_attribute(false)
|
||||
, symlink_attribute(false)
|
||||
{}
|
||||
|
||||
std::string path;
|
||||
std::string symlink_path;
|
||||
copy_ptr<sha1_hash> filehash;
|
||||
// the offset of this file inside the torrent
|
||||
size_type offset;
|
||||
// the size of this file
|
||||
|
@ -66,9 +72,16 @@ namespace libtorrent
|
|||
// This is always 0 unless parts of the torrent is
|
||||
// compressed into a single file, such as a so-called part file.
|
||||
size_type file_base;
|
||||
// modification time
|
||||
time_t mtime;
|
||||
// the index of this file, as ordered in the torrent
|
||||
int file_index;
|
||||
time_t mtime;
|
||||
// index into file_storage::m_file_hashes or -1
|
||||
// if this file does not have a hash
|
||||
int filehash_index;
|
||||
// index into file_storage::m_symlinks or -1
|
||||
// if this is not a symlink
|
||||
int symlink_index;
|
||||
bool pad_file:1;
|
||||
bool hidden_attribute:1;
|
||||
bool executable_attribute:1;
|
||||
|
@ -101,7 +114,9 @@ namespace libtorrent
|
|||
|
||||
void reserve(int num_files);
|
||||
|
||||
void add_file(file_entry const& e);
|
||||
void add_file(file_entry const& e, sha1_hash const* filehash = 0
|
||||
, std::string const* symlink = 0);
|
||||
|
||||
void add_file(std::string const& p, size_type size, int flags = 0
|
||||
, std::time_t mtime = 0, std::string const& s_p = "");
|
||||
void rename_file(int index, std::string const& new_filename);
|
||||
|
@ -133,7 +148,19 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
|
||||
return m_files[index];
|
||||
}
|
||||
|
||||
sha1_hash const& hash(int index) const
|
||||
{
|
||||
TORRENT_ASSERT(index >= 0 && index < int(m_file_hashes.size()));
|
||||
return m_file_hashes[index];
|
||||
}
|
||||
|
||||
std::string const& symlink(int index) const
|
||||
{
|
||||
TORRENT_ASSERT(index >= 0 && index < int(m_symlinks.size()));
|
||||
return m_symlinks[index];
|
||||
}
|
||||
|
||||
size_type total_size() const { return m_total_size; }
|
||||
void set_num_pieces(int n) { m_num_pieces = n; }
|
||||
int num_pieces() const { TORRENT_ASSERT(m_piece_length > 0); return m_num_pieces; }
|
||||
|
@ -160,9 +187,22 @@ namespace libtorrent
|
|||
void optimize(int pad_file_limit = -1);
|
||||
|
||||
private:
|
||||
|
||||
// the list of files that this torrent consists of
|
||||
std::vector<file_entry> m_files;
|
||||
|
||||
// if there are sha1 hashes for each individual file
|
||||
// each file_entry has an index into this vector
|
||||
// and the actual hashes are in here
|
||||
std::vector<sha1_hash> m_file_hashes;
|
||||
|
||||
// for files that are symlinks, the symlink
|
||||
// path_index in the file_entry indexes
|
||||
// this vector of strings
|
||||
std::vector<std::string> m_symlinks;
|
||||
|
||||
// name of torrent. For multi-file torrents
|
||||
// this is always the root directory
|
||||
std::string m_name;
|
||||
|
||||
// the sum of all filesizes
|
||||
|
|
|
@ -225,22 +225,25 @@ namespace libtorrent
|
|||
class TORRENT_EXPORT torrent_info : public intrusive_ptr_base<torrent_info>
|
||||
{
|
||||
public:
|
||||
|
||||
enum flags_t { ommit_filehashes = 1 };
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
torrent_info(lazy_entry const& torrent_file);
|
||||
torrent_info(char const* buffer, int size);
|
||||
torrent_info(std::string const& filename);
|
||||
torrent_info(lazy_entry const& torrent_file, int flags = 0);
|
||||
torrent_info(char const* buffer, int size, int flags = 0);
|
||||
torrent_info(std::string const& filename, int flags = 0);
|
||||
#if TORRENT_USE_WSTRING
|
||||
torrent_info(std::wstring const& filename);
|
||||
torrent_info(std::wstring const& filename, int flags = 0);
|
||||
#endif // TORRENT_USE_WSTRING
|
||||
#endif
|
||||
|
||||
torrent_info(torrent_info const& t);
|
||||
torrent_info(sha1_hash const& info_hash);
|
||||
torrent_info(lazy_entry const& torrent_file, error_code& ec);
|
||||
torrent_info(char const* buffer, int size, error_code& ec);
|
||||
torrent_info(std::string const& filename, error_code& ec);
|
||||
torrent_info(torrent_info const& t, int flags = 0);
|
||||
torrent_info(sha1_hash const& info_hash, int flags = 0);
|
||||
torrent_info(lazy_entry const& torrent_file, error_code& ec, int flags = 0);
|
||||
torrent_info(char const* buffer, int size, error_code& ec, int flags = 0);
|
||||
torrent_info(std::string const& filename, error_code& ec, int flags = 0);
|
||||
#if TORRENT_USE_WSTRING
|
||||
torrent_info(std::wstring const& filename, error_code& ec);
|
||||
torrent_info(std::wstring const& filename, error_code& ec, int flags = 0);
|
||||
#endif // TORRENT_USE_WSTRING
|
||||
|
||||
~torrent_info();
|
||||
|
@ -369,7 +372,7 @@ namespace libtorrent
|
|||
void add_node(std::pair<std::string, int> const& node)
|
||||
{ m_nodes.push_back(node); }
|
||||
|
||||
bool parse_info_section(lazy_entry const& e, error_code& ex);
|
||||
bool parse_info_section(lazy_entry const& e, error_code& ec, int flags);
|
||||
|
||||
lazy_entry const* info(char const* key) const
|
||||
{
|
||||
|
@ -406,7 +409,7 @@ namespace libtorrent
|
|||
torrent_info const& operator=(torrent_info const&);
|
||||
|
||||
void copy_on_write();
|
||||
bool parse_torrent_file(lazy_entry const& libtorrent, error_code& ec);
|
||||
bool parse_torrent_file(lazy_entry const& libtorrent, error_code& ec, int flags);
|
||||
|
||||
file_storage m_files;
|
||||
|
||||
|
|
|
@ -314,11 +314,13 @@ namespace libtorrent
|
|||
if (m_files.at(0).executable_attribute) attr += 'x';
|
||||
if (m_include_symlinks && m_files.at(0).symlink_attribute) attr += 'l';
|
||||
}
|
||||
if (m_include_symlinks && m_files.at(0).symlink_attribute)
|
||||
if (m_include_symlinks
|
||||
&& m_files.at(0).symlink_attribute
|
||||
&& m_files.at(0).symlink_index != -1)
|
||||
{
|
||||
entry& sympath_e = info["symlink path"];
|
||||
|
||||
std::string split = split_path(m_files.at(0).symlink_path);
|
||||
std::string split = split_path(m_files.symlink(m_files.at(0).symlink_index));
|
||||
for (char const* e = split.c_str(); e != 0; e = next_path_element(e))
|
||||
sympath_e.list().push_back(entry(e));
|
||||
}
|
||||
|
@ -362,11 +364,13 @@ namespace libtorrent
|
|||
if (i->executable_attribute) attr += 'x';
|
||||
if (m_include_symlinks && i->symlink_attribute) attr += 'l';
|
||||
}
|
||||
if (m_include_symlinks && i->symlink_attribute)
|
||||
if (m_include_symlinks
|
||||
&& i->symlink_attribute
|
||||
&& i->symlink_index != -1)
|
||||
{
|
||||
entry& sympath_e = file_e["symlink path"];
|
||||
|
||||
std::string split = split_path(i->symlink_path);
|
||||
std::string split = split_path(m_files.symlink(i->symlink_index));
|
||||
for (char const* e = split.c_str(); e != 0; e = next_path_element(e))
|
||||
sympath_e.list().push_back(entry(e));
|
||||
}
|
||||
|
|
|
@ -204,12 +204,18 @@ namespace libtorrent
|
|||
e.hidden_attribute = (flags & attribute_hidden) != 0;
|
||||
e.executable_attribute = (flags & attribute_executable) != 0;
|
||||
e.symlink_attribute = (flags & attribute_symlink) != 0;
|
||||
if (e.symlink_attribute) e.symlink_path = symlink_path;
|
||||
if (e.symlink_attribute)
|
||||
{
|
||||
e.symlink_index = m_symlinks.size();
|
||||
m_symlinks.push_back(symlink_path);
|
||||
|
||||
}
|
||||
e.mtime = mtime;
|
||||
m_total_size += size;
|
||||
}
|
||||
|
||||
void file_storage::add_file(file_entry const& ent)
|
||||
void file_storage::add_file(file_entry const& ent, sha1_hash const* filehash
|
||||
, std::string const* symlink)
|
||||
{
|
||||
if (!has_parent_path(ent.path))
|
||||
{
|
||||
|
@ -230,6 +236,17 @@ namespace libtorrent
|
|||
e.offset = m_total_size;
|
||||
e.file_index = m_files.size() - 1;
|
||||
m_total_size += ent.size;
|
||||
if (filehash)
|
||||
{
|
||||
e.filehash_index = m_file_hashes.size();
|
||||
m_file_hashes.push_back(*filehash);
|
||||
}
|
||||
|
||||
if (symlink)
|
||||
{
|
||||
e.symlink_index = m_symlinks.size();
|
||||
m_symlinks.push_back(*symlink);
|
||||
}
|
||||
}
|
||||
|
||||
void file_storage::optimize(int pad_file_limit)
|
||||
|
|
|
@ -4486,7 +4486,7 @@ namespace libtorrent
|
|||
lazy_entry metadata;
|
||||
error_code ec;
|
||||
int ret = lazy_bdecode(metadata_buf, metadata_buf + metadata_size, metadata, ec);
|
||||
if (ret != 0 || !m_torrent_file->parse_info_section(metadata, ec))
|
||||
if (ret != 0 || !m_torrent_file->parse_info_section(metadata, ec, 0))
|
||||
{
|
||||
// this means the metadata is correct, since we
|
||||
// verified it against the info-hash, but we
|
||||
|
|
|
@ -233,7 +233,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
bool extract_single_file(lazy_entry const& dict, file_entry& target
|
||||
, std::string const& root_dir)
|
||||
, std::string const& root_dir, sha1_hash* filehash, std::string* symlink)
|
||||
{
|
||||
if (dict.type() != lazy_entry::dict_t) return false;
|
||||
lazy_entry const* length = dict.dict_find("length");
|
||||
|
@ -287,21 +287,24 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
lazy_entry const* fh = dict.dict_find_string("sha1");
|
||||
if (fh && fh->string_length() == 20)
|
||||
if (fh && fh->string_length() == 20 && filehash)
|
||||
{
|
||||
target.filehash.reset(new sha1_hash);
|
||||
std::memcpy(&(*target.filehash)[0], fh->string_ptr(), 20);
|
||||
std::memcpy(&(*filehash)[0], fh->string_ptr(), 20);
|
||||
// indicate that the file has a filehash
|
||||
target.filehash_index = 0;
|
||||
}
|
||||
|
||||
lazy_entry const* s_p = dict.dict_find("symlink path");
|
||||
if (s_p != 0 && s_p->type() == lazy_entry::list_t)
|
||||
if (s_p != 0 && s_p->type() == lazy_entry::list_t && symlink)
|
||||
{
|
||||
for (int i = 0, end(s_p->list_size()); i < end; ++i)
|
||||
{
|
||||
std::string path_element = s_p->list_at(i)->string_value();
|
||||
trim_path_element(path_element);
|
||||
target.symlink_path = combine_path(target.symlink_path, path_element);
|
||||
*symlink = combine_path(*symlink, path_element);
|
||||
}
|
||||
// indeicate that we have a symlink
|
||||
target.symlink_index = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -335,9 +338,15 @@ namespace libtorrent
|
|||
target.reserve(list.list_size());
|
||||
for (int i = 0, end(list.list_size()); i < end; ++i)
|
||||
{
|
||||
sha1_hash file_hash;
|
||||
std::string symlink;
|
||||
file_entry e;
|
||||
if (!extract_single_file(*list.list_at(i), e, root_dir))
|
||||
if (!extract_single_file(*list.list_at(i), e, root_dir, &file_hash, &symlink))
|
||||
return false;
|
||||
|
||||
// TODO: this logic should be a separate step
|
||||
// done once the torrent is loaded, and the original
|
||||
// filenames should be preserved!
|
||||
int cnt = 0;
|
||||
std::set<std::string, string_less_no_case> files;
|
||||
|
||||
|
@ -350,7 +359,8 @@ namespace libtorrent
|
|||
snprintf(suffix, sizeof(suffix), ".%d%s", cnt, extension(e.path).c_str());
|
||||
replace_extension(e.path, suffix);
|
||||
}
|
||||
target.add_file(e);
|
||||
target.add_file(e, e.filehash_index != -1 ? &file_hash : 0
|
||||
, e.symlink_index != -1 ? &symlink : 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -436,7 +446,7 @@ namespace libtorrent
|
|||
url.erase(url.begin());
|
||||
}
|
||||
|
||||
torrent_info::torrent_info(torrent_info const& t)
|
||||
torrent_info::torrent_info(torrent_info const& t, int flags)
|
||||
: m_files(t.m_files)
|
||||
, m_orig_files(t.m_orig_files)
|
||||
, m_urls(t.m_urls)
|
||||
|
@ -508,7 +518,7 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
if (!parse_torrent_file(e, ec))
|
||||
if (!parse_torrent_file(e, ec, 0))
|
||||
throw invalid_torrent_file(ec);
|
||||
#else
|
||||
parse_torrent_file(e, ec);
|
||||
|
@ -517,7 +527,7 @@ namespace libtorrent
|
|||
#endif
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
torrent_info::torrent_info(lazy_entry const& torrent_file)
|
||||
torrent_info::torrent_info(lazy_entry const& torrent_file, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(0)
|
||||
, m_merkle_first_leaf(0)
|
||||
|
@ -527,11 +537,11 @@ namespace libtorrent
|
|||
, m_i2p(false)
|
||||
{
|
||||
error_code ec;
|
||||
if (!parse_torrent_file(torrent_file, ec))
|
||||
if (!parse_torrent_file(torrent_file, ec, flags))
|
||||
throw invalid_torrent_file(ec);
|
||||
}
|
||||
|
||||
torrent_info::torrent_info(char const* buffer, int size)
|
||||
torrent_info::torrent_info(char const* buffer, int size, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(0)
|
||||
, m_merkle_first_leaf(0)
|
||||
|
@ -545,11 +555,11 @@ namespace libtorrent
|
|||
if (lazy_bdecode(buffer, buffer + size, e, ec) != 0)
|
||||
throw invalid_torrent_file(ec);
|
||||
|
||||
if (!parse_torrent_file(e, ec))
|
||||
if (!parse_torrent_file(e, ec, flags))
|
||||
throw invalid_torrent_file(ec);
|
||||
}
|
||||
|
||||
torrent_info::torrent_info(std::string const& filename)
|
||||
torrent_info::torrent_info(std::string const& filename, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(0)
|
||||
, m_info_section_size(0)
|
||||
|
@ -566,12 +576,12 @@ namespace libtorrent
|
|||
if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
throw invalid_torrent_file(ec);
|
||||
|
||||
if (!parse_torrent_file(e, ec))
|
||||
if (!parse_torrent_file(e, ec, flags))
|
||||
throw invalid_torrent_file(ec);
|
||||
}
|
||||
|
||||
#if TORRENT_USE_WSTRING
|
||||
torrent_info::torrent_info(std::wstring const& filename)
|
||||
torrent_info::torrent_info(std::wstring const& filename, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(0)
|
||||
, m_merkle_first_leaf(0)
|
||||
|
@ -591,13 +601,13 @@ namespace libtorrent
|
|||
if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
throw invalid_torrent_file(ec);
|
||||
|
||||
if (!parse_torrent_file(e, ec))
|
||||
if (!parse_torrent_file(e, ec, flags))
|
||||
throw invalid_torrent_file(ec);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
torrent_info::torrent_info(lazy_entry const& torrent_file, error_code& ec)
|
||||
torrent_info::torrent_info(lazy_entry const& torrent_file, error_code& ec, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(0)
|
||||
, m_info_section_size(0)
|
||||
|
@ -605,10 +615,10 @@ namespace libtorrent
|
|||
, m_private(false)
|
||||
, m_i2p(false)
|
||||
{
|
||||
parse_torrent_file(torrent_file, ec);
|
||||
parse_torrent_file(torrent_file, ec, flags);
|
||||
}
|
||||
|
||||
torrent_info::torrent_info(char const* buffer, int size, error_code& ec)
|
||||
torrent_info::torrent_info(char const* buffer, int size, error_code& ec, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(0)
|
||||
, m_merkle_first_leaf(0)
|
||||
|
@ -620,10 +630,10 @@ namespace libtorrent
|
|||
lazy_entry e;
|
||||
if (lazy_bdecode(buffer, buffer + size, e, ec) != 0)
|
||||
return;
|
||||
parse_torrent_file(e, ec);
|
||||
parse_torrent_file(e, ec, flags);
|
||||
}
|
||||
|
||||
torrent_info::torrent_info(std::string const& filename, error_code& ec)
|
||||
torrent_info::torrent_info(std::string const& filename, error_code& ec, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(0)
|
||||
, m_info_section_size(0)
|
||||
|
@ -638,11 +648,11 @@ namespace libtorrent
|
|||
lazy_entry e;
|
||||
if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
return;
|
||||
parse_torrent_file(e, ec);
|
||||
parse_torrent_file(e, ec, flags);
|
||||
}
|
||||
|
||||
#if TORRENT_USE_WSTRING
|
||||
torrent_info::torrent_info(std::wstring const& filename, error_code& ec)
|
||||
torrent_info::torrent_info(std::wstring const& filename, error_code& ec, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(0)
|
||||
, m_info_section_size(0)
|
||||
|
@ -659,7 +669,7 @@ namespace libtorrent
|
|||
lazy_entry e;
|
||||
if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0)
|
||||
return;
|
||||
parse_torrent_file(e, ec);
|
||||
parse_torrent_file(e, ec, flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -667,7 +677,7 @@ namespace libtorrent
|
|||
// will not contain any hashes, comments, creation date
|
||||
// just the necessary to use it with piece manager
|
||||
// used for torrents with no metadata
|
||||
torrent_info::torrent_info(sha1_hash const& info_hash)
|
||||
torrent_info::torrent_info(sha1_hash const& info_hash, int flags)
|
||||
: m_piece_hashes(0)
|
||||
, m_creation_date(time(0))
|
||||
, m_info_hash(info_hash)
|
||||
|
@ -717,7 +727,7 @@ namespace libtorrent
|
|||
|
||||
#undef SWAP
|
||||
|
||||
bool torrent_info::parse_info_section(lazy_entry const& info, error_code& ec)
|
||||
bool torrent_info::parse_info_section(lazy_entry const& info, error_code& ec, int flags)
|
||||
{
|
||||
if (info.type() != lazy_entry::dict_t)
|
||||
{
|
||||
|
@ -796,20 +806,23 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
lazy_entry const* s_p = info.dict_find("symlink path");
|
||||
std::string symlink;
|
||||
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();
|
||||
trim_path_element(path_element);
|
||||
e.symlink_path = combine_path(e.symlink_path, path_element);
|
||||
symlink = combine_path(symlink, path_element);
|
||||
}
|
||||
e.symlink_index = 0;
|
||||
}
|
||||
lazy_entry const* fh = info.dict_find_string("sha1");
|
||||
sha1_hash filehash;
|
||||
if (fh && fh->string_length() == 20)
|
||||
{
|
||||
e.filehash.reset(new sha1_hash);
|
||||
std::memcpy(&(*e.filehash)[0], fh->string_ptr(), 20);
|
||||
std::memcpy(&filehash[0], fh->string_ptr(), 20);
|
||||
e.filehash_index = 0;
|
||||
}
|
||||
|
||||
// bitcomet pad file
|
||||
|
@ -820,7 +833,9 @@ namespace libtorrent
|
|||
ec = errors::torrent_invalid_length;
|
||||
return false;
|
||||
}
|
||||
m_files.add_file(e);
|
||||
bool ommit_hash = (flags & torrent_info::ommit_filehashes) || e.filehash_index == -1;
|
||||
m_files.add_file(e, ommit_hash ? 0 : &filehash
|
||||
, e.symlink_index != -1 ? &symlink : 0);
|
||||
m_multifile = false;
|
||||
}
|
||||
else
|
||||
|
@ -965,7 +980,7 @@ namespace libtorrent
|
|||
}
|
||||
#endif
|
||||
|
||||
bool torrent_info::parse_torrent_file(lazy_entry const& torrent_file, error_code& ec)
|
||||
bool torrent_info::parse_torrent_file(lazy_entry const& torrent_file, error_code& ec, int flags)
|
||||
{
|
||||
if (torrent_file.type() != lazy_entry::dict_t)
|
||||
{
|
||||
|
@ -1103,7 +1118,7 @@ namespace libtorrent
|
|||
ec = errors::torrent_missing_info;
|
||||
return false;
|
||||
}
|
||||
return parse_info_section(*info, ec);
|
||||
return parse_info_section(*info, ec, flags);
|
||||
}
|
||||
|
||||
boost::optional<time_t>
|
||||
|
|
Loading…
Reference in New Issue