forked from premiere/premiere-libtorrent
reverted part of the file_storage API to match the previous one more closly
This commit is contained in:
parent
f82321c1dd
commit
2e69366b02
|
@ -48,11 +48,9 @@ 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)
|
||||
void add_file(file_storage& ct, file_entry const& fe)
|
||||
{
|
||||
ct.add_file(fe, hash.empty() ? 0 : hash.c_str()
|
||||
, linkpath.empty() ? 0 : &linkpath);
|
||||
ct.add_file(fe);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,21 +71,23 @@ void bind_create_torrent()
|
|||
#endif
|
||||
void (*add_files0)(file_storage&, std::string const&, boost::uint32_t) = add_files;
|
||||
|
||||
file_entry (file_storage::*at)(int) const = &file_storage::at;
|
||||
|
||||
class_<file_storage>("file_storage")
|
||||
.def("is_valid", &file_storage::is_valid)
|
||||
.def("add_file", add_file, (arg("entry"), arg("hash") = std::string(), arg("symlink") = std::string()))
|
||||
.def("add_file", add_file, arg("entry"))
|
||||
.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_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<>())
|
||||
.def("hash", &file_storage::hash)
|
||||
.def("symlink", &file_storage::symlink, return_internal_reference<>())
|
||||
.def("file_index", &file_storage::file_index)
|
||||
.def("file_base", &file_storage::file_base)
|
||||
.def("set_file_base", &file_storage::set_file_base)
|
||||
.def("file_path", &file_storage::file_path)
|
||||
.def("at", at)
|
||||
// .def("hash", &file_storage::hash)
|
||||
// .def("symlink", &file_storage::symlink, return_internal_reference<>())
|
||||
// .def("file_index", &file_storage::file_index)
|
||||
// .def("file_base", &file_storage::file_base)
|
||||
// .def("set_file_base", &file_storage::set_file_base)
|
||||
// .def("file_path", &file_storage::file_path)
|
||||
.def("total_size", &file_storage::total_size)
|
||||
.def("set_num_pieces", &file_storage::set_num_pieces)
|
||||
.def("num_pieces", &file_storage::num_pieces)
|
||||
|
|
|
@ -55,10 +55,10 @@ namespace
|
|||
list files(torrent_info const& ti, bool storage) {
|
||||
list result;
|
||||
|
||||
typedef std::vector<file_entry> list_type;
|
||||
typedef torrent_info::file_iterator iter;
|
||||
|
||||
for (list_type::const_iterator i = ti.begin_files(); i != ti.end_files(); ++i)
|
||||
result.append(*i);
|
||||
for (iter i = ti.begin_files(); i != ti.end_files(); ++i)
|
||||
result.append(ti.files().at(i));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ void bind_torrent_info()
|
|||
.def("piece_size", &torrent_info::piece_size)
|
||||
|
||||
.def("num_files", &torrent_info::num_files, (arg("storage")=false))
|
||||
.def("file_at", &torrent_info::file_at, return_internal_reference<>())
|
||||
.def("file_at", &torrent_info::file_at)
|
||||
.def("file_at_offset", &torrent_info::file_at_offset)
|
||||
.def("files", &files, (arg("storage")=false))
|
||||
.def("rename_file", rename_file0)
|
||||
|
@ -182,8 +182,10 @@ void bind_torrent_info()
|
|||
;
|
||||
|
||||
class_<file_entry>("file_entry")
|
||||
.def("filename", &file_entry::filename)
|
||||
.def("set_name", &file_entry::set_name)
|
||||
.def_readwrite("path", &file_entry::path)
|
||||
.def_readwrite("symlink_path", &file_entry::symlink_path)
|
||||
.def_readwrite("filehash", &file_entry::filehash)
|
||||
.def_readwrite("mtime", &file_entry::mtime)
|
||||
.add_property("pad_file", &get_pad_file)
|
||||
.add_property("executable_attribute", &get_executable_attribute)
|
||||
.add_property("hidden_attribute", &get_hidden_attribute)
|
||||
|
|
|
@ -173,12 +173,12 @@ file structure. Its synopsis::
|
|||
int piece_length() const;
|
||||
int piece_size(int index) const;
|
||||
|
||||
sha1_hash const& hash(file_entry const& fe) const;
|
||||
std::string const& symlink(file_entry const& fe) const;
|
||||
time_t mtime(file_entry const& fe) const;
|
||||
int file_index(file_entry const& fe) const;
|
||||
size_type file_base(file_entry const& fe) const;
|
||||
void set_file_base(file_entry const& fe, size_type off);
|
||||
sha1_hash const& hash(internal_file_entry const& fe) const;
|
||||
std::string const& symlink(internal_file_entry const& fe) const;
|
||||
time_t mtime(internal_file_entry const& fe) const;
|
||||
int file_index(internal_file_entry const& fe) const;
|
||||
size_type file_base(internal_file_entry const& fe) const;
|
||||
void set_file_base(internal_file_entry const& fe, size_type off);
|
||||
|
||||
void set_name(std::string const& n);
|
||||
void set_name(std::wstring const& n);
|
||||
|
@ -193,8 +193,8 @@ add_file()
|
|||
::
|
||||
|
||||
void add_file(file_entry const& e);
|
||||
void add_file(fs::path const& p, size_type size, int flags = 0);
|
||||
void add_file(fs::wpath const& p, size_type size, int flags = 0);
|
||||
void add_file(std::string const& p, size_type size, int flags = 0);
|
||||
void add_file(std::wstring const& p, size_type size, int flags = 0);
|
||||
|
||||
Adds a file to the file storage. The ``flags`` argument sets attributes on the file.
|
||||
The file attributes is an extension and may not work in all bittorrent clients.
|
||||
|
@ -204,17 +204,8 @@ The possible arreibutes are::
|
|||
attribute_hidden
|
||||
attribute_executable
|
||||
|
||||
add_file
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
void add_file(file_entry const& e);
|
||||
void add_file(fs::path const& p, size_type size);
|
||||
|
||||
Adds a file to the file storage. If more files than one are added,
|
||||
certain restrictions to their paths apply. In a multi-file file
|
||||
storage (torrent), all files must share the same root directory.
|
||||
If more files than one are added, certain restrictions to their paths apply.
|
||||
In a multi-file file storage (torrent), all files must share the same root directory.
|
||||
|
||||
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
|
||||
|
@ -228,13 +219,14 @@ hash() symlink() mtime() file_index()
|
|||
|
||||
::
|
||||
|
||||
sha1_hash hash(file_entry const& fe) const;
|
||||
std::string const& symlink(file_entry const& fe) const;
|
||||
time_t mtime(file_entry const& fe) const;
|
||||
int file_index(file_entry const& fe) const;
|
||||
sha1_hash hash(internal_file_entry const& fe) const;
|
||||
std::string const& symlink(internal_file_entry const& fe) const;
|
||||
time_t mtime(internal_file_entry const& fe) const;
|
||||
int file_index(internal_file_entry const& fe) const;
|
||||
|
||||
These functions are used to query the symlink, file hash,
|
||||
modification time and the file-index from a ``file_entry``.
|
||||
modification time and the file-index from a ``internal_file_entry``,
|
||||
which typically would be acquired from an iterator.
|
||||
|
||||
For these functions to function, the file entry must be an
|
||||
actual object from this same ``file_storage`` object. It may
|
||||
|
@ -255,8 +247,8 @@ file_base() set_file_base()
|
|||
|
||||
::
|
||||
|
||||
size_type file_base(file_entry const& fe) const;
|
||||
void set_file_base(file_entry const& fe, size_type off);
|
||||
size_type file_base(internal_file_entry const& fe) const;
|
||||
void set_file_base(internal_file_entry const& fe, size_type off);
|
||||
|
||||
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
|
||||
|
|
|
@ -1546,28 +1546,29 @@ begin_files() end_files() rbegin_files() rend_files()
|
|||
This class will need some explanation. First of all, to get a list of all files
|
||||
in the torrent, you can use ``begin_files()``, ``end_files()``,
|
||||
``rbegin_files()`` and ``rend_files()``. These will give you standard vector
|
||||
iterators with the type ``file_entry``.
|
||||
iterators with the type ``internal_file_entry``, which is an internal type.
|
||||
|
||||
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;
|
||||
|
||||
::
|
||||
|
||||
struct file_entry
|
||||
{
|
||||
std::string filename();
|
||||
std::string path;
|
||||
size_type offset;
|
||||
size_type size;
|
||||
size_type file_base;
|
||||
time_t mtime;
|
||||
int symlink_index;
|
||||
int filehash_index;
|
||||
sha1_hash filehash;
|
||||
bool pad_file:1;
|
||||
bool hidden_attribute:1;
|
||||
bool executable_attribute:1;
|
||||
bool symlink_attribute:1;
|
||||
};
|
||||
|
||||
The ``filename`` function returns the filename of this file. It does not include the
|
||||
path, just the leaf name. To get the full path name, use ``file_storage::file_path()``.
|
||||
The filenames are unicode strings encoded in UTF-8.
|
||||
The ``path`` is the full path of this file. The paths are unicode strings
|
||||
encoded in UTF-8.
|
||||
|
||||
``size`` is the size of the file (in bytes) and ``offset`` is the byte offset
|
||||
of the file within the torrent. i.e. the sum of all the sizes of the files
|
||||
|
@ -1582,14 +1583,12 @@ 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)``.
|
||||
``symlink_path`` is the path which this is a symlink to, or empty if this is
|
||||
not a symlink. This field is only used if the ``symlink_attribute`` is set.
|
||||
|
||||
``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`` is a sha-1 hash of the content of the file, or zeroes, if no
|
||||
file hash was present in the torrent file. It can be used to potentially
|
||||
find alternative sources for the file.
|
||||
|
||||
``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
|
||||
|
|
|
@ -47,18 +47,16 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/file.hpp"
|
||||
#include "libtorrent/ptime.hpp"
|
||||
#include "libtorrent/thread.hpp"
|
||||
#include "libtorrent/file_storage.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
struct file_entry;
|
||||
struct file_storage;
|
||||
|
||||
struct TORRENT_EXPORT file_pool : boost::noncopyable
|
||||
{
|
||||
file_pool(int size = 40): m_size(size), m_low_prio_io(true) {}
|
||||
|
||||
boost::intrusive_ptr<file> open_file(void* st, std::string const& p
|
||||
, file_entry const& fe, file_storage const& fs, int m, error_code& ec);
|
||||
, file_storage::iterator fe, file_storage const& fs, int m, error_code& ec);
|
||||
void release(void* st);
|
||||
void release(void* st, int file_index);
|
||||
void resize(int size);
|
||||
|
|
|
@ -47,9 +47,37 @@ namespace libtorrent
|
|||
struct file;
|
||||
|
||||
struct TORRENT_EXPORT file_entry
|
||||
{
|
||||
file_entry(): offset(0), size(0), file_base(0)
|
||||
, mtime(0), pad_file(false), hidden_attribute(false)
|
||||
, executable_attribute(false)
|
||||
, symlink_attribute(false)
|
||||
{}
|
||||
|
||||
std::string path;
|
||||
size_type offset; // the offset of this file inside the torrent
|
||||
size_type size; // the size of this file
|
||||
// the offset in the file where the storage starts.
|
||||
// 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;
|
||||
std::time_t mtime;
|
||||
sha1_hash filehash;
|
||||
bool pad_file:1;
|
||||
bool hidden_attribute:1;
|
||||
bool executable_attribute:1;
|
||||
bool symlink_attribute:1;
|
||||
std::string symlink_path;
|
||||
};
|
||||
|
||||
// this is used internally to hold the file entry
|
||||
// it's smaller and optimized for smaller memory
|
||||
// footprint, as opposed to file_entry, which is
|
||||
// optimized for convenience
|
||||
struct internal_file_entry
|
||||
{
|
||||
friend class file_storage;
|
||||
file_entry()
|
||||
internal_file_entry()
|
||||
: name(0)
|
||||
, offset(0)
|
||||
, symlink_index(-1)
|
||||
|
@ -62,10 +90,25 @@ namespace libtorrent
|
|||
, path_index(-1)
|
||||
{}
|
||||
|
||||
file_entry(file_entry const& fe);
|
||||
file_entry& operator=(file_entry const& fe);
|
||||
internal_file_entry(file_entry const& e)
|
||||
: name(0)
|
||||
, offset(e.offset)
|
||||
, symlink_index(-1)
|
||||
, size(e.size)
|
||||
, name_len(0)
|
||||
, pad_file(e.pad_file)
|
||||
, hidden_attribute(e.hidden_attribute)
|
||||
, executable_attribute(e.executable_attribute)
|
||||
, symlink_attribute(e.symlink_attribute)
|
||||
, path_index(-1)
|
||||
{
|
||||
set_name(e.path.c_str());
|
||||
}
|
||||
|
||||
~file_entry();
|
||||
internal_file_entry(internal_file_entry const& fe);
|
||||
internal_file_entry& operator=(internal_file_entry const& fe);
|
||||
|
||||
~internal_file_entry();
|
||||
|
||||
void set_name(char const* n, int borrow_chars = 0);
|
||||
std::string filename() const;
|
||||
|
@ -129,8 +172,7 @@ namespace libtorrent
|
|||
|
||||
void reserve(int num_files);
|
||||
|
||||
void add_file(file_entry const& e, char const* filehash = 0
|
||||
, std::string const* symlink = 0, time_t mtime = 0);
|
||||
void add_file(file_entry const& e, char const* filehash = 0);
|
||||
|
||||
void add_file(std::string const& p, size_type size, int flags = 0
|
||||
, std::time_t mtime = 0, std::string const& s_p = "");
|
||||
|
@ -148,8 +190,8 @@ namespace libtorrent
|
|||
, int size) const;
|
||||
peer_request map_file(int file, size_type offset, int size) const;
|
||||
|
||||
typedef std::vector<file_entry>::const_iterator iterator;
|
||||
typedef std::vector<file_entry>::const_reverse_iterator reverse_iterator;
|
||||
typedef std::vector<internal_file_entry>::const_iterator iterator;
|
||||
typedef std::vector<internal_file_entry>::const_reverse_iterator reverse_iterator;
|
||||
|
||||
iterator file_at_offset(size_type offset) const;
|
||||
iterator begin() const { return m_files.begin(); }
|
||||
|
@ -159,20 +201,8 @@ namespace libtorrent
|
|||
int num_files() const
|
||||
{ return int(m_files.size()); }
|
||||
|
||||
file_entry const& at(int index) const
|
||||
{
|
||||
TORRENT_ASSERT(index >= 0 && index < int(m_files.size()));
|
||||
return m_files[index];
|
||||
}
|
||||
|
||||
sha1_hash hash(file_entry const& fe) const;
|
||||
std::string const& symlink(file_entry const& fe) const;
|
||||
time_t mtime(file_entry const& fe) const;
|
||||
int file_index(file_entry const& fe) const;
|
||||
size_type file_base(file_entry const& fe) const;
|
||||
void set_file_base(file_entry const& fe, size_type off);
|
||||
|
||||
std::string file_path(file_entry const& fe) const;
|
||||
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; }
|
||||
|
@ -199,13 +229,21 @@ namespace libtorrent
|
|||
// not add any padding
|
||||
void optimize(int pad_file_limit = -1);
|
||||
|
||||
sha1_hash hash(internal_file_entry const& fe) const;
|
||||
std::string const& symlink(internal_file_entry const& fe) const;
|
||||
time_t mtime(internal_file_entry const& fe) const;
|
||||
int file_index(internal_file_entry const& fe) const;
|
||||
size_type file_base(internal_file_entry const& fe) const;
|
||||
void set_file_base(internal_file_entry const& fe, size_type off);
|
||||
std::string file_path(internal_file_entry const& fe) const;
|
||||
|
||||
private:
|
||||
|
||||
void update_path_index(file_entry& e);
|
||||
void update_path_index(internal_file_entry& e);
|
||||
void reorder_file(int index, int dst);
|
||||
|
||||
// the list of files that this torrent consists of
|
||||
std::vector<file_entry> m_files;
|
||||
std::vector<internal_file_entry> m_files;
|
||||
|
||||
// if there are sha1 hashes for each individual file
|
||||
// there are as many entries in this array as the
|
||||
|
@ -216,7 +254,7 @@ namespace libtorrent
|
|||
std::vector<char const*> m_file_hashes;
|
||||
|
||||
// for files that are symlinks, the symlink
|
||||
// path_index in the file_entry indexes
|
||||
// path_index in the internal_file_entry indexes
|
||||
// this vector of strings
|
||||
std::vector<std::string> m_symlinks;
|
||||
|
||||
|
@ -231,7 +269,7 @@ namespace libtorrent
|
|||
// offsets)
|
||||
std::vector<size_type> m_file_base;
|
||||
|
||||
// all unique paths files have. The file_entry::path_index
|
||||
// all unique paths files have. The internal_file_entry::path_index
|
||||
// points into this array
|
||||
std::vector<std::string> m_paths;
|
||||
|
||||
|
|
|
@ -302,7 +302,7 @@ namespace libtorrent
|
|||
reverse_file_iterator rbegin_files() const { return m_files.rbegin(); }
|
||||
reverse_file_iterator rend_files() const { return m_files.rend(); }
|
||||
int num_files() const { return m_files.num_files(); }
|
||||
file_entry const& file_at(int index) const { return m_files.at(index); }
|
||||
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); }
|
||||
|
|
|
@ -118,7 +118,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.at(0)))) m_multifile = true;
|
||||
if (!m_multifile && has_parent_path(m_files.file_path(*m_files.begin()))) m_multifile = true;
|
||||
|
||||
// a piece_size of 0 means automatic
|
||||
if (piece_size == 0 && !m_merkle_torrent)
|
||||
|
@ -301,26 +301,26 @@ namespace libtorrent
|
|||
|
||||
if (!m_multifile)
|
||||
{
|
||||
if (m_include_mtime) info["mtime"] = m_files.mtime(m_files.at(0));
|
||||
info["length"] = m_files.at(0).size;
|
||||
if (m_files.at(0).pad_file
|
||||
|| m_files.at(0).hidden_attribute
|
||||
|| m_files.at(0).executable_attribute
|
||||
|| m_files.at(0).symlink_attribute)
|
||||
file_entry e = m_files.at(0);
|
||||
if (m_include_mtime) info["mtime"] = e.mtime;
|
||||
info["length"] = e.size;
|
||||
if (e.pad_file
|
||||
|| e.hidden_attribute
|
||||
|| e.executable_attribute
|
||||
|| e.symlink_attribute)
|
||||
{
|
||||
std::string& attr = info["attr"].string();
|
||||
if (m_files.at(0).pad_file) attr += 'p';
|
||||
if (m_files.at(0).hidden_attribute) attr += 'h';
|
||||
if (m_files.at(0).executable_attribute) attr += 'x';
|
||||
if (m_include_symlinks && m_files.at(0).symlink_attribute) attr += 'l';
|
||||
if (e.pad_file) attr += 'p';
|
||||
if (e.hidden_attribute) attr += 'h';
|
||||
if (e.executable_attribute) attr += 'x';
|
||||
if (m_include_symlinks && e.symlink_attribute) attr += 'l';
|
||||
}
|
||||
if (m_include_symlinks
|
||||
&& m_files.at(0).symlink_attribute
|
||||
&& m_files.at(0).symlink_index != -1)
|
||||
&& e.symlink_attribute)
|
||||
{
|
||||
entry& sympath_e = info["symlink path"];
|
||||
|
||||
std::string split = split_path(m_files.symlink(m_files.at(0)));
|
||||
std::string split = split_path(e.symlink_path);
|
||||
for (char const* e = split.c_str(); e != 0; e = next_path_element(e))
|
||||
sympath_e.list().push_back(entry(e));
|
||||
}
|
||||
|
|
|
@ -41,14 +41,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace libtorrent
|
||||
{
|
||||
boost::intrusive_ptr<file> file_pool::open_file(void* st, std::string const& p
|
||||
, file_entry const& fe, file_storage const& fs, int m, error_code& ec)
|
||||
, file_storage::iterator fe, 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, fs.file_index(*fe)));
|
||||
if (i != m_files.end())
|
||||
{
|
||||
lru_file_entry& e = i->second;
|
||||
|
@ -77,7 +77,7 @@ namespace libtorrent
|
|||
// the new read/write privilages
|
||||
TORRENT_ASSERT(e.file_ptr->refcount() == 1);
|
||||
e.file_ptr->close();
|
||||
std::string full_path = combine_path(p, fs.file_path(fe));
|
||||
std::string full_path = combine_path(p, fs.file_path(*fe));
|
||||
if (!e.file_ptr->open(full_path, m, ec))
|
||||
{
|
||||
m_files.erase(i);
|
||||
|
@ -115,12 +115,12 @@ namespace libtorrent
|
|||
ec = error_code(ENOMEM, get_posix_category());
|
||||
return e.file_ptr;
|
||||
}
|
||||
std::string full_path = combine_path(p, fs.file_path(fe));
|
||||
std::string full_path = combine_path(p, fs.file_path(*fe));
|
||||
if (!e.file_ptr->open(full_path, m, ec))
|
||||
return boost::intrusive_ptr<file>();
|
||||
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, fs.file_index(*fe)), e));
|
||||
TORRENT_ASSERT(e.file_ptr->is_open());
|
||||
return e.file_ptr;
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace libtorrent
|
|||
return piece_length();
|
||||
}
|
||||
|
||||
void file_storage::update_path_index(file_entry& e)
|
||||
void file_storage::update_path_index(internal_file_entry& e)
|
||||
{
|
||||
std::string parent = parent_path(e.filename());
|
||||
if (parent.empty())
|
||||
|
@ -95,9 +95,9 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
file_entry::~file_entry() { if (name_len == 0) free((void*)name); }
|
||||
internal_file_entry::~internal_file_entry() { if (name_len == 0) free((void*)name); }
|
||||
|
||||
file_entry::file_entry(file_entry const& fe)
|
||||
internal_file_entry::internal_file_entry(internal_file_entry const& fe)
|
||||
: name(0)
|
||||
, offset(fe.offset)
|
||||
, symlink_index(fe.symlink_index)
|
||||
|
@ -112,7 +112,7 @@ namespace libtorrent
|
|||
set_name(fe.name, fe.name_len);
|
||||
}
|
||||
|
||||
file_entry& file_entry::operator=(file_entry const& fe)
|
||||
internal_file_entry& internal_file_entry::operator=(internal_file_entry const& fe)
|
||||
{
|
||||
offset = fe.offset;
|
||||
size = fe.size;
|
||||
|
@ -126,7 +126,7 @@ namespace libtorrent
|
|||
return *this;
|
||||
}
|
||||
|
||||
void file_entry::set_name(char const* n, int borrow_chars)
|
||||
void internal_file_entry::set_name(char const* n, int borrow_chars)
|
||||
{
|
||||
TORRENT_ASSERT(borrow_chars >= 0);
|
||||
if (borrow_chars > 1023) borrow_chars = 1023;
|
||||
|
@ -143,7 +143,7 @@ namespace libtorrent
|
|||
name_len = borrow_chars;
|
||||
}
|
||||
|
||||
std::string file_entry::filename() const
|
||||
std::string internal_file_entry::filename() const
|
||||
{
|
||||
if (name_len) return std::string(name, name_len);
|
||||
return name ? name : "";
|
||||
|
@ -184,7 +184,7 @@ namespace libtorrent
|
|||
|
||||
namespace
|
||||
{
|
||||
bool compare_file_offset(file_entry const& lhs, file_entry const& rhs)
|
||||
bool compare_file_offset(internal_file_entry const& lhs, internal_file_entry const& rhs)
|
||||
{
|
||||
return lhs.offset < rhs.offset;
|
||||
}
|
||||
|
@ -193,11 +193,11 @@ namespace libtorrent
|
|||
file_storage::iterator file_storage::file_at_offset(size_type offset) const
|
||||
{
|
||||
// find the file iterator and file offset
|
||||
file_entry target;
|
||||
internal_file_entry target;
|
||||
target.offset = offset;
|
||||
TORRENT_ASSERT(!compare_file_offset(target, m_files.front()));
|
||||
|
||||
std::vector<file_entry>::const_iterator file_iter = std::upper_bound(
|
||||
std::vector<internal_file_entry>::const_iterator file_iter = std::upper_bound(
|
||||
begin(), end(), target, compare_file_offset);
|
||||
|
||||
TORRENT_ASSERT(file_iter != begin());
|
||||
|
@ -214,12 +214,12 @@ namespace libtorrent
|
|||
if (m_files.empty()) return ret;
|
||||
|
||||
// find the file iterator and file offset
|
||||
file_entry target;
|
||||
internal_file_entry target;
|
||||
target.offset = piece * (size_type)m_piece_length + offset;
|
||||
TORRENT_ASSERT(target.offset + size <= m_total_size);
|
||||
TORRENT_ASSERT(!compare_file_offset(target, m_files.front()));
|
||||
|
||||
std::vector<file_entry>::const_iterator file_iter = std::upper_bound(
|
||||
std::vector<internal_file_entry>::const_iterator file_iter = std::upper_bound(
|
||||
begin(), end(), target, compare_file_offset);
|
||||
|
||||
TORRENT_ASSERT(file_iter != begin());
|
||||
|
@ -244,8 +244,30 @@ namespace libtorrent
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string file_storage::file_path(file_entry const& fe) const
|
||||
|
||||
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.offset = ife.offset;
|
||||
ret.size = ife.size;
|
||||
ret.file_base = file_base(ife);
|
||||
ret.mtime = mtime(ife);
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string file_storage::file_path(internal_file_entry const& fe) const
|
||||
{
|
||||
TORRENT_ASSERT(fe.path_index >= -1 && fe.path_index < int(m_paths.size()));
|
||||
if (fe.path_index == -1) return fe.filename();
|
||||
|
@ -285,8 +307,8 @@ namespace libtorrent
|
|||
m_name = split_path(file).c_str();
|
||||
}
|
||||
TORRENT_ASSERT(m_name == split_path(file).c_str());
|
||||
m_files.push_back(file_entry());
|
||||
file_entry& e = m_files.back();
|
||||
m_files.push_back(internal_file_entry());
|
||||
internal_file_entry& e = m_files.back();
|
||||
e.set_name(file.c_str());
|
||||
e.size = size;
|
||||
e.offset = m_total_size;
|
||||
|
@ -309,25 +331,25 @@ namespace libtorrent
|
|||
m_total_size += size;
|
||||
}
|
||||
|
||||
void file_storage::add_file(file_entry const& ent, char const* filehash
|
||||
, std::string const* symlink, time_t mtime)
|
||||
void file_storage::add_file(file_entry const& ent, char const* filehash)
|
||||
{
|
||||
if (!has_parent_path(ent.filename()))
|
||||
if (!has_parent_path(ent.path))
|
||||
{
|
||||
// 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(m_files.empty());
|
||||
m_name = ent.filename();
|
||||
m_name = ent.path;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_files.empty())
|
||||
m_name = split_path(ent.filename()).c_str();
|
||||
m_name = split_path(ent.path).c_str();
|
||||
}
|
||||
m_files.push_back(ent);
|
||||
file_entry& e = m_files.back();
|
||||
internal_file_entry ife(ent);
|
||||
m_files.push_back(ife);
|
||||
internal_file_entry& e = m_files.back();
|
||||
e.offset = m_total_size;
|
||||
m_total_size += ent.size;
|
||||
if (filehash)
|
||||
|
@ -335,47 +357,48 @@ namespace libtorrent
|
|||
if (m_file_hashes.size() < m_files.size()) m_file_hashes.resize(m_files.size());
|
||||
m_file_hashes[m_files.size() - 1] = filehash;
|
||||
}
|
||||
if (symlink)
|
||||
if (!ent.symlink_path.empty())
|
||||
{
|
||||
e.symlink_index = m_symlinks.size();
|
||||
m_symlinks.push_back(*symlink);
|
||||
m_symlinks.push_back(ent.symlink_path);
|
||||
}
|
||||
if (mtime)
|
||||
if (ent.mtime)
|
||||
{
|
||||
if (m_mtime.size() < m_files.size()) m_mtime.resize(m_files.size());
|
||||
m_mtime[m_files.size() - 1] = mtime;
|
||||
m_mtime[m_files.size() - 1] = ent.mtime;
|
||||
}
|
||||
if (ent.file_base) set_file_base(e, ent.file_base);
|
||||
update_path_index(e);
|
||||
}
|
||||
|
||||
sha1_hash file_storage::hash(file_entry const& fe) const
|
||||
sha1_hash file_storage::hash(internal_file_entry const& fe) const
|
||||
{
|
||||
int index = &fe - &m_files[0];
|
||||
if (index >= m_file_hashes.size()) return sha1_hash(0);
|
||||
return sha1_hash(m_file_hashes[index]);
|
||||
}
|
||||
|
||||
std::string const& file_storage::symlink(file_entry const& fe) const
|
||||
std::string const& file_storage::symlink(internal_file_entry const& fe) const
|
||||
{
|
||||
TORRENT_ASSERT(fe.symlink_index < int(m_symlinks.size()));
|
||||
return m_symlinks[fe.symlink_index];
|
||||
}
|
||||
|
||||
time_t file_storage::mtime(file_entry const& fe) const
|
||||
time_t file_storage::mtime(internal_file_entry const& fe) const
|
||||
{
|
||||
int index = &fe - &m_files[0];
|
||||
if (index >= m_mtime.size()) return 0;
|
||||
return m_mtime[index];
|
||||
}
|
||||
|
||||
int file_storage::file_index(file_entry const& fe) const
|
||||
int file_storage::file_index(internal_file_entry const& fe) const
|
||||
{
|
||||
int index = &fe - &m_files[0];
|
||||
TORRENT_ASSERT(index >= 0 && index < m_files.size());
|
||||
return index;
|
||||
}
|
||||
|
||||
void file_storage::set_file_base(file_entry const& fe, size_type off)
|
||||
void file_storage::set_file_base(internal_file_entry const& fe, size_type off)
|
||||
{
|
||||
int index = &fe - &m_files[0];
|
||||
TORRENT_ASSERT(index >= 0 && index < m_files.size());
|
||||
|
@ -383,19 +406,19 @@ namespace libtorrent
|
|||
m_file_base[index] = off;
|
||||
}
|
||||
|
||||
size_type file_storage::file_base(file_entry const& fe) const
|
||||
size_type file_storage::file_base(internal_file_entry const& fe) const
|
||||
{
|
||||
int index = &fe - &m_files[0];
|
||||
if (index >= m_file_base.size()) return 0;
|
||||
return m_file_base[index];
|
||||
}
|
||||
|
||||
bool compare_file_entry_size(file_entry const& fe1, file_entry const& fe2)
|
||||
bool compare_file_entry_size(internal_file_entry const& fe1, internal_file_entry const& fe2)
|
||||
{ return fe1.size < fe2.size; }
|
||||
|
||||
void file_storage::reorder_file(int index, int dst)
|
||||
{
|
||||
file_entry e = m_files[index];
|
||||
internal_file_entry e = m_files[index];
|
||||
m_files.erase(m_files.begin() + index);
|
||||
m_files.insert(m_files.begin() + dst, e);
|
||||
if (!m_mtime.empty())
|
||||
|
@ -443,7 +466,7 @@ namespace libtorrent
|
|||
|
||||
// put the largest file at the front, to make sure
|
||||
// it's aligned
|
||||
std::vector<file_entry>::iterator i = std::max_element(m_files.begin(), m_files.end()
|
||||
std::vector<internal_file_entry>::iterator i = std::max_element(m_files.begin(), m_files.end()
|
||||
, &compare_file_entry_size);
|
||||
|
||||
int index = file_index(*i);
|
||||
|
@ -451,7 +474,7 @@ namespace libtorrent
|
|||
|
||||
size_type off = 0;
|
||||
int padding_file = 0;
|
||||
for (std::vector<file_entry>::iterator i = m_files.begin();
|
||||
for (std::vector<internal_file_entry>::iterator i = m_files.begin();
|
||||
i != m_files.end(); ++i)
|
||||
{
|
||||
if (pad_file_limit >= 0
|
||||
|
@ -466,8 +489,8 @@ namespace libtorrent
|
|||
int pad_size = alignment - (off & (alignment-1));
|
||||
|
||||
// find the largest file that fits in pad_size
|
||||
std::vector<file_entry>::iterator best_match = m_files.end();
|
||||
for (std::vector<file_entry>::iterator j = i+1; j < m_files.end(); ++j)
|
||||
std::vector<internal_file_entry>::iterator best_match = m_files.end();
|
||||
for (std::vector<internal_file_entry>::iterator j = i+1; j < m_files.end(); ++j)
|
||||
{
|
||||
if (j->size > pad_size) continue;
|
||||
if (best_match == m_files.end() || j->size > best_match->size)
|
||||
|
@ -488,7 +511,7 @@ namespace libtorrent
|
|||
// we could not find a file that fits in pad_size
|
||||
// add a padding file
|
||||
|
||||
file_entry e;
|
||||
internal_file_entry e;
|
||||
i = m_files.insert(i, e);
|
||||
i->size = pad_size;
|
||||
i->offset = off;
|
||||
|
|
|
@ -409,7 +409,8 @@ namespace libtorrent
|
|||
file_storage const& m_files;
|
||||
|
||||
// helper function to open a file in the file pool with the right mode
|
||||
boost::intrusive_ptr<file> open_file(file_entry const& fe, int mode, error_code& ec) const;
|
||||
boost::intrusive_ptr<file> open_file(file_storage::iterator fe, int mode
|
||||
, error_code& ec) const;
|
||||
|
||||
std::vector<boost::uint8_t> m_file_priority;
|
||||
std::string m_save_path;
|
||||
|
@ -553,7 +554,7 @@ namespace libtorrent
|
|||
if (ec || s.file_size > file_iter->size || file_iter->size == 0)
|
||||
{
|
||||
ec.clear();
|
||||
boost::intrusive_ptr<file> f = open_file(*file_iter, file::read_write, ec);
|
||||
boost::intrusive_ptr<file> f = open_file(file_iter, file::read_write, ec);
|
||||
if (ec) set_error(file_path, ec);
|
||||
else if (f)
|
||||
{
|
||||
|
@ -577,7 +578,7 @@ namespace libtorrent
|
|||
if (index < 0 || index >= m_files.num_files()) return;
|
||||
|
||||
error_code ec;
|
||||
boost::intrusive_ptr<file> f = open_file(files().at(index), file::read_write, ec);
|
||||
boost::intrusive_ptr<file> f = open_file(files().begin() + index, file::read_write, ec);
|
||||
if (ec || !f) return;
|
||||
|
||||
f->finalize();
|
||||
|
@ -702,7 +703,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(slot < m_files.num_pieces());
|
||||
|
||||
size_type file_offset = (size_type)slot * m_files.piece_length();
|
||||
std::vector<file_entry>::const_iterator file_iter;
|
||||
file_storage::iterator file_iter;
|
||||
|
||||
for (file_iter = files().begin();;)
|
||||
{
|
||||
|
@ -715,7 +716,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
error_code ec;
|
||||
boost::intrusive_ptr<file> file_handle = open_file(*file_iter, file::read_only, ec);
|
||||
boost::intrusive_ptr<file> file_handle = open_file(file_iter, file::read_only, ec);
|
||||
if (!file_handle || ec) return slot;
|
||||
|
||||
size_type data_start = file_handle->sparse_end(file_offset);
|
||||
|
@ -1057,7 +1058,7 @@ ret:
|
|||
// 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<file> f = open_file(*file_iter, file::read_only, ec);
|
||||
boost::intrusive_ptr<file> f = open_file(file_iter, file::read_only, ec);
|
||||
|
||||
size_type ret = 0;
|
||||
if (f && !ec) ret = f->phys_offset(file_offset);
|
||||
|
@ -1130,7 +1131,7 @@ ret:
|
|||
|
||||
// find the file iterator and file offset
|
||||
size_type file_offset = start;
|
||||
std::vector<file_entry>::const_iterator file_iter;
|
||||
file_storage::iterator file_iter;
|
||||
|
||||
for (file_iter = files().begin();;)
|
||||
{
|
||||
|
@ -1179,8 +1180,8 @@ ret:
|
|||
TORRENT_ASSERT(int(slices.size()) > counter);
|
||||
size_type slice_size = slices[counter].size;
|
||||
TORRENT_ASSERT(slice_size == file_bytes_left);
|
||||
TORRENT_ASSERT(&files().at(slices[counter].file_index)
|
||||
== &*file_iter);
|
||||
TORRENT_ASSERT((files().begin() + slices[counter].file_index)
|
||||
== file_iter);
|
||||
++counter;
|
||||
#endif
|
||||
|
||||
|
@ -1199,7 +1200,7 @@ ret:
|
|||
}
|
||||
|
||||
error_code ec;
|
||||
file_handle = open_file(*file_iter, op.mode, ec);
|
||||
file_handle = open_file(file_iter, op.mode, ec);
|
||||
if (!file_handle || ec)
|
||||
{
|
||||
std::string path = combine_path(m_save_path, files().file_path(*file_iter));
|
||||
|
@ -1309,12 +1310,13 @@ ret:
|
|||
return readv(&b, slot, offset, 1);
|
||||
}
|
||||
|
||||
boost::intrusive_ptr<file> storage::open_file(file_entry const& fe, int mode, error_code& ec) const
|
||||
boost::intrusive_ptr<file> storage::open_file(file_storage::iterator fe, 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))
|
||||
&& ((fe->offset + files().file_base(*fe)) & (m_page_size-1)) == 0))
|
||||
mode |= file::no_buffer;
|
||||
if (!m_allocate_files) mode |= file::sparse;
|
||||
if (m_settings && settings().no_atime_storage) mode |= file::no_atime;
|
||||
|
|
|
@ -182,12 +182,6 @@ namespace libtorrent
|
|||
return valid_encoding;
|
||||
}
|
||||
|
||||
void verify_encoding(file_entry& target)
|
||||
{
|
||||
std::string p = target.filename();
|
||||
if (!verify_encoding(p, true)) target.set_name(p.c_str());
|
||||
}
|
||||
|
||||
// TODO: should this take a char const*?
|
||||
bool valid_path_element(std::string const& element)
|
||||
{
|
||||
|
@ -233,7 +227,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
bool extract_single_file(lazy_entry const& dict, file_entry& target
|
||||
, std::string const& root_dir, lazy_entry const** filehash, std::string* symlink
|
||||
, std::string const& root_dir, lazy_entry const** filehash
|
||||
, lazy_entry const** filename, time_t* mtime)
|
||||
{
|
||||
if (dict.type() != lazy_entry::dict_t) return false;
|
||||
|
@ -266,13 +260,13 @@ namespace libtorrent
|
|||
path = combine_path(path, path_element);
|
||||
}
|
||||
path = sanitize_path(path);
|
||||
verify_encoding(target);
|
||||
verify_encoding(path, true);
|
||||
|
||||
// bitcomet pad file
|
||||
if (path.find("_____padding_file_") != std::string::npos)
|
||||
target.pad_file = true;
|
||||
|
||||
target.set_name(path.c_str());
|
||||
target.path = path;
|
||||
|
||||
lazy_entry const* attr = dict.dict_find_string("attr");
|
||||
if (attr)
|
||||
|
@ -300,10 +294,8 @@ namespace libtorrent
|
|||
{
|
||||
std::string path_element = s_p->list_at(i)->string_value();
|
||||
trim_path_element(path_element);
|
||||
*symlink = combine_path(*symlink, path_element);
|
||||
target.symlink_path = combine_path(target.symlink_path, path_element);
|
||||
}
|
||||
// indeicate that we have a symlink
|
||||
target.symlink_index = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -339,11 +331,10 @@ namespace libtorrent
|
|||
{
|
||||
lazy_entry const* file_hash = 0;
|
||||
time_t mtime = 0;
|
||||
std::string symlink;
|
||||
file_entry e;
|
||||
lazy_entry const* fee = 0;
|
||||
if (!extract_single_file(*list.list_at(i), e, root_dir
|
||||
, &file_hash, &symlink, &fee, &mtime))
|
||||
, &file_hash, &fee, &mtime))
|
||||
return false;
|
||||
|
||||
// TODO: this logic should be a separate step
|
||||
|
@ -354,22 +345,19 @@ namespace libtorrent
|
|||
|
||||
// as long as this file already exists
|
||||
// increase the counter
|
||||
std::string path = e.filename();
|
||||
while (!files.insert(path).second)
|
||||
while (!files.insert(e.path).second)
|
||||
{
|
||||
++cnt;
|
||||
char suffix[50];
|
||||
snprintf(suffix, sizeof(suffix), ".%d%s", cnt, extension(path).c_str());
|
||||
replace_extension(path, suffix);
|
||||
snprintf(suffix, sizeof(suffix), ".%d%s", cnt, extension(e.path).c_str());
|
||||
replace_extension(e.path, suffix);
|
||||
}
|
||||
e.set_name(path.c_str());
|
||||
target.add_file(e, file_hash ? file_hash->string_ptr() + info_ptr_diff : 0
|
||||
, e.symlink_index != -1 ? &symlink : 0, mtime);
|
||||
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
|
||||
file_entry const& fe = target.at(target.num_files() - 1);
|
||||
internal_file_entry const& fe = *target.rbegin();
|
||||
// TODO: once the filename renaming is removed from here
|
||||
// this check can be removed as well
|
||||
if (fee && fe.filename() == fee->string_value())
|
||||
|
@ -377,7 +365,7 @@ namespace libtorrent
|
|||
// 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<file_entry&>(fe).set_name(str_ptr, fee->string_length());
|
||||
const_cast<internal_file_entry&>(fe).set_name(str_ptr, fee->string_length());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -807,12 +795,10 @@ namespace libtorrent
|
|||
// if there's no list of files, there has to be a length
|
||||
// field.
|
||||
file_entry e;
|
||||
e.set_name(name.c_str());
|
||||
e.path = name;
|
||||
e.offset = 0;
|
||||
e.size = info.dict_find_int_value("length", -1);
|
||||
size_type ts = info.dict_find_int_value("mtime", -1);
|
||||
time_t mtime = 0;
|
||||
if (ts > 0) mtime = std::time_t(ts);
|
||||
e.mtime = info.dict_find_int_value("mtime", 0);
|
||||
lazy_entry const* attr = info.dict_find_string("attr");
|
||||
if (attr)
|
||||
{
|
||||
|
@ -829,30 +815,27 @@ 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);
|
||||
symlink = combine_path(symlink, path_element);
|
||||
e.symlink_path = combine_path(e.symlink_path, path_element);
|
||||
}
|
||||
e.symlink_index = 0;
|
||||
}
|
||||
lazy_entry const* fh = info.dict_find_string("sha1");
|
||||
if (fh && fh->string_length() != 20) fh = 0;
|
||||
|
||||
// bitcomet pad file
|
||||
if (e.filename().find("_____padding_file_") != std::string::npos)
|
||||
if (e.path.find("_____padding_file_") != std::string::npos)
|
||||
e.pad_file = true;
|
||||
if (e.size < 0)
|
||||
{
|
||||
ec = errors::torrent_invalid_length;
|
||||
return false;
|
||||
}
|
||||
m_files.add_file(e, fh ? fh->string_ptr() + info_ptr_diff : 0
|
||||
, e.symlink_index != -1 ? &symlink : 0, mtime);
|
||||
m_files.add_file(e, fh ? fh->string_ptr() + info_ptr_diff : 0);
|
||||
m_multifile = false;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -257,11 +257,11 @@ int run_suite(char const* protocol, bool test_url_seed, bool chunked_encoding)
|
|||
// verify that the file hashes are correct
|
||||
for (int i = 0; i < torrent_file->num_files(); ++i)
|
||||
{
|
||||
sha1_hash h1 = torrent_file->files().hash(torrent_file->file_at(i));
|
||||
sha1_hash h1 = torrent_file->file_at(i).filehash;
|
||||
sha1_hash h2 = file_hash(combine_path("./tmp1_web_seed"
|
||||
, torrent_file->files().file_path(torrent_file->file_at(i))));
|
||||
, torrent_file->file_at(i).path));
|
||||
fprintf(stderr, "%s: %s == %s\n"
|
||||
, torrent_file->files().file_path(torrent_file->file_at(i)).c_str()
|
||||
, torrent_file->file_at(i).path.c_str()
|
||||
, to_hex(h1.to_string()).c_str(), to_hex(h2.to_string()).c_str());
|
||||
TEST_EQUAL(h1, h2);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue