make iovec_t an alias for span<char>, in preparation for removing it altogether in favour of span

This commit is contained in:
arvidn 2017-04-29 00:27:55 -04:00 committed by Arvid Norberg
parent a693565df0
commit 749d0da875
17 changed files with 191 additions and 191 deletions

View File

@ -63,6 +63,7 @@ using namespace lt::detail; // for write_* and read_*
using namespace std::placeholders; using namespace std::placeholders;
// TODO: this should take a span
void generate_block(std::uint32_t* buffer, piece_index_t const piece, int start, int length) void generate_block(std::uint32_t* buffer, piece_index_t const piece, int start, int length)
{ {
std::uint32_t fill = (static_cast<int>(piece) << 8) | ((start / 0x4000) & 0xff); std::uint32_t fill = (static_cast<int>(piece) << 8) | ((start / 0x4000) & 0xff);
@ -867,7 +868,8 @@ void generate_data(char const* path, torrent_info const& ti)
{ {
generate_block(piece, i, j, 0x4000); generate_block(piece, i, j, 0x4000);
int const left_in_piece = ti.piece_size(i) - j; int const left_in_piece = ti.piece_size(i) - j;
iovec_t const b = { piece, size_t(std::min(left_in_piece, 0x4000))}; iovec_t const b = { reinterpret_cast<char*>(piece)
, size_t(std::min(left_in_piece, 0x4000))};
storage_error error; storage_error error;
st->writev(b, i, j, 0, error); st->writev(b, i, j, 0, error);
if (error) if (error)

View File

@ -40,10 +40,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/units.hpp" #include "libtorrent/units.hpp"
#include "libtorrent/storage_defs.hpp" // for status_t #include "libtorrent/storage_defs.hpp" // for status_t
#ifndef TORRENT_WINDOWS
#include <sys/uio.h> // for iovec
#endif
namespace libtorrent { namespace libtorrent {
class file_storage; class file_storage;
@ -52,19 +48,14 @@ namespace libtorrent {
struct stat_cache; struct stat_cache;
struct add_torrent_params; struct add_torrent_params;
#ifdef TORRENT_WINDOWS // TODO: 3 remove this typedef, and use span<char const> for disk write
struct iovec_t // operations
{ using iovec_t = span<char>;
void* iov_base;
size_t iov_len;
};
#else
using iovec_t = ::iovec;
#endif
namespace aux { namespace aux {
TORRENT_EXTRA_EXPORT int copy_bufs(span<iovec_t const> bufs, int bytes, span<iovec_t> target); TORRENT_EXTRA_EXPORT int copy_bufs(span<iovec_t const> bufs
, int bytes, span<iovec_t> target);
TORRENT_EXTRA_EXPORT span<iovec_t> advance_bufs(span<iovec_t> bufs, int bytes); TORRENT_EXTRA_EXPORT span<iovec_t> advance_bufs(span<iovec_t> bufs, int bytes);
// this identifies a read or write operation so that readwritev() knows // this identifies a read or write operation so that readwritev() knows

View File

@ -214,9 +214,6 @@ namespace libtorrent {
static bool has_manage_volume_privs; static bool has_manage_volume_privs;
#endif #endif
}; };
TORRENT_EXTRA_EXPORT int bufs_size(span<iovec_t const> bufs);
} }
#endif // TORRENT_FILE_HPP_INCLUDED #endif // TORRENT_FILE_HPP_INCLUDED

View File

@ -1272,14 +1272,14 @@ void block_cache::insert_blocks(cached_piece_entry* pe, int block, span<iovec_t
for (auto const& buf : iov) for (auto const& buf : iov)
{ {
// each iovec buffer has to be the size of a block (or the size of the last block) // each iovec buffer has to be the size of a block (or the size of the last block)
TORRENT_PIECE_ASSERT(int(buf.iov_len) == std::min(block_size() TORRENT_PIECE_ASSERT(int(buf.size()) == std::min(block_size()
, pe->storage->files().piece_size(pe->piece) - block * block_size()), pe); , pe->storage->files().piece_size(pe->piece) - block * block_size()), pe);
// no nullptrs allowed // no nullptrs allowed
TORRENT_ASSERT(buf.iov_base != nullptr); TORRENT_ASSERT(buf.data() != nullptr);
#ifdef TORRENT_DEBUG_BUFFERS #ifdef TORRENT_DEBUG_BUFFERS
TORRENT_PIECE_ASSERT(is_disk_buffer(static_cast<char*>(buf.iov_base)), pe); TORRENT_PIECE_ASSERT(is_disk_buffer(buf.data()), pe);
#endif #endif
if (pe->blocks[block].buf && (flags & blocks_inc_refcount)) if (pe->blocks[block].buf && (flags & blocks_inc_refcount))
@ -1290,13 +1290,13 @@ void block_cache::insert_blocks(cached_piece_entry* pe, int block, span<iovec_t
// either free the block or insert it. Never replace a block // either free the block or insert it. Never replace a block
if (pe->blocks[block].buf) if (pe->blocks[block].buf)
{ {
free_buffer(static_cast<char*>(buf.iov_base)); free_buffer(buf.data());
} }
else else
{ {
pe->blocks[block].buf = static_cast<char*>(buf.iov_base); pe->blocks[block].buf = buf.data();
TORRENT_PIECE_ASSERT(buf.iov_base != nullptr, pe); TORRENT_PIECE_ASSERT(buf.data() != nullptr, pe);
TORRENT_PIECE_ASSERT(pe->blocks[block].dirty == false, pe); TORRENT_PIECE_ASSERT(pe->blocks[block].dirty == false, pe);
++pe->num_blocks; ++pe->num_blocks;
++m_read_cache_size; ++m_read_cache_size;

View File

@ -195,17 +195,16 @@ namespace libtorrent {
std::unique_lock<std::mutex> l(m_pool_mutex); std::unique_lock<std::mutex> l(m_pool_mutex);
for (auto& i : iov) for (auto& i : iov)
{ {
i.iov_base = allocate_buffer_impl(l, "pending read"); i = { allocate_buffer_impl(l, "pending read"), std::size_t(block_size())};
i.iov_len = std::size_t(block_size()); if (i.data() == nullptr)
if (i.iov_base == nullptr)
{ {
// uh oh. We failed to allocate the buffer! // uh oh. We failed to allocate the buffer!
// we need to roll back and free all the buffers // we need to roll back and free all the buffers
// we've already allocated // we've already allocated
for (auto j : iov) for (auto j : iov)
{ {
if (j.iov_base == nullptr) break; if (j.data() == nullptr) break;
char* buf = static_cast<char*>(j.iov_base); char* buf = j.data();
TORRENT_ASSERT(is_disk_buffer(buf, l)); TORRENT_ASSERT(is_disk_buffer(buf, l));
free_buffer_impl(buf, l); free_buffer_impl(buf, l);
remove_buffer_in_use(buf); remove_buffer_in_use(buf);
@ -222,7 +221,7 @@ namespace libtorrent {
std::unique_lock<std::mutex> l(m_pool_mutex); std::unique_lock<std::mutex> l(m_pool_mutex);
for (auto i : iov) for (auto i : iov)
{ {
char* buf = static_cast<char*>(i.iov_base); char* buf = i.data();
TORRENT_ASSERT(is_disk_buffer(buf, l)); TORRENT_ASSERT(is_disk_buffer(buf, l));
free_buffer_impl(buf, l); free_buffer_impl(buf, l);
remove_buffer_in_use(buf); remove_buffer_in_use(buf);

View File

@ -631,8 +631,7 @@ namespace libtorrent {
TORRENT_UNUSED(locked); TORRENT_UNUSED(locked);
flushing[num_flushing++] = i + block_base_index; flushing[num_flushing++] = i + block_base_index;
iov[iov_len].iov_base = pe->blocks[i].buf; iov[iov_len] = { pe->blocks[i].buf, aux::numeric_cast<std::size_t>(std::min(block_size, size_left)) };
iov[iov_len].iov_len = aux::numeric_cast<std::size_t>(std::min(block_size, size_left));
++iov_len; ++iov_len;
pe->blocks[i].pending = true; pe->blocks[i].pending = true;
@ -1302,9 +1301,10 @@ namespace libtorrent {
// if this is the last piece, adjust the size of the // if this is the last piece, adjust the size of the
// last buffer to match up // last buffer to match up
iov[iov_len - 1].iov_len = aux::numeric_cast<std::size_t>(std::min(int(piece_size - adjusted_offset) iov[iov_len - 1] = iov[iov_len - 1].first(aux::numeric_cast<std::size_t>(
- (iov_len - 1) * block_size, block_size)); std::min(int(piece_size - adjusted_offset)
TORRENT_ASSERT(iov[iov_len - 1].iov_len > 0); - (iov_len - 1) * block_size, block_size)));
TORRENT_ASSERT(iov[iov_len - 1].size() > 0);
// at this point, all the buffers are allocated and iov is initialized // at this point, all the buffers are allocated and iov is initialized
// and the blocks have their refcounters incremented, so no other thread // and the blocks have their refcounters incremented, so no other thread
@ -2162,8 +2162,7 @@ namespace libtorrent {
std::uint32_t const file_flags = file_flags_for_job(j std::uint32_t const file_flags = file_flags_for_job(j
, m_settings.get_bool(settings_pack::coalesce_reads)); , m_settings.get_bool(settings_pack::coalesce_reads));
iovec_t iov; iovec_t iov = { m_disk_cache.allocate_buffer("hashing"), 0x4000 };
iov.iov_base = m_disk_cache.allocate_buffer("hashing");
hasher h; hasher h;
int ret = 0; int ret = 0;
int offset = 0; int offset = 0;
@ -2174,10 +2173,11 @@ namespace libtorrent {
time_point const start_time = clock_type::now(); time_point const start_time = clock_type::now();
iov.iov_len = aux::numeric_cast<std::size_t>(std::min(block_size, piece_size - offset)); iov = iov.first(aux::numeric_cast<std::size_t>(std::min(block_size, piece_size - offset)));
ret = j->storage->readv(iov, j->piece ret = j->storage->readv(iov, j->piece
, offset, file_flags, j->error); , offset, file_flags, j->error);
if (ret < 0) break; if (ret < 0) break;
iov = iov.first(std::size_t(ret));
if (!j->error.ec) if (!j->error.ec)
{ {
@ -2191,10 +2191,10 @@ namespace libtorrent {
} }
offset += block_size; offset += block_size;
h.update(static_cast<char const*>(iov.iov_base), int(iov.iov_len)); h.update(iov);
} }
m_disk_cache.free_buffer(static_cast<char*>(iov.iov_base)); m_disk_cache.free_buffer(iov.data());
sha1_hash piece_hash = h.final(); sha1_hash piece_hash = h.final();
std::memcpy(j->d.piece_hash, piece_hash.data(), 20); std::memcpy(j->d.piece_hash, piece_hash.data(), 20);
@ -2326,23 +2326,22 @@ namespace libtorrent {
int next_locked_block = 0; int next_locked_block = 0;
for (int i = offset / block_size; i < blocks_in_piece; ++i) for (int i = offset / block_size; i < blocks_in_piece; ++i)
{ {
iovec_t iov;
iov.iov_len = aux::numeric_cast<std::size_t>(std::min(block_size, piece_size - offset));
if (next_locked_block < num_locked_blocks if (next_locked_block < num_locked_blocks
&& locked_blocks[next_locked_block] == i) && locked_blocks[next_locked_block] == i)
{ {
int const len = std::min(block_size, piece_size - offset);
++next_locked_block; ++next_locked_block;
TORRENT_PIECE_ASSERT(pe->blocks[i].buf, pe); TORRENT_PIECE_ASSERT(pe->blocks[i].buf, pe);
TORRENT_PIECE_ASSERT(offset == i * block_size, pe); TORRENT_PIECE_ASSERT(offset == i * block_size, pe);
offset += int(iov.iov_len); offset += len;
ph->h.update({pe->blocks[i].buf, iov.iov_len}); ph->h.update({pe->blocks[i].buf, aux::numeric_cast<std::size_t>(len)});
} }
else else
{ {
iov.iov_base = m_disk_cache.allocate_buffer("hashing"); iovec_t const iov = { m_disk_cache.allocate_buffer("hashing")
, aux::numeric_cast<std::size_t>(std::min(block_size, piece_size - offset))};
if (iov.iov_base == nullptr) if (iov.data() == nullptr)
{ {
l.lock(); l.lock();
@ -2374,19 +2373,19 @@ namespace libtorrent {
{ {
ret = status_t::fatal_disk_error; ret = status_t::fatal_disk_error;
TORRENT_ASSERT(j->error.ec && j->error.operation != 0); TORRENT_ASSERT(j->error.ec && j->error.operation != 0);
m_disk_cache.free_buffer(static_cast<char*>(iov.iov_base)); m_disk_cache.free_buffer(iov.data());
break; break;
} }
// treat a short read as an error. The hash will be invalid, the // treat a short read as an error. The hash will be invalid, the
// block cannot be cached and the main thread should skip the rest // block cannot be cached and the main thread should skip the rest
// of this file // of this file
if (read_ret != int(iov.iov_len)) if (read_ret != int(iov.size()))
{ {
ret = status_t::fatal_disk_error; ret = status_t::fatal_disk_error;
j->error.ec = boost::asio::error::eof; j->error.ec = boost::asio::error::eof;
j->error.operation = storage_error::read; j->error.operation = storage_error::read;
m_disk_cache.free_buffer(static_cast<char*>(iov.iov_base)); m_disk_cache.free_buffer(iov.data());
break; break;
} }
@ -2403,8 +2402,8 @@ namespace libtorrent {
} }
TORRENT_PIECE_ASSERT(offset == i * block_size, pe); TORRENT_PIECE_ASSERT(offset == i * block_size, pe);
offset += int(iov.iov_len); offset += int(iov.size());
ph->h.update({static_cast<char const*>(iov.iov_base), iov.iov_len}); ph->h.update(iov);
l.lock(); l.lock();
m_disk_cache.insert_blocks(pe, i, iov, j); m_disk_cache.insert_blocks(pe, i, iov, j);

View File

@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "libtorrent/config.hpp"
#include "libtorrent/aux_/disable_warnings_push.hpp" #include "libtorrent/aux_/disable_warnings_push.hpp"
#ifdef __GNUC__ #ifdef __GNUC__
@ -49,6 +50,18 @@ POSSIBILITY OF SUCH DAMAGE.
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#define _LARGE_FILES 1 #define _LARGE_FILES 1
#ifndef TORRENT_WINDOWS
#include <sys/uio.h> // for iovec
#else
namespace {
struct iovec
{
void* iov_base;
std::size_t iov_len;
};
} // anonymous namespace
#endif
// on mingw this is necessary to enable 64-bit time_t, specifically used for // on mingw this is necessary to enable 64-bit time_t, specifically used for
// the stat struct. Without this, modification times returned by stat may be // the stat struct. Without this, modification times returned by stat may be
// incorrect and consistently fail resume data // incorrect and consistently fail resume data
@ -66,7 +79,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/disable_warnings_pop.hpp" #include "libtorrent/aux_/disable_warnings_pop.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/aux_/alloca.hpp" #include "libtorrent/aux_/alloca.hpp"
#include "libtorrent/file.hpp" #include "libtorrent/file.hpp"
#include "libtorrent/aux_/path.hpp" #include "libtorrent/aux_/path.hpp"
@ -165,7 +177,7 @@ namespace {
return WAIT_FAILED; return WAIT_FAILED;
} }
int preadv(HANDLE fd, libtorrent::iovec_t const* bufs, int num_bufs, std::int64_t file_offset) int preadv(HANDLE fd, ::iovec const* bufs, int num_bufs, std::int64_t file_offset)
{ {
TORRENT_ALLOCA(ol, OVERLAPPED, num_bufs); TORRENT_ALLOCA(ol, OVERLAPPED, num_bufs);
std::memset(ol.data(), 0, sizeof(OVERLAPPED) * num_bufs); std::memset(ol.data(), 0, sizeof(OVERLAPPED) * num_bufs);
@ -235,7 +247,7 @@ done:
return ret; return ret;
} }
int pwritev(HANDLE fd, libtorrent::iovec_t const* bufs, int num_bufs, std::int64_t file_offset) int pwritev(HANDLE fd, ::iovec const* bufs, int num_bufs, std::int64_t file_offset)
{ {
TORRENT_ALLOCA(ol, OVERLAPPED, num_bufs); TORRENT_ALLOCA(ol, OVERLAPPED, num_bufs);
std::memset(ol.data(), 0, sizeof(OVERLAPPED) * num_bufs); std::memset(ol.data(), 0, sizeof(OVERLAPPED) * num_bufs);
@ -330,12 +342,6 @@ static_assert((libtorrent::file::sparse & libtorrent::file::attribute_mask) == 0
namespace libtorrent { namespace libtorrent {
template <typename T>
std::unique_ptr<T, decltype(&std::free)> make_free_holder(T* ptr)
{
return std::unique_ptr<T, decltype(&std::free)>(ptr, &std::free);
}
directory::directory(std::string const& path, error_code& ec) directory::directory(std::string const& path, error_code& ec)
: m_done(false) : m_done(false)
{ {
@ -796,8 +802,8 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
std::size_t offset = 0; std::size_t offset = 0;
for (auto buf : bufs) for (auto buf : bufs)
{ {
std::memcpy(dst + offset, buf.iov_base, buf.iov_len); std::memcpy(dst + offset, buf.data(), buf.size());
offset += buf.iov_len; offset += buf.size();
} }
} }
@ -806,8 +812,8 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
std::size_t offset = 0; std::size_t offset = 0;
for (auto buf : bufs) for (auto buf : bufs)
{ {
std::memcpy(buf.iov_base, src + offset, buf.iov_len); std::memcpy(buf.data(), src + offset, buf.size());
offset += buf.iov_len; offset += buf.size();
} }
} }
@ -815,10 +821,9 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
, iovec_t& tmp) , iovec_t& tmp)
{ {
std::size_t const buf_size = aux::numeric_cast<std::size_t>(bufs_size(bufs)); std::size_t const buf_size = aux::numeric_cast<std::size_t>(bufs_size(bufs));
char* buf = static_cast<char*>(std::malloc(buf_size)); char* buf = new char[buf_size];
if (!buf) return false; if (!buf) return false;
tmp.iov_base = buf; tmp = { buf, buf_size };
tmp.iov_len = buf_size;
bufs = span<iovec_t const>(tmp); bufs = span<iovec_t const>(tmp);
return true; return true;
} }
@ -827,21 +832,30 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
, char* const buf, bool const copy) , char* const buf, bool const copy)
{ {
if (copy) scatter_copy(bufs, buf); if (copy) scatter_copy(bufs, buf);
std::free(buf); delete[] buf;
} }
bool coalesce_write_buffers(span<iovec_t const>& bufs bool coalesce_write_buffers(span<iovec_t const>& bufs
, iovec_t& tmp) , iovec_t& tmp)
{ {
std::size_t const buf_size = aux::numeric_cast<std::size_t>(bufs_size(bufs)); std::size_t const buf_size = aux::numeric_cast<std::size_t>(bufs_size(bufs));
char* buf = static_cast<char*>(std::malloc(buf_size)); char* buf = new char[buf_size];
if (!buf) return false; if (!buf) return false;
gather_copy(bufs, buf); gather_copy(bufs, buf);
tmp.iov_base = buf; tmp = { buf, buf_size };
tmp.iov_len = buf_size;
bufs = span<iovec_t const>(tmp); bufs = span<iovec_t const>(tmp);
return true; return true;
} }
#else
namespace {
int bufs_size(span<::iovec> bufs)
{
std::size_t size = 0;
for (auto buf : bufs) size += buf.iov_len;
return int(size);
}
}
#endif // TORRENT_USE_PREADV #endif // TORRENT_USE_PREADV
template <class Fun> template <class Fun>
@ -850,13 +864,22 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
{ {
#if TORRENT_USE_PREADV #if TORRENT_USE_PREADV
TORRENT_ALLOCA(vec, ::iovec, bufs.size());
auto it = vec.begin();
for (auto const& b : bufs)
{
it->iov_base = b.data();
it->iov_len = b.size();
++it;
}
int ret = 0; int ret = 0;
while (!bufs.empty()) while (!vec.empty())
{ {
#ifdef IOV_MAX #ifdef IOV_MAX
auto const nbufs = bufs.first((std::min)(int(bufs.size()), IOV_MAX)); auto const nbufs = vec.first(std::min(int(vec.size()), IOV_MAX));
#else #else
auto const nbufs = bufs; auto const nbufs = vec;
#endif #endif
int tmp_ret = 0; int tmp_ret = 0;
@ -880,7 +903,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
const int expected_len = bufs_size(nbufs); const int expected_len = bufs_size(nbufs);
if (tmp_ret < expected_len) break; if (tmp_ret < expected_len) break;
bufs = bufs.subspan(nbufs.size()); vec = vec.subspan(nbufs.size());
} }
return ret; return ret;
@ -889,7 +912,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
std::int64_t ret = 0; std::int64_t ret = 0;
for (auto i : bufs) for (auto i : bufs)
{ {
std::int64_t const tmp_ret = f(fd, i.iov_base, i.iov_len, file_offset); std::int64_t const tmp_ret = f(fd, i.data(), i.size(), file_offset);
if (tmp_ret < 0) if (tmp_ret < 0)
{ {
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
@ -901,7 +924,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
} }
file_offset += tmp_ret; file_offset += tmp_ret;
ret += tmp_ret; ret += tmp_ret;
if (tmp_ret < int(i.iov_len)) break; if (tmp_ret < int(i.size())) break;
} }
return ret; return ret;
@ -926,7 +949,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
for (auto i : bufs) for (auto i : bufs)
{ {
int tmp_ret = f(fd, i.iov_base, i.iov_len); int tmp_ret = f(fd, i.data(), i.size());
if (tmp_ret < 0) if (tmp_ret < 0)
{ {
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
@ -938,7 +961,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
} }
file_offset += tmp_ret; file_offset += tmp_ret;
ret += tmp_ret; ret += tmp_ret;
if (tmp_ret < int(i.iov_len)) break; if (tmp_ret < int(i.size())) break;
} }
return ret; return ret;
@ -968,7 +991,6 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
#if TORRENT_USE_PREADV #if TORRENT_USE_PREADV
TORRENT_UNUSED(flags); TORRENT_UNUSED(flags);
std::int64_t ret = iov(&::preadv, native_handle(), file_offset, bufs, ec); std::int64_t ret = iov(&::preadv, native_handle(), file_offset, bufs, ec);
#else #else
@ -995,7 +1017,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
if ((flags & file::coalesce_buffers)) if ((flags & file::coalesce_buffers))
coalesce_read_buffers_end(bufs coalesce_read_buffers_end(bufs
, static_cast<char*>(tmp.iov_base), !ec); , tmp.data(), !ec);
#endif #endif
return ret; return ret;
@ -1049,7 +1071,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
#endif #endif
if (flags & file::coalesce_buffers) if (flags & file::coalesce_buffers)
std::free(tmp.iov_base); delete[] tmp.data();
#endif #endif
#if TORRENT_USE_FDATASYNC \ #if TORRENT_USE_FDATASYNC \

View File

@ -96,8 +96,8 @@ namespace libtorrent {
if (ec) return; if (ec) return;
// parse header // parse header
std::unique_ptr<std::uint32_t[]> header(new std::uint32_t[m_header_size]); std::vector<char> header(static_cast<std::size_t>(m_header_size));
iovec_t b = {header.get(), std::size_t(m_header_size)}; iovec_t b = header;
int n = int(m_file.readv(0, b, ec)); int n = int(m_file.readv(0, b, ec));
if (ec) return; if (ec) return;
@ -105,7 +105,7 @@ namespace libtorrent {
if (n < m_header_size) return; if (n < m_header_size) return;
using namespace libtorrent::detail; using namespace libtorrent::detail;
char* ptr = reinterpret_cast<char*>(header.get()); char* ptr = header.data();
// we have a header. Parse it // we have a header. Parse it
int const num_pieces_ = int(read_uint32(ptr)); int const num_pieces_ = int(read_uint32(ptr));
int const piece_size_ = int(read_uint32(ptr)); int const piece_size_ = int(read_uint32(ptr));
@ -313,9 +313,10 @@ namespace libtorrent {
l.unlock(); l.unlock();
iovec_t v = {buf.get(), std::size_t(block_to_copy)}; iovec_t v = {buf.get(), std::size_t(block_to_copy)};
v.iov_len = std::size_t(m_file.readv(slot_offset + piece_offset, v, ec)); auto bytes_read = std::size_t(m_file.readv(slot_offset + piece_offset, v, ec));
v = v.first(bytes_read);
TORRENT_ASSERT(!ec); TORRENT_ASSERT(!ec);
if (ec || v.iov_len == 0) return; if (ec || v.size() == 0) return;
f(file_offset, {buf.get(), std::size_t(block_to_copy)}); f(file_offset, {buf.get(), std::size_t(block_to_copy)});
@ -377,12 +378,11 @@ namespace libtorrent {
open_file(file::read_write, ec); open_file(file::read_write, ec);
if (ec) return; if (ec) return;
std::unique_ptr<std::uint32_t[]> header(new std::uint32_t[m_header_size]); std::vector<char> header(static_cast<std::size_t>(m_header_size));
using namespace libtorrent::detail; using namespace libtorrent::detail;
char* ptr = reinterpret_cast<char*>(header.get()); char* ptr = header.data();
write_uint32(m_max_pieces, ptr); write_uint32(m_max_pieces, ptr);
write_uint32(m_piece_size, ptr); write_uint32(m_piece_size, ptr);
@ -393,9 +393,8 @@ namespace libtorrent {
? slot_index_t(-1) : i->second); ? slot_index_t(-1) : i->second);
write_int32(static_cast<int>(slot), ptr); write_int32(static_cast<int>(slot), ptr);
} }
std::memset(ptr, 0, std::size_t(m_header_size - (ptr - reinterpret_cast<char*>(header.get())))); std::memset(ptr, 0, std::size_t(m_header_size - (ptr - header.data())));
iovec_t b = header;
iovec_t b = {header.get(), std::size_t(m_header_size)};
m_file.writev(0, b, ec); m_file.writev(0, b, ec);
} }
} }

View File

@ -130,8 +130,7 @@ namespace libtorrent {
int bufs_size(span<iovec_t const> bufs) int bufs_size(span<iovec_t const> bufs)
{ {
std::size_t size = 0; std::size_t size = 0;
for (auto buf : bufs) for (auto buf : bufs) size += buf.size();
size += buf.iov_len;
return int(size); return int(size);
} }

View File

@ -80,7 +80,7 @@ namespace libtorrent {
void clear_bufs(span<iovec_t const> bufs) void clear_bufs(span<iovec_t const> bufs)
{ {
for (auto buf : bufs) for (auto buf : bufs)
std::memset(buf.iov_base, 0, buf.iov_len); std::memset(buf.data(), 0, buf.size());
} }
struct write_fileop final : aux::fileop struct write_fileop final : aux::fileop
@ -303,7 +303,7 @@ namespace libtorrent {
iovec_t const v = {buf.data(), buf.size()}; iovec_t const v = {buf.data(), buf.size()};
std::int64_t const ret = f->writev(file_offset, v, ec.ec); std::int64_t const ret = f->writev(file_offset, v, ec.ec);
TORRENT_UNUSED(ret); TORRENT_UNUSED(ret);
TORRENT_ASSERT(ec || ret == std::int64_t(v.iov_len)); TORRENT_ASSERT(ec || ret == std::int64_t(v.size()));
}, fs.file_offset(i), fs.file_size(i), ec.ec); }, fs.file_offset(i), fs.file_size(i), ec.ec);
if (ec) if (ec)
@ -817,8 +817,8 @@ namespace {
int ret = 0; int ret = 0;
for (auto const& b : bufs) for (auto const& b : bufs)
{ {
std::memset(b.iov_base, 0, b.iov_len); std::memset(b.data(), 0, b.size());
ret += int(b.iov_len); ret += int(b.size());
} }
return 0; return 0;
} }
@ -827,7 +827,7 @@ namespace {
{ {
int ret = 0; int ret = 0;
for (auto const& b : bufs) for (auto const& b : bufs)
ret += int(b.iov_len); ret += int(b.size());
return 0; return 0;
} }

View File

@ -44,34 +44,35 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent { namespace aux { namespace libtorrent { namespace aux {
int copy_bufs(span<iovec_t const> bufs, int const bytes, span<iovec_t> target) int copy_bufs(span<iovec_t const> bufs, int bytes
, span<iovec_t> target)
{ {
int size = 0; TORRENT_ASSERT(bytes >= 0);
for (int i = 0;; i++) auto dst = target.begin();
int ret = 0;
if (bytes == 0) return ret;
for (iovec_t const& src : bufs)
{ {
std::size_t const idx = std::size_t(i); std::size_t const to_copy = std::min(src.size(), std::size_t(bytes));
target[idx] = bufs[idx]; *dst = src.first(to_copy);
size += int(bufs[idx].iov_len); bytes -= int(to_copy);
if (size >= bytes) ++ret;
{ ++dst;
TORRENT_ASSERT(target[idx].iov_len >= aux::numeric_cast<std::size_t>(size - bytes)); if (bytes <= 0) return ret;
target[idx].iov_len -= aux::numeric_cast<std::size_t>(size - bytes);
return i + 1;
}
} }
return ret;
} }
span<iovec_t> advance_bufs(span<iovec_t> bufs, int const bytes) span<iovec_t> advance_bufs(span<iovec_t> bufs, int const bytes)
{ {
int size = 0; TORRENT_ASSERT(bytes >= 0);
std::size_t size = 0;
for (;;) for (;;)
{ {
size += int(bufs.front().iov_len); size += bufs.front().size();
if (size >= bytes) if (size >= std::size_t(bytes))
{ {
bufs.front().iov_base = reinterpret_cast<char*>(bufs.front().iov_base) bufs.front() = bufs.front().last(size - std::size_t(bytes));
+ bufs.front().iov_len - (size - bytes);
bufs.front().iov_len = aux::numeric_cast<std::size_t>(size - bytes);
return bufs; return bufs;
} }
bufs = bufs.subspan(1); bufs = bufs.subspan(1);
@ -83,14 +84,16 @@ namespace libtorrent { namespace aux {
int count_bufs(span<iovec_t const> bufs, int bytes) int count_bufs(span<iovec_t const> bufs, int bytes)
{ {
int size = 0; std::size_t size = 0;
int count = 1; int count = 0;
if (bytes == 0) return 0; if (bytes == 0) return count;
for (auto i = bufs.begin();; ++i, ++count) for (auto b : bufs)
{ {
size += int(i->iov_len); ++count;
if (size >= bytes) return count; size += b.size();
if (size >= std::size_t(bytes)) return count;
} }
return count;
} }
} }

View File

@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/disk_io_thread.hpp" #include "libtorrent/disk_io_thread.hpp"
#include "libtorrent/storage.hpp" #include "libtorrent/storage.hpp"
#include "libtorrent/session.hpp" #include "libtorrent/session.hpp"
#include "libtorrent/aux_/path.hpp" // for bufs_size
#include <functional> #include <functional>
#include <memory> #include <memory>

View File

@ -291,14 +291,14 @@ TORRENT_TEST(file)
std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
TEST_EQUAL(ec, error_code()); TEST_EQUAL(ec, error_code());
if (ec) std::printf("%s\n", ec.message().c_str()); if (ec) std::printf("%s\n", ec.message().c_str());
iovec_t b = {(void*)"test", 4}; char test[] = "test";
iovec_t b = {test, 4};
TEST_EQUAL(f.writev(0, b, ec), 4); TEST_EQUAL(f.writev(0, b, ec), 4);
if (ec) if (ec)
std::printf("writev failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); std::printf("writev failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
TEST_CHECK(!ec); TEST_CHECK(!ec);
char test_buf[5] = {0}; char test_buf[5] = {0};
b.iov_base = test_buf; b = { test_buf, 4 };
b.iov_len = 4;
TEST_EQUAL(f.readv(0, b, ec), 4); TEST_EQUAL(f.readv(0, b, ec), 4);
if (ec) if (ec)
std::printf("readv failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); std::printf("readv failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
@ -321,7 +321,8 @@ TORRENT_TEST(hard_link)
std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
TEST_EQUAL(ec, error_code()); TEST_EQUAL(ec, error_code());
iovec_t b = {(void*)"abcdefghijklmnopqrstuvwxyz", 26}; char str[] = "abcdefghijklmnopqrstuvwxyz";
iovec_t b = { str, 26 };
TEST_EQUAL(f.writev(0, b, ec), 26); TEST_EQUAL(f.writev(0, b, ec), 26);
if (ec) if (ec)
std::printf("writev failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); std::printf("writev failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
@ -340,9 +341,8 @@ TORRENT_TEST(hard_link)
std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
TEST_EQUAL(ec, error_code()); TEST_EQUAL(ec, error_code());
char test_buf[27] = {0}; char test_buf[27] = {};
b.iov_base = test_buf; b = { test_buf, 27 };
b.iov_len = 27;
TEST_EQUAL(f.readv(0, b, ec), 26); TEST_EQUAL(f.readv(0, b, ec), 26);
if (ec) if (ec)
std::printf("readv failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); std::printf("readv failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
@ -368,18 +368,18 @@ TORRENT_TEST(coalesce_buffer)
std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
TEST_EQUAL(ec, error_code()); TEST_EQUAL(ec, error_code());
if (ec) std::printf("%s\n", ec.message().c_str()); if (ec) std::printf("%s\n", ec.message().c_str());
iovec_t b[2] = {{(void*)"test", 4}, {(void*)"foobar", 6}}; char test[] = "test";
TEST_EQUAL(f.writev(0, {b, 2}, ec, file::coalesce_buffers), 4 + 6); char foobar[] = "foobar";
iovec_t b[2] = {{test, 4}, {foobar, 6}};
TEST_EQUAL(f.writev(0, b, ec, file::coalesce_buffers), 4 + 6);
if (ec) if (ec)
std::printf("writev failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); std::printf("writev failed: [%s] %s\n", ec.category().name(), ec.message().c_str());
TEST_CHECK(!ec); TEST_CHECK(!ec);
char test_buf1[5] = {0}; char test_buf1[5] = {0};
char test_buf2[7] = {0}; char test_buf2[7] = {0};
b[0].iov_base = test_buf1; b[0] = { test_buf1, 4 };
b[0].iov_len = 4; b[1] = { test_buf2, 6 };
b[1].iov_base = test_buf2; TEST_EQUAL(f.readv(0, b, ec), 4 + 6);
b[1].iov_len = 6;
TEST_EQUAL(f.readv(0, {b, 2}, ec), 4 + 6);
if (ec) if (ec)
{ {
std::printf("readv failed: [%s] %s\n" std::printf("readv failed: [%s] %s\n"

View File

@ -69,7 +69,7 @@ TORRENT_TEST(part_file)
// write something to the metadata file // write something to the metadata file
for (int i = 0; i < 1024; ++i) buf[i] = i; for (int i = 0; i < 1024; ++i) buf[i] = i;
iovec_t v = {&buf, 1024}; iovec_t v = buf;
pf.writev(v, piece_index_t(10), 0, ec); pf.writev(v, piece_index_t(10), 0, ec);
if (ec) std::printf("part_file::writev: %s\n", ec.message().c_str()); if (ec) std::printf("part_file::writev: %s\n", ec.message().c_str());
@ -101,12 +101,12 @@ TORRENT_TEST(part_file)
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
iovec_t v = {&buf, 1024}; iovec_t v = buf;
pf.readv(v, piece_index_t(10), 0, ec); pf.readv(v, piece_index_t(10), 0, ec);
if (ec) std::printf("part_file::readv: %s\n", ec.message().c_str()); if (ec) std::printf("part_file::readv: %s\n", ec.message().c_str());
for (int i = 0; i < 1024; ++i) for (int i = 0; i < 1024; ++i)
TEST_CHECK(buf[i] == char(i)); TEST_CHECK(buf[i] == static_cast<char>(i));
// test exporting the piece to a file // test exporting the piece to a file

View File

@ -44,7 +44,6 @@ using namespace lt;
TORRENT_TEST(primitives) TORRENT_TEST(primitives)
{ {
using namespace lt;
error_code ec; error_code ec;
// make sure the retry interval keeps growing // make sure the retry interval keeps growing

View File

@ -55,8 +55,8 @@ POSSIBILITY OF SUCH DAMAGE.
using namespace std::placeholders; using namespace std::placeholders;
using namespace lt; using namespace lt;
const int piece_size = 16 * 1024 * 16; std::size_t const piece_size = 16 * 1024 * 16;
const int half = piece_size / 2; std::size_t const half = piece_size / 2;
void signal_bool(bool* b, char const* string) void signal_bool(bool* b, char const* string)
{ {
@ -178,7 +178,7 @@ std::shared_ptr<default_storage> setup_torrent(file_storage& fs
return s; return s;
} }
std::vector<char> new_piece(int size) std::vector<char> new_piece(std::size_t const size)
{ {
std::vector<char> ret(size); std::vector<char> ret(size);
std::generate(ret.begin(), ret.end(), random_byte); std::generate(ret.begin(), ret.end(), random_byte);
@ -245,54 +245,46 @@ void run_storage_tests(std::shared_ptr<torrent_info> info
ret = s->writev(iov, piece_index_t(0), 0, 0, ec); ret = s->writev(iov, piece_index_t(0), 0, 0, ec);
if (ret != half) print_error("writev", ret, ec); if (ret != half) print_error("writev", ret, ec);
iov.iov_base = piece1.data() + half; iov = { piece1.data() + half, half };
iov.iov_len = half;
ret = s->writev(iov, piece_index_t(0), half, 0, ec); ret = s->writev(iov, piece_index_t(0), half, 0, ec);
if (ret != half) print_error("writev", ret, ec); if (ret != half) print_error("writev", ret, ec);
// test unaligned read (where the bytes are aligned) // test unaligned read (where the bytes are aligned)
iov.iov_base = piece + 3; iov = { piece + 3, piece_size - 9};
iov.iov_len = piece_size - 9;
ret = s->readv(iov, piece_index_t(0), 3, 0, ec); ret = s->readv(iov, piece_index_t(0), 3, 0, ec);
if (ret != piece_size - 9) print_error("readv",ret, ec); if (ret != piece_size - 9) print_error("readv",ret, ec);
TEST_CHECK(std::equal(piece+3, piece + piece_size-9, piece1.data()+3)); TEST_CHECK(std::equal(piece+3, piece + piece_size-9, piece1.data()+3));
// test unaligned read (where the bytes are not aligned) // test unaligned read (where the bytes are not aligned)
iov.iov_base = piece; iov = { piece, piece_size - 9};
iov.iov_len = piece_size - 9;
ret = s->readv(iov, piece_index_t(0), 3, 0, ec); ret = s->readv(iov, piece_index_t(0), 3, 0, ec);
TEST_CHECK(ret == piece_size - 9); TEST_CHECK(ret == piece_size - 9);
if (ret != piece_size - 9) print_error("readv", ret, ec); if (ret != piece_size - 9) print_error("readv", ret, ec);
TEST_CHECK(std::equal(piece, piece + piece_size-9, piece1.data()+3)); TEST_CHECK(std::equal(piece, piece + piece_size-9, piece1.data()+3));
// verify piece 1 // verify piece 1
iov.iov_base = piece; iov = { piece, piece_size };
iov.iov_len = piece_size;
ret = s->readv(iov, piece_index_t(0), 0, 0, ec); ret = s->readv(iov, piece_index_t(0), 0, 0, ec);
TEST_CHECK(ret == piece_size); TEST_CHECK(ret == piece_size);
if (ret != piece_size) print_error("readv", ret, ec); if (ret != piece_size) print_error("readv", ret, ec);
TEST_CHECK(std::equal(piece, piece + piece_size, piece1.data())); TEST_CHECK(std::equal(piece, piece + piece_size, piece1.data()));
// do the same with piece 0 and 2 (in slot 1 and 2) // do the same with piece 0 and 2 (in slot 1 and 2)
iov.iov_base = piece0.data(); iov = { piece0.data(), piece_size };
iov.iov_len = piece_size;
ret = s->writev(iov, piece_index_t(1), 0, 0, ec); ret = s->writev(iov, piece_index_t(1), 0, 0, ec);
if (ret != piece_size) print_error("writev", ret, ec); if (ret != piece_size) print_error("writev", ret, ec);
iov.iov_base = piece2.data(); iov = { piece2.data(), piece_size };
iov.iov_len = piece_size;
ret = s->writev(iov, piece_index_t(2), 0, 0, ec); ret = s->writev(iov, piece_index_t(2), 0, 0, ec);
if (ret != piece_size) print_error("writev", ret, ec); if (ret != piece_size) print_error("writev", ret, ec);
// verify piece 0 and 2 // verify piece 0 and 2
iov.iov_base = piece; iov = { piece, piece_size };
iov.iov_len = piece_size;
ret = s->readv(iov, piece_index_t(1), 0, 0, ec); ret = s->readv(iov, piece_index_t(1), 0, 0, ec);
if (ret != piece_size) print_error("readv", ret, ec); if (ret != piece_size) print_error("readv", ret, ec);
TEST_CHECK(std::equal(piece, piece + piece_size, piece0.data())); TEST_CHECK(std::equal(piece, piece + piece_size, piece0.data()));
iov.iov_base = piece; iov = { piece, piece_size };
iov.iov_len = piece_size;
ret = s->readv(iov, piece_index_t(2), 0, 0, ec); ret = s->readv(iov, piece_index_t(2), 0, 0, ec);
if (ret != piece_size) print_error("readv", ret, ec); if (ret != piece_size) print_error("readv", ret, ec);
TEST_CHECK(std::equal(piece, piece + piece_size, piece2.data())); TEST_CHECK(std::equal(piece, piece + piece_size, piece2.data()));
@ -558,8 +550,8 @@ void run_test(bool unbuffered)
TEST_EQUAL(file_size(combine_path(base, "test6.tmp")), 841); TEST_EQUAL(file_size(combine_path(base, "test6.tmp")), 841);
std::printf("file: %d expected: %d last_file_size: %d, piece_size: %d\n" std::printf("file: %d expected: %d last_file_size: %d, piece_size: %d\n"
, int(file_size(combine_path(base, "test7.tmp"))) , int(file_size(combine_path(base, "test7.tmp")))
, int(last_file_size - piece_size), last_file_size, piece_size); , int(last_file_size - piece_size), last_file_size, int(piece_size));
TEST_EQUAL(file_size(combine_path(base, "test7.tmp")), last_file_size - piece_size); TEST_EQUAL(file_size(combine_path(base, "test7.tmp")), last_file_size - int(piece_size));
remove_all(combine_path(test_path, "temp_storage"), ec); remove_all(combine_path(test_path, "temp_storage"), ec);
if (ec && ec != boost::system::errc::no_such_file_or_directory) if (ec && ec != boost::system::errc::no_such_file_or_directory)
std::cout << "remove_all '" << combine_path(test_path, "temp_storage") std::cout << "remove_all '" << combine_path(test_path, "temp_storage")
@ -931,20 +923,20 @@ void alloc_iov(iovec_t* iov, int num_bufs)
{ {
for (int i = 0; i < num_bufs; ++i) for (int i = 0; i < num_bufs; ++i)
{ {
iov[i].iov_base = malloc(num_bufs * (i + 1)); iov[i] = { new char[num_bufs * (i + 1)]
iov[i].iov_len = num_bufs * (i + 1); , static_cast<std::size_t>(num_bufs * (i + 1)) };
} }
} }
// TODO: this should take a span of iovec_ts
void fill_pattern(iovec_t* iov, int num_bufs) void fill_pattern(iovec_t* iov, int num_bufs)
{ {
int counter = 0; int counter = 0;
for (int i = 0; i < num_bufs; ++i) for (int i = 0; i < num_bufs; ++i)
{ {
unsigned char* buf = (unsigned char*)iov[i].iov_base; for (char& v : iov[i])
for (int k = 0; k < int(iov[i].iov_len); ++k)
{ {
buf[k] = counter & 0xff; v = counter & 0xff;
++counter; ++counter;
} }
} }
@ -961,22 +953,22 @@ bool check_pattern(std::vector<char> const& buf, int counter)
return true; return true;
} }
// TODO: this should take a span
void fill_pattern2(iovec_t* iov, int num_bufs) void fill_pattern2(iovec_t* iov, int num_bufs)
{ {
for (int i = 0; i < num_bufs; ++i) for (int i = 0; i < num_bufs; ++i)
{ {
unsigned char* buf = (unsigned char*)iov[i].iov_base; memset(iov[i].data(), 0xfe, iov[i].size());
memset(buf, 0xfe, int(iov[i].iov_len));
} }
} }
// TODO: this should take a span
void free_iov(iovec_t* iov, int num_bufs) void free_iov(iovec_t* iov, int num_bufs)
{ {
for (int i = 0; i < num_bufs; ++i) for (int i = 0; i < num_bufs; ++i)
{ {
free(iov[i].iov_base); delete[] iov[i].data();
iov[i].iov_len = 0; iov[i] = { nullptr, 0 };
iov[i].iov_base = nullptr;
} }
} }
@ -999,10 +991,9 @@ TORRENT_TEST(iovec_copy_bufs)
int counter = 0; int counter = 0;
for (int i = 0; i < num_bufs; ++i) for (int i = 0; i < num_bufs; ++i)
{ {
unsigned char* buf = (unsigned char*)iov2[i].iov_base; for (char v : iov2[i])
for (int k = 0; k < int(iov2[i].iov_len); ++k)
{ {
TEST_EQUAL(int(buf[k]), (counter & 0xff)); TEST_EQUAL(int(v), (counter & 0xff));
++counter; ++counter;
} }
} }
@ -1020,10 +1011,9 @@ TORRENT_TEST(iovec_clear_bufs)
clear_bufs({iov, 10}); clear_bufs({iov, 10});
for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
{ {
unsigned char* buf = (unsigned char*)iov[i].iov_base; for (char v : iov[i])
for (int k = 0; k < int(iov[i].iov_len); ++k)
{ {
TEST_EQUAL(int(buf[k]), 0); TEST_EQUAL(int(v), 0);
} }
} }
free_iov(iov, 10); free_iov(iov, 10);
@ -1064,10 +1054,9 @@ TORRENT_TEST(iovec_advance_bufs)
int counter = 13; int counter = 13;
for (auto buf : iov) for (auto buf : iov)
{ {
unsigned char* buf_base = (unsigned char*)buf.iov_base; for (char v : buf)
for (int k = 0; k < int(buf.iov_len); ++k)
{ {
TEST_EQUAL(int(buf_base[k]), (counter & 0xff)); TEST_EQUAL(v, static_cast<char>(counter));
++counter; ++counter;
} }
} }
@ -1115,8 +1104,8 @@ struct test_fileop : aux::fileop
int left = write_size; int left = write_size;
while (left > 0) while (left > 0)
{ {
const int copy_size = (std::min)(left, int(bufs.front().iov_len)); const int copy_size = std::min(left, int(bufs.front().size()));
memcpy(&file[offset], bufs.front().iov_base, copy_size); memcpy(&file[offset], bufs.front().data(), copy_size);
bufs = bufs.subspan(1); bufs = bufs.subspan(1);
offset += copy_size; offset += copy_size;
left -= copy_size; left -= copy_size;
@ -1140,11 +1129,11 @@ struct test_read_fileop : aux::fileop
const int read = local_size; const int read = local_size;
while (local_size > 0) while (local_size > 0)
{ {
unsigned char* p = (unsigned char*)bufs.front().iov_base; int const len = std::min(int(bufs.front().size()), local_size);
const int len = (std::min)(int(bufs.front().iov_len), local_size); auto local_buf = bufs.front().first(len);
for (int i = 0; i < len; ++i) for (char& v : local_buf)
{ {
p[i] = m_counter & 0xff; v = m_counter & 0xff;
++m_counter; ++m_counter;
} }
local_size -= len; local_size -= len;
@ -1188,7 +1177,7 @@ int count_bufs(iovec_t const* bufs, int bytes)
if (bytes == 0) return 0; if (bytes == 0) return 0;
for (iovec_t const* i = bufs;; ++i, ++count) for (iovec_t const* i = bufs;; ++i, ++count)
{ {
size += int(i->iov_len); size += int(i->size());
if (size >= bytes) return count; if (size >= bytes) return count;
} }
} }

View File

@ -102,7 +102,7 @@ struct test_storage : default_storage
return 0; return 0;
} }
for (auto const& b : bufs) m_written += int(b.iov_len); for (auto const& b : bufs) m_written += int(b.size());
l.unlock(); l.unlock();
return default_storage::writev(bufs, piece_index, offset, flags, se); return default_storage::writev(bufs, piece_index, offset, flags, se);
} }