added support for generating torrent files with padding files in them
This commit is contained in:
parent
ce6531640b
commit
eea890de11
|
@ -22,6 +22,7 @@
|
||||||
* added monitoring of the DHT lookups
|
* added monitoring of the DHT lookups
|
||||||
* added bandwidth reports for estimated TCP/IP overhead and DHT
|
* added bandwidth reports for estimated TCP/IP overhead and DHT
|
||||||
* includes DHT traffic in the rate limiter
|
* includes DHT traffic in the rate limiter
|
||||||
|
* added support for bitcomet padding files
|
||||||
|
|
||||||
release 0.14.2
|
release 0.14.2
|
||||||
|
|
||||||
|
|
|
@ -118,8 +118,8 @@ file structure. Its synopsis::
|
||||||
bool is_valid() const;
|
bool is_valid() const;
|
||||||
|
|
||||||
void add_file(file_entry const& e);
|
void add_file(file_entry const& e);
|
||||||
void add_file(fs::path const& p, size_type size);
|
void add_file(fs::path const& p, size_type size, bool pad_file = false);
|
||||||
void add_file(fs::wpath const& p, size_type size);
|
void add_file(fs::wpath const& p, size_type size, bool pad_file = false);
|
||||||
void rename_file(int index, std::string const& new_filename);
|
void rename_file(int index, std::string const& new_filename);
|
||||||
void rename_file(int index, std::wstring const& new_filename);
|
void rename_file(int index, std::wstring const& new_filename);
|
||||||
|
|
||||||
|
@ -161,8 +161,7 @@ The ``create_torrent`` class has the following synopsis::
|
||||||
|
|
||||||
struct create_torrent
|
struct create_torrent
|
||||||
{
|
{
|
||||||
create_torrent(file_storage& fs, int piece_size);
|
create_torrent(file_storage& fs, int piece_size = 0, int pad_size_limit = -1);
|
||||||
create_torrent(file_storage& fs);
|
|
||||||
create_torrent(torrent_info const& ti);
|
create_torrent(torrent_info const& ti);
|
||||||
|
|
||||||
entry generate() const;
|
entry generate() const;
|
||||||
|
@ -188,15 +187,16 @@ create_torrent()
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
create_torrent(file_storage& fs, int piece_size);
|
create_torrent(file_storage& fs, int piece_size = 0, int pad_size_limit = -1);
|
||||||
create_torrent(file_storage& fs);
|
|
||||||
create_torrent(torrent_info const& ti);
|
create_torrent(torrent_info const& ti);
|
||||||
|
|
||||||
The ``piece_size`` is the size of each piece in bytes. It must
|
The ``piece_size`` is the size of each piece in bytes. It must
|
||||||
be a multiple of 16 kiB.
|
be a multiple of 16 kiB. If a piece size of 0 is specified, a
|
||||||
|
piece_size will becalculated such that the torrent file is roughly 40 kB.
|
||||||
|
|
||||||
The constructor that does not take a piece_size will calculate
|
If a ``pad_size_limit`` is specified (other than -1), any file larger than
|
||||||
a piece size such that the torrent file is roughly 40 kB.
|
the specified number of bytes will be preceeded by a pad file to align it
|
||||||
|
with the start od a piece.
|
||||||
|
|
||||||
The overlad that takes a ``torrent_info`` object will make a verbatim
|
The overlad that takes a ``torrent_info`` object will make a verbatim
|
||||||
copy of its info dictionary (to preserve the info-hash). The copy of
|
copy of its info dictionary (to preserve the info-hash). The copy of
|
||||||
|
|
|
@ -65,19 +65,33 @@ void print_progress(int i, int num)
|
||||||
std::cerr << "\r" << (i+1) << "/" << num;
|
std::cerr << "\r" << (i+1) << "/" << num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_usage()
|
||||||
|
{
|
||||||
|
std::cerr << "usage: make_torrent FILE [OPTIONS]\n"
|
||||||
|
"\n"
|
||||||
|
"Generates a torrent file from the specified file\n"
|
||||||
|
"or directory and writes it to standard out\n\n"
|
||||||
|
"OPTIONS:\n"
|
||||||
|
"-w url adds a web seed to the torrent with\n"
|
||||||
|
" the specified url\n"
|
||||||
|
"-t url adds the specified tracker to the\n"
|
||||||
|
" torrent\n"
|
||||||
|
"-p bytes enables padding files. Files larger\n"
|
||||||
|
" than bytes will be piece-aligned\n"
|
||||||
|
"-s bytes specifies a piece size for the torrent\n"
|
||||||
|
" This has to be a multiple of 16 kiB\n";
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
using namespace boost::filesystem;
|
using namespace boost::filesystem;
|
||||||
|
|
||||||
int piece_size = 256 * 1024;
|
|
||||||
char const* creator_str = "libtorrent";
|
char const* creator_str = "libtorrent";
|
||||||
|
|
||||||
if (argc != 4 && argc != 5)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
std::cerr << "usage: make_torrent <output torrent-file> "
|
print_usage();
|
||||||
"<announce url> <file or directory to create torrent from> "
|
|
||||||
"[url-seed]\n";
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,24 +99,65 @@ int main(int argc, char* argv[])
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
std::vector<std::string> web_seeds;
|
||||||
|
std::vector<std::string> trackers;
|
||||||
|
int pad_file_limit = -1;
|
||||||
|
int piece_size = 0;
|
||||||
|
|
||||||
|
for (int i = 2; i < argc; ++i)
|
||||||
|
{
|
||||||
|
if (argv[i][0] != '-')
|
||||||
|
{
|
||||||
|
print_usage();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (argv[i][1])
|
||||||
|
{
|
||||||
|
case 'w':
|
||||||
|
++i;
|
||||||
|
web_seeds.push_back(argv[i]);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
++i;
|
||||||
|
trackers.push_back(argv[i]);
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
++i;
|
||||||
|
pad_file_limit = atoi(argv[i]);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
++i;
|
||||||
|
piece_size = atoi(argv[i]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_usage();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
file_storage fs;
|
file_storage fs;
|
||||||
file_pool fp;
|
file_pool fp;
|
||||||
path full_path = complete(path(argv[3]));
|
path full_path = complete(path(argv[1]));
|
||||||
|
|
||||||
add_files(fs, full_path, file_filter);
|
add_files(fs, full_path, file_filter);
|
||||||
|
|
||||||
create_torrent t(fs, piece_size);
|
create_torrent t(fs, piece_size, pad_file_limit);
|
||||||
t.add_tracker(argv[2]);
|
for (std::vector<std::string>::iterator i = trackers.begin()
|
||||||
|
, end(trackers.end()); i != end; ++i)
|
||||||
|
t.add_tracker(*i);
|
||||||
|
|
||||||
|
for (std::vector<std::string>::iterator i = web_seeds.begin()
|
||||||
|
, end(web_seeds.end()); i != end; ++i)
|
||||||
|
t.add_url_seed(*i);
|
||||||
|
|
||||||
set_piece_hashes(t, full_path.branch_path()
|
set_piece_hashes(t, full_path.branch_path()
|
||||||
, boost::bind(&print_progress, _1, t.num_pieces()));
|
, boost::bind(&print_progress, _1, t.num_pieces()));
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
t.set_creator(creator_str);
|
t.set_creator(creator_str);
|
||||||
|
|
||||||
if (argc == 5) t.add_url_seed(argv[4]);
|
// create the torrent and print it to stdout
|
||||||
|
bencode(std::ostream_iterator<char>(std::cout), t.generate());
|
||||||
// create the torrent and print it to out
|
|
||||||
ofstream out(complete(path(argv[1])), std::ios_base::binary);
|
|
||||||
bencode(std::ostream_iterator<char>(out), t.generate());
|
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
|
|
|
@ -68,8 +68,7 @@ namespace libtorrent
|
||||||
|
|
||||||
struct TORRENT_EXPORT create_torrent
|
struct TORRENT_EXPORT create_torrent
|
||||||
{
|
{
|
||||||
create_torrent(file_storage& fs, int piece_size);
|
create_torrent(file_storage& fs, int piece_size = 0, int pad_file_limit = -1);
|
||||||
create_torrent(file_storage& fs);
|
|
||||||
create_torrent(torrent_info const& ti);
|
create_torrent(torrent_info const& ti);
|
||||||
entry generate() const;
|
entry generate() const;
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace libtorrent
|
||||||
return m_files[index];
|
return m_files[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type total_size() const { TORRENT_ASSERT(m_piece_length > 0); return m_total_size; }
|
size_type total_size() const { return m_total_size; }
|
||||||
void set_num_pieces(int n) { m_num_pieces = n; }
|
void set_num_pieces(int n) { m_num_pieces = n; }
|
||||||
int num_pieces() const { TORRENT_ASSERT(m_piece_length > 0); return m_num_pieces; }
|
int num_pieces() const { TORRENT_ASSERT(m_piece_length > 0); return m_num_pieces; }
|
||||||
void set_piece_length(int l) { m_piece_length = l; }
|
void set_piece_length(int l) { m_piece_length = l; }
|
||||||
|
@ -132,6 +132,11 @@ namespace libtorrent
|
||||||
swap(ti.m_name, m_name);
|
swap(ti.m_name, m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if pad_file_limit >= 0, files larger than
|
||||||
|
// that limit will be padded, default is to
|
||||||
|
// not add any padding
|
||||||
|
void optimize(int pad_file_limit = -1);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_piece_length;
|
int m_piece_length;
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,7 @@ namespace libtorrent
|
||||||
|
|
||||||
struct TORRENT_EXPORT storage_interface
|
struct TORRENT_EXPORT storage_interface
|
||||||
{
|
{
|
||||||
|
storage_interface(): m_io_thread(0) {}
|
||||||
// create directories and set file sizes
|
// create directories and set file sizes
|
||||||
// if allocate_files is true.
|
// if allocate_files is true.
|
||||||
// allocate_files is true if allocation mode
|
// allocate_files is true if allocation mode
|
||||||
|
@ -167,7 +168,7 @@ namespace libtorrent
|
||||||
// non-zero return value indicates an error
|
// non-zero return value indicates an error
|
||||||
virtual bool delete_files() = 0;
|
virtual bool delete_files() = 0;
|
||||||
|
|
||||||
disk_io_thread& io_thread() { return *m_io_thread; }
|
disk_io_thread* io_thread() { return m_io_thread; }
|
||||||
|
|
||||||
void set_error(boost::filesystem::path const& file, error_code const& ec) const
|
void set_error(boost::filesystem::path const& file, error_code const& ec) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace gr = boost::gregorian;
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
create_torrent::create_torrent(file_storage& fs, int size)
|
create_torrent::create_torrent(file_storage& fs, int piece_size, int pad_file_limit)
|
||||||
: m_files(fs)
|
: m_files(fs)
|
||||||
, m_creation_date(pt::second_clock::universal_time())
|
, m_creation_date(pt::second_clock::universal_time())
|
||||||
, m_multifile(fs.num_files() > 1)
|
, m_multifile(fs.num_files() > 1)
|
||||||
|
@ -55,47 +55,33 @@ namespace libtorrent
|
||||||
if (!m_multifile && m_files.at(0).path.has_parent_path()) m_multifile = true;
|
if (!m_multifile && m_files.at(0).path.has_parent_path()) m_multifile = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// a piece_size of 0 means automatic
|
||||||
|
if (piece_size == 0)
|
||||||
|
{
|
||||||
|
const int target_size = 40 * 1024;
|
||||||
|
piece_size = fs.total_size() / (target_size / 20);
|
||||||
|
|
||||||
|
for (int i = 2*1024*1024; i >= 16*1024; i /= 2)
|
||||||
|
{
|
||||||
|
if (piece_size < i) continue;
|
||||||
|
piece_size = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// make sure the size is an even power of 2
|
// make sure the size is an even power of 2
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
for (int i = 0; i < 32; ++i)
|
for (int i = 0; i < 32; ++i)
|
||||||
{
|
{
|
||||||
if (size & (1 << i))
|
if (piece_size & (1 << i))
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT((size & ~(1 << i)) == 0);
|
TORRENT_ASSERT((piece_size & ~(1 << i)) == 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
m_files.set_piece_length(size);
|
m_files.set_piece_length(piece_size);
|
||||||
m_files.set_num_pieces(static_cast<int>(
|
m_files.optimize(pad_file_limit);
|
||||||
(m_files.total_size() + m_files.piece_length() - 1) / m_files.piece_length()));
|
|
||||||
m_piece_hash.resize(m_files.num_pieces());
|
|
||||||
}
|
|
||||||
|
|
||||||
create_torrent::create_torrent(file_storage& fs)
|
|
||||||
: m_files(fs)
|
|
||||||
, m_creation_date(pt::second_clock::universal_time())
|
|
||||||
, m_multifile(fs.num_files() > 1)
|
|
||||||
, m_private(false)
|
|
||||||
{
|
|
||||||
TORRENT_ASSERT(fs.num_files() > 0);
|
|
||||||
#if BOOST_VERSION < 103600
|
|
||||||
if (!m_multifile && m_files.at(0).path.has_branch_path()) m_multifile = true;
|
|
||||||
#else
|
|
||||||
if (!m_multifile && m_files.at(0).path.has_parent_path()) m_multifile = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const int target_size = 40 * 1024;
|
|
||||||
int size = fs.total_size() / (target_size / 20);
|
|
||||||
|
|
||||||
for (int i = 4*1024*1024; i > 16*1024; i /= 2)
|
|
||||||
{
|
|
||||||
if (size < i) continue;
|
|
||||||
size = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_files.set_piece_length(size);
|
|
||||||
m_files.set_num_pieces(static_cast<int>(
|
m_files.set_num_pieces(static_cast<int>(
|
||||||
(m_files.total_size() + m_files.piece_length() - 1) / m_files.piece_length()));
|
(m_files.total_size() + m_files.piece_length() - 1) / m_files.piece_length()));
|
||||||
m_piece_hash.resize(m_files.num_pieces());
|
m_piece_hash.resize(m_files.num_pieces());
|
||||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "libtorrent/file_storage.hpp"
|
#include "libtorrent/file_storage.hpp"
|
||||||
#include "libtorrent/utf8.hpp"
|
#include "libtorrent/utf8.hpp"
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
|
@ -186,5 +187,81 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
add_file(e.path, e.size, e.pad_file);
|
add_file(e.path, e.size, e.pad_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void file_storage::optimize(int pad_file_limit)
|
||||||
|
{
|
||||||
|
// the main purpuse of padding is to optimize disk
|
||||||
|
// I/O. This is a conservative memory page size assumption
|
||||||
|
int alignment = 8*1024;
|
||||||
|
|
||||||
|
// it doesn't make any sense to pad files that
|
||||||
|
// are smaller than one piece
|
||||||
|
if (pad_file_limit >= 0 && pad_file_limit < alignment)
|
||||||
|
pad_file_limit = alignment;
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
, boost::bind(&file_entry::size, _1) < boost::bind(&file_entry::size, _2));
|
||||||
|
|
||||||
|
using std::iter_swap;
|
||||||
|
iter_swap(i, m_files.begin());
|
||||||
|
|
||||||
|
size_type off = 0;
|
||||||
|
int padding_file = 0;
|
||||||
|
for (std::vector<file_entry>::iterator i = m_files.begin();
|
||||||
|
i != m_files.end(); ++i)
|
||||||
|
{
|
||||||
|
if (pad_file_limit >= 0
|
||||||
|
&& (off & (alignment-1)) != 0
|
||||||
|
&& i->size > pad_file_limit)
|
||||||
|
{
|
||||||
|
// if we have pad files enabled, and this file is
|
||||||
|
// not piece-aligned and the file size exceeds the
|
||||||
|
// limit, so add a padding file in front of it
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (j->size > pad_size) continue;
|
||||||
|
if (best_match == m_files.end() || j->size > best_match->size)
|
||||||
|
best_match = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best_match != m_files.end())
|
||||||
|
{
|
||||||
|
// we found one
|
||||||
|
file_entry e = *best_match;
|
||||||
|
m_files.erase(best_match);
|
||||||
|
i = m_files.insert(i, e);
|
||||||
|
i->offset = off;
|
||||||
|
off += i->size;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we could not find a file that fits in pad_size
|
||||||
|
// add a padding file
|
||||||
|
|
||||||
|
file_entry e;
|
||||||
|
i = m_files.insert(i, e);
|
||||||
|
i->size = pad_size;
|
||||||
|
i->offset = off;
|
||||||
|
i->file_base = 0;
|
||||||
|
char name[10];
|
||||||
|
sprintf(name, "%d", padding_file);
|
||||||
|
i->path = *(i+1)->path.begin();
|
||||||
|
i->path /= "_____padding_file_";
|
||||||
|
i->path /= name;
|
||||||
|
off += pad_size;
|
||||||
|
++padding_file;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
i->offset = off;
|
||||||
|
off += i->size;
|
||||||
|
}
|
||||||
|
m_total_size = off;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -454,13 +454,15 @@ namespace libtorrent
|
||||||
int slot_size = piece_size - ph.offset;
|
int slot_size = piece_size - ph.offset;
|
||||||
if (slot_size > 0)
|
if (slot_size > 0)
|
||||||
{
|
{
|
||||||
|
int block_size = 16 * 1024;
|
||||||
|
if (io_thread()) block_size = io_thread()->block_size();
|
||||||
int size = slot_size;
|
int size = slot_size;
|
||||||
int num_blocks = (size + io_thread().block_size() - 1) / io_thread().block_size();
|
int num_blocks = (size + block_size - 1) / block_size;
|
||||||
file::iovec_t* bufs = TORRENT_ALLOCA(file::iovec_t, num_blocks);
|
file::iovec_t* bufs = TORRENT_ALLOCA(file::iovec_t, num_blocks);
|
||||||
for (int i = 0; i < num_blocks; ++i)
|
for (int i = 0; i < num_blocks; ++i)
|
||||||
{
|
{
|
||||||
bufs[i].iov_base = io_thread().allocate_buffer();
|
bufs[i].iov_base = io_thread()->allocate_buffer();
|
||||||
bufs[i].iov_len = (std::min)(io_thread().block_size(), size);
|
bufs[i].iov_len = (std::min)(block_size, size);
|
||||||
size -= bufs[i].iov_len;
|
size -= bufs[i].iov_len;
|
||||||
}
|
}
|
||||||
readv(bufs, slot, ph.offset, num_blocks);
|
readv(bufs, slot, ph.offset, num_blocks);
|
||||||
|
@ -468,7 +470,7 @@ namespace libtorrent
|
||||||
for (int i = 0; i < num_blocks; ++i)
|
for (int i = 0; i < num_blocks; ++i)
|
||||||
{
|
{
|
||||||
ph.h.update((char const*)bufs[i].iov_base, bufs[i].iov_len);
|
ph.h.update((char const*)bufs[i].iov_base, bufs[i].iov_len);
|
||||||
io_thread().free_buffer((char*)bufs[i].iov_base);
|
io_thread()->free_buffer((char*)bufs[i].iov_base);
|
||||||
}
|
}
|
||||||
if (error()) return sha1_hash(0);
|
if (error()) return sha1_hash(0);
|
||||||
}
|
}
|
||||||
|
@ -526,7 +528,8 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
error_code ec;
|
error_code ec;
|
||||||
int mode = file::read_write;
|
int mode = file::read_write;
|
||||||
if (io_thread().no_buffer()
|
if (io_thread()
|
||||||
|
&& io_thread()->no_buffer()
|
||||||
&& ((file_iter->offset + file_iter->file_base) & (m_page_size-1)) == 0)
|
&& ((file_iter->offset + file_iter->file_base) & (m_page_size-1)) == 0)
|
||||||
mode |= file::no_buffer;
|
mode |= file::no_buffer;
|
||||||
boost::shared_ptr<file> f = m_pool.open_file(this
|
boost::shared_ptr<file> f = m_pool.open_file(this
|
||||||
|
@ -915,22 +918,22 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TORRENT_ALLOCATE_BLOCKS(bufs, num_blocks, piece_size) \
|
#define TORRENT_ALLOCATE_BLOCKS(bufs, num_blocks, piece_size) \
|
||||||
int num_blocks = (piece_size + io_thread().block_size() - 1) / io_thread().block_size(); \
|
int num_blocks = (piece_size + io_thread()->block_size() - 1) / io_thread()->block_size(); \
|
||||||
file::iovec_t* bufs = TORRENT_ALLOCA(file::iovec_t, num_blocks); \
|
file::iovec_t* bufs = TORRENT_ALLOCA(file::iovec_t, num_blocks); \
|
||||||
for (int i = 0, size = piece_size; i < num_blocks; ++i) \
|
for (int i = 0, size = piece_size; i < num_blocks; ++i) \
|
||||||
{ \
|
{ \
|
||||||
bufs[i].iov_base = io_thread().allocate_buffer(); \
|
bufs[i].iov_base = io_thread()->allocate_buffer(); \
|
||||||
bufs[i].iov_len = (std::min)(io_thread().block_size(), size); \
|
bufs[i].iov_len = (std::min)(io_thread()->block_size(), size); \
|
||||||
size -= bufs[i].iov_len; \
|
size -= bufs[i].iov_len; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TORRENT_FREE_BLOCKS(bufs, num_blocks) \
|
#define TORRENT_FREE_BLOCKS(bufs, num_blocks) \
|
||||||
for (int i = 0; i < num_blocks; ++i) \
|
for (int i = 0; i < num_blocks; ++i) \
|
||||||
io_thread().free_buffer((char*)bufs[i].iov_base);
|
io_thread()->free_buffer((char*)bufs[i].iov_base);
|
||||||
|
|
||||||
#define TORRENT_SET_SIZE(bufs, size, num_bufs) \
|
#define TORRENT_SET_SIZE(bufs, size, num_bufs) \
|
||||||
for (num_bufs = 0; size > 0; size -= io_thread().block_size(), ++num_bufs) \
|
for (num_bufs = 0; size > 0; size -= io_thread()->block_size(), ++num_bufs) \
|
||||||
bufs[num_bufs].iov_len = (std::min)(io_thread().block_size(), size)
|
bufs[num_bufs].iov_len = (std::min)(io_thread()->block_size(), size)
|
||||||
|
|
||||||
|
|
||||||
bool storage::move_slot(int src_slot, int dst_slot)
|
bool storage::move_slot(int src_slot, int dst_slot)
|
||||||
|
@ -954,7 +957,6 @@ ret:
|
||||||
bool r = true;
|
bool r = true;
|
||||||
|
|
||||||
// the size of the target slot is the size of the piece
|
// the size of the target slot is the size of the piece
|
||||||
int piece_size = m_files.piece_length();
|
|
||||||
int piece1_size = m_files.piece_size(slot2);
|
int piece1_size = m_files.piece_size(slot2);
|
||||||
int piece2_size = m_files.piece_size(slot1);
|
int piece2_size = m_files.piece_size(slot1);
|
||||||
|
|
||||||
|
@ -1098,7 +1100,8 @@ ret:
|
||||||
|
|
||||||
error_code ec;
|
error_code ec;
|
||||||
int mode = file::read_only;
|
int mode = file::read_only;
|
||||||
if (io_thread().no_buffer()
|
if (io_thread()
|
||||||
|
&& io_thread()->no_buffer()
|
||||||
&& ((file_iter->offset + file_iter->file_base) & (m_page_size-1)) == 0)
|
&& ((file_iter->offset + file_iter->file_base) & (m_page_size-1)) == 0)
|
||||||
mode |= file::no_buffer;
|
mode |= file::no_buffer;
|
||||||
in = m_pool.open_file(this, path, mode, ec);
|
in = m_pool.open_file(this, path, mode, ec);
|
||||||
|
@ -1241,7 +1244,8 @@ ret:
|
||||||
|
|
||||||
error_code ec;
|
error_code ec;
|
||||||
int mode = file::read_write;
|
int mode = file::read_write;
|
||||||
if (io_thread().no_buffer()
|
if (io_thread()
|
||||||
|
&& io_thread()->no_buffer()
|
||||||
&& ((file_iter->offset + file_iter->file_base) & (m_page_size-1)) == 0)
|
&& ((file_iter->offset + file_iter->file_base) & (m_page_size-1)) == 0)
|
||||||
mode |= file::no_buffer;
|
mode |= file::no_buffer;
|
||||||
out = m_pool.open_file(this, path, mode, ec);
|
out = m_pool.open_file(this, path, mode, ec);
|
||||||
|
|
|
@ -219,11 +219,7 @@ namespace
|
||||||
|
|
||||||
// bitcomet pad file
|
// bitcomet pad file
|
||||||
|
|
||||||
#if BOOST_VERSION < 103600
|
if (target.path.string().find("_____padding_file_") != std::string::npos)
|
||||||
if (target.path.leaf().substr(0, 18) == "_____padding_file_")
|
|
||||||
#else
|
|
||||||
if (target.path.filename().substr(0, 18) == "_____padding_file_")
|
|
||||||
#endif
|
|
||||||
target.pad_file = true;
|
target.pad_file = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue