use a dedicated class template for flags types instead of enum class. It's more backwards compatible and improves ergonomics

This commit is contained in:
arvidn 2017-07-14 17:59:20 -07:00 committed by Arvid Norberg
parent a41c9f62e4
commit c4afb5e949
27 changed files with 244 additions and 239 deletions

View File

@ -874,7 +874,7 @@ void generate_data(char const* path, torrent_info const& ti)
iovec_t const b = { reinterpret_cast<char*>(piece) iovec_t const b = { reinterpret_cast<char*>(piece)
, size_t(std::min(left_in_piece, 0x4000))}; , size_t(std::min(left_in_piece, 0x4000))};
storage_error error; storage_error error;
st->writev(b, i, j, open_mode_t::write_only, error); st->writev(b, i, j, open_mode::write_only, error);
if (error) if (error)
std::fprintf(stderr, "storage error: %s\n", error.ec.message().c_str()); std::fprintf(stderr, "storage error: %s\n", error.ec.message().c_str());
} }

View File

@ -122,40 +122,41 @@ namespace libtorrent {
using file_handle = std::shared_ptr<file>; using file_handle = std::shared_ptr<file>;
// hidden
struct open_mode_tag;
using open_mode_t = flags::bitfield_flag<std::uint32_t, open_mode_tag>;
// the open mode for files. Used for the file constructor or // the open mode for files. Used for the file constructor or
// file::open(). // file::open().
enum class open_mode_t : std::uint32_t namespace open_mode {
{
none = 0,
// open the file for reading only // open the file for reading only
read_only = 0, constexpr open_mode_t read_only{0};
// open the file for writing only // open the file for writing only
write_only = 1, constexpr open_mode_t write_only{1};
// open the file for reading and writing // open the file for reading and writing
read_write = 2, constexpr open_mode_t read_write{2};
// the mask for the bits determining read or write mode constexpr open_mode_t rw_mask = read_only | write_only | read_write;
rw_mask = read_only | write_only | read_write,
// open the file in sparse mode (if supported by the // open the file in sparse mode (if supported by the
// filesystem). // filesystem).
sparse = 0x4, constexpr open_mode_t sparse{0x4};
// don't update the access timestamps on the file (if // don't update the access timestamps on the file (if
// supported by the operating system and filesystem). // supported by the operating system and filesystem).
// this generally improves disk performance. // this generally improves disk performance.
no_atime = 0x8, constexpr open_mode_t no_atime{0x8};
// open the file for random access. This disables read-ahead // open the file for random access. This disables read-ahead
// logic // logic
random_access = 0x10, constexpr open_mode_t random_access{0x10};
// prevent the file from being opened by another process // prevent the file from being opened by another process
// while it's still being held open by this handle // while it's still being held open by this handle
lock_file = 0x20, constexpr open_mode_t lock_file{0x20};
// don't put any pressure on the OS disk cache // don't put any pressure on the OS disk cache
// because of access to this file. We expect our // because of access to this file. We expect our
@ -163,24 +164,19 @@ namespace libtorrent {
// a cache at the bittorrent block level. This // a cache at the bittorrent block level. This
// may improve overall system performance by // may improve overall system performance by
// leaving running applications in the page cache // leaving running applications in the page cache
no_cache = 0x40, constexpr open_mode_t no_cache{0x40};
// this is only used for readv/writev flags // this is only used for readv/writev flags
coalesce_buffers = 0x100, constexpr open_mode_t coalesce_buffers{0x100};
// when creating a file, set the hidden attribute (windows only) // when creating a file, set the hidden attribute (windows only)
attribute_hidden = 0x200, constexpr open_mode_t attribute_hidden{0x200};
// when creating a file, set the executable attribute // when creating a file, set the executable attribute
attribute_executable = 0x400, constexpr open_mode_t attribute_executable{0x400};
// the mask of all attribute bits // the mask of all attribute bits
attribute_mask = attribute_hidden | attribute_executable constexpr open_mode_t attribute_mask = attribute_hidden | attribute_executable;
};
namespace flags {
template <>
struct enable_flag_operators<open_mode_t> : std::true_type {};
} }
using namespace flags; using namespace flags;
@ -199,9 +195,9 @@ namespace flags {
open_mode_t open_mode() const { return m_open_mode; } open_mode_t open_mode() const { return m_open_mode; }
std::int64_t writev(std::int64_t file_offset, span<iovec_t const> bufs std::int64_t writev(std::int64_t file_offset, span<iovec_t const> bufs
, error_code& ec, open_mode_t flags = open_mode_t::none); , error_code& ec, open_mode_t flags = open_mode_t{});
std::int64_t readv(std::int64_t file_offset, span<iovec_t const> bufs std::int64_t readv(std::int64_t file_offset, span<iovec_t const> bufs
, error_code& ec, open_mode_t flags = open_mode_t::none); , error_code& ec, open_mode_t flags = open_mode_t{});
std::int64_t get_size(error_code& ec) const; std::int64_t get_size(error_code& ec) const;
@ -215,7 +211,7 @@ namespace flags {
handle_type m_file_handle; handle_type m_file_handle;
open_mode_t m_open_mode = open_mode_t::none; open_mode_t m_open_mode{};
#if defined TORRENT_WINDOWS #if defined TORRENT_WINDOWS
static bool has_manage_volume_privs; static bool has_manage_volume_privs;
#endif #endif

View File

@ -111,7 +111,7 @@ namespace libtorrent {
file_handle file_ptr; file_handle file_ptr;
time_point const opened{aux::time_now()}; time_point const opened{aux::time_now()};
time_point last_use{opened}; time_point last_use{opened};
open_mode_t mode = open_mode_t::none; open_mode_t mode{};
}; };
// maps storage pointer, file index pairs to the // maps storage pointer, file index pairs to the

View File

@ -33,54 +33,73 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef TORRENT_FLAGS_HPP_INCLUDED #ifndef TORRENT_FLAGS_HPP_INCLUDED
#define TORRENT_FLAGS_HPP_INCLUDED #define TORRENT_FLAGS_HPP_INCLUDED
// this is based on Anthony William's article:
// https://www.justsoftwaresolutions.co.uk/cplusplus/using-enum-classes-as-bitfields.html
#include <type_traits> // for enable_if #include <type_traits> // for enable_if
namespace libtorrent { namespace libtorrent {
namespace flags { namespace flags {
template <typename E> template<typename UnderlyingType, typename Tag
struct enable_flag_operators : std::false_type {}; , typename Cond = typename std::enable_if<std::is_integral<UnderlyingType>::value>::type>
struct bitfield_flag
{
using underlying_type = UnderlyingType;
#define ENUM_OPERATOR(op) \ constexpr bitfield_flag(bitfield_flag const& rhs) noexcept = default;
template<typename E> \ constexpr bitfield_flag(bitfield_flag&& rhs) noexcept = default;
constexpr typename std::enable_if<enable_flag_operators<E>::value, E>::type \ constexpr bitfield_flag() noexcept : m_val(0) {}
operator op (E const lhs, E const rhs) { \ explicit constexpr bitfield_flag(UnderlyingType val) : m_val(val) {}
using underlying = typename std::underlying_type<E>::type; \ explicit constexpr operator UnderlyingType() const { return m_val; }
return static_cast<E>( \ explicit constexpr operator bool() const { return m_val != 0; }
static_cast<underlying>(lhs) op static_cast<underlying>(rhs)); \
} \ bool constexpr operator==(bitfield_flag const f) const
\ { return m_val == f.m_val; }
template<typename E> \
typename std::enable_if<enable_flag_operators<E>::value, E&>::type \ bool constexpr operator!=(bitfield_flag const f) const
operator op##= (E& lhs, E const rhs) { \ { return m_val != f.m_val; }
using underlying = typename std::underlying_type<E>::type; \
lhs = static_cast<E>( \ bitfield_flag& operator|=(bitfield_flag const f)
static_cast<underlying>(lhs) op static_cast<underlying>(rhs)); \ {
return lhs; \ m_val |= f.m_val;
return *this;
} }
ENUM_OPERATOR(|) bitfield_flag& operator&=(bitfield_flag const f)
ENUM_OPERATOR(&) {
ENUM_OPERATOR(^) m_val &= f.m_val;
return *this;
template<typename E>
constexpr typename std::enable_if<enable_flag_operators<E>::value, E>::type
operator~ (E const operand) {
using underlying = typename std::underlying_type<E>::type;
return static_cast<E>(~static_cast<underlying>(operand));
} }
template<typename E> bitfield_flag& operator^=(bitfield_flag const f)
constexpr typename std::enable_if<enable_flag_operators<E>::value, bool>::type {
test(E const operand) { m_val ^= f.m_val;
using underlying = typename std::underlying_type<E>::type; return *this;
return static_cast<underlying>(operand) != 0;
} }
#undef ENUM_OPERATOR constexpr friend bitfield_flag operator|(bitfield_flag const lhs, bitfield_flag const rhs)
{
return bitfield_flag(lhs.m_val | rhs.m_val);
}
constexpr friend bitfield_flag operator&(bitfield_flag const lhs, bitfield_flag const rhs)
{
return bitfield_flag(lhs.m_val & rhs.m_val);
}
constexpr friend bitfield_flag operator^(bitfield_flag const lhs, bitfield_flag const rhs)
{
return bitfield_flag(lhs.m_val ^ rhs.m_val);
}
constexpr bitfield_flag operator~() const
{
return bitfield_flag(~m_val);
}
bitfield_flag& operator=(bitfield_flag const& rhs) noexcept = default;
bitfield_flag& operator=(bitfield_flag&& rhs) noexcept = default;
private:
UnderlyingType m_val;
};
} // flags } // flags
} // libtorrent } // libtorrent

View File

@ -104,7 +104,7 @@ struct TORRENT_EXTRA_EXPORT http_connection
, int prio = 0, aux::proxy_settings const* ps = NULL, int handle_redirects = 5 , int prio = 0, aux::proxy_settings const* ps = NULL, int handle_redirects = 5
, std::string const& user_agent = std::string() , std::string const& user_agent = std::string()
, boost::optional<address> const& bind_addr = boost::optional<address>() , boost::optional<address> const& bind_addr = boost::optional<address>()
, resolver_flags resolve_flags = resolver_flags::none, std::string const& auth_ = std::string() , resolver_flags resolve_flags = resolver_flags{}, std::string const& auth_ = std::string()
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
, i2p_connection* i2p_conn = 0 , i2p_connection* i2p_conn = 0
#endif #endif
@ -114,7 +114,7 @@ struct TORRENT_EXTRA_EXPORT http_connection
, time_duration timeout, int prio = 0, aux::proxy_settings const* ps = NULL , time_duration timeout, int prio = 0, aux::proxy_settings const* ps = NULL
, bool ssl = false, int handle_redirect = 5 , bool ssl = false, int handle_redirect = 5
, boost::optional<address> const& bind_addr = boost::optional<address>() , boost::optional<address> const& bind_addr = boost::optional<address>()
, resolver_flags resolve_flags = resolver_flags::none , resolver_flags resolve_flags = resolver_flags{}
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
, i2p_connection* i2p_conn = 0 , i2p_connection* i2p_conn = 0
#endif #endif

View File

@ -43,31 +43,23 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent { namespace libtorrent {
enum class resolver_flags : std::uint8_t // hidden
struct resolver_flag_tag;
using resolver_flags = flags::bitfield_flag<std::uint8_t, resolver_flag_tag>;
struct TORRENT_EXTRA_EXPORT resolver_interface
{ {
none = 0, using callback_t = std::function<void(error_code const&, std::vector<address> const&)>;
// this flag will make async_resolve() only use the cache and fail if we // this flag will make async_resolve() only use the cache and fail if we
// don't have a cache entry, regardless of how old it is. This is usefull // don't have a cache entry, regardless of how old it is. This is usefull
// when completing the lookup quickly is more important than accuracy, // when completing the lookup quickly is more important than accuracy,
// like on shutdown // like on shutdown
cache_only = 1, static constexpr resolver_flags cache_only{1};
// set this flag for lookups that are not critical during shutdown. i.e. // set this flag for lookups that are not critical during shutdown. i.e.
// for looking up tracker names _except_ when stopping a tracker. // for looking up tracker names _except_ when stopping a tracker.
abort_on_shutdown = 2 static constexpr resolver_flags abort_on_shutdown{2};
};
namespace flags {
template <>
struct enable_flag_operators<resolver_flags> : std::true_type {};
}
using namespace flags;
struct TORRENT_EXTRA_EXPORT resolver_interface
{
using callback_t = std::function<void(error_code const&, std::vector<address> const&)>;
virtual void async_resolve(std::string const& host, resolver_flags flags virtual void async_resolve(std::string const& host, resolver_flags flags
, callback_t const& h) = 0; , callback_t const& h) = 0;

View File

@ -179,7 +179,7 @@ std::shared_ptr<http_connection> test_request(io_service& ios
}); });
h->get(url, seconds(1), 0, &ps, 5, "test/user-agent", boost::optional<address>() h->get(url, seconds(1), 0, &ps, 5, "test/user-agent", boost::optional<address>()
, resolver_flags::none, auth); , resolver_flags{}, auth);
return h; return h;
} }

View File

@ -120,9 +120,9 @@ namespace libtorrent {
open_mode_t file_flags_for_job(disk_io_job* j open_mode_t file_flags_for_job(disk_io_job* j
, bool const coalesce_buffers) , bool const coalesce_buffers)
{ {
open_mode_t ret = open_mode_t::none; open_mode_t ret = open_mode_t{};
if (!(j->flags & disk_interface::sequential_access)) ret |= open_mode_t::random_access; if (!(j->flags & disk_interface::sequential_access)) ret |= open_mode::random_access;
if (coalesce_buffers) ret |= open_mode_t::coalesce_buffers; if (coalesce_buffers) ret |= open_mode::coalesce_buffers;
return ret; return ret;
} }
@ -664,7 +664,7 @@ namespace libtorrent {
#endif #endif
open_mode_t const file_flags = m_settings.get_bool(settings_pack::coalesce_writes) open_mode_t const file_flags = m_settings.get_bool(settings_pack::coalesce_writes)
? open_mode_t::coalesce_buffers : open_mode_t::none; ? open_mode::coalesce_buffers : open_mode_t{};
// issue the actual write operation // issue the actual write operation
auto iov_start = iov; auto iov_start = iov;

View File

@ -328,9 +328,9 @@ done:
namespace libtorrent { namespace libtorrent {
static_assert((open_mode_t::rw_mask & open_mode_t::sparse) == open_mode_t::none, "internal flags error"); static_assert(!(open_mode::rw_mask & open_mode::sparse), "internal flags error");
static_assert((open_mode_t::rw_mask & open_mode_t::attribute_mask) == open_mode_t::none, "internal flags error"); static_assert(!(open_mode::rw_mask & open_mode::attribute_mask), "internal flags error");
static_assert((open_mode_t::sparse & open_mode_t::attribute_mask) == open_mode_t::none, "internal flags error"); static_assert(!(open_mode::sparse & open_mode::attribute_mask), "internal flags error");
directory::directory(std::string const& path, error_code& ec) directory::directory(std::string const& path, error_code& ec)
: m_done(false) : m_done(false)
@ -530,21 +530,21 @@ static_assert((open_mode_t::sparse & open_mode_t::attribute_mask) == open_mode_t
FILE_ATTRIBUTE_HIDDEN, // hidden + executable FILE_ATTRIBUTE_HIDDEN, // hidden + executable
}}; }};
TORRENT_ASSERT(static_cast<std::size_t>(mode & open_mode_t::rw_mask) < mode_array.size()); TORRENT_ASSERT(static_cast<std::uint32_t>(mode & open_mode::rw_mask) < mode_array.size());
win_open_mode_t const& m = mode_array[static_cast<std::size_t>(mode & open_mode_t::rw_mask)]; win_open_mode_t const& m = mode_array[static_cast<std::uint32_t>(mode & open_mode::rw_mask)];
DWORD a = attrib_array[static_cast<std::size_t>(mode & open_mode_t::attribute_mask) >> 12]; DWORD a = attrib_array[static_cast<std::uint32_t>(mode & open_mode::attribute_mask) >> 12];
// one might think it's a good idea to pass in FILE_FLAG_RANDOM_ACCESS. It // one might think it's a good idea to pass in FILE_FLAG_RANDOM_ACCESS. It
// turns out that it isn't. That flag will break your operating system: // turns out that it isn't. That flag will break your operating system:
// http://support.microsoft.com/kb/2549369 // http://support.microsoft.com/kb/2549369
DWORD const flags = (test(mode & open_mode_t::random_access) ? 0 : FILE_FLAG_SEQUENTIAL_SCAN) DWORD const flags = ((mode & open_mode::random_access) ? 0 : FILE_FLAG_SEQUENTIAL_SCAN)
| (a ? a : FILE_ATTRIBUTE_NORMAL) | (a ? a : FILE_ATTRIBUTE_NORMAL)
| FILE_FLAG_OVERLAPPED | FILE_FLAG_OVERLAPPED
| (test(mode & open_mode_t::no_cache) ? FILE_FLAG_WRITE_THROUGH : 0); | ((mode & open_mode::no_cache) ? FILE_FLAG_WRITE_THROUGH : 0);
handle_type handle = CreateFileW(file_path.c_str(), m.rw_mode handle_type handle = CreateFileW(file_path.c_str(), m.rw_mode
, test(mode & open_mode_t::lock_file) ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE , (mode & open_mode::lock_file) ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE
, 0, m.create_mode, flags, 0); , 0, m.create_mode, flags, 0);
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
@ -558,8 +558,8 @@ static_assert((open_mode_t::sparse & open_mode_t::attribute_mask) == open_mode_t
// try to make the file sparse if supported // try to make the file sparse if supported
// only set this flag if the file is opened for writing // only set this flag if the file is opened for writing
if (test(mode & open_mode_t::sparse) if ((mode & open_mode::sparse)
&& (mode & open_mode_t::rw_mask) != open_mode_t::read_only) && (mode & open_mode::rw_mask) != open_mode::read_only)
{ {
DWORD temp; DWORD temp;
overlapped_t ol; overlapped_t ol;
@ -577,7 +577,7 @@ static_assert((open_mode_t::sparse & open_mode_t::attribute_mask) == open_mode_t
| S_IRGRP | S_IWGRP | S_IRGRP | S_IWGRP
| S_IROTH | S_IWOTH; | S_IROTH | S_IWOTH;
if (test(mode & open_mode_t::attribute_executable)) if ((mode & open_mode::attribute_executable))
permissions |= S_IXGRP | S_IXOTH | S_IXUSR; permissions |= S_IXGRP | S_IXOTH | S_IXUSR;
#ifdef O_BINARY #ifdef O_BINARY
static const int mode_array[] = {O_RDONLY | O_BINARY, O_WRONLY | O_CREAT | O_BINARY, O_RDWR | O_CREAT | O_BINARY}; static const int mode_array[] = {O_RDONLY | O_BINARY, O_WRONLY | O_CREAT | O_BINARY, O_RDWR | O_CREAT | O_BINARY};
@ -587,27 +587,27 @@ static_assert((open_mode_t::sparse & open_mode_t::attribute_mask) == open_mode_t
int open_mode = 0 int open_mode = 0
#ifdef O_NOATIME #ifdef O_NOATIME
| (test(mode & open_mode_t::no_atime) ? O_NOATIME : 0) | ((mode & open_mode::no_atime) ? O_NOATIME : 0)
#endif #endif
#ifdef O_SYNC #ifdef O_SYNC
| (test(mode & open_mode_t::no_cache) ? O_SYNC : 0) | ((mode & open_mode::no_cache) ? O_SYNC : 0)
#endif #endif
; ;
handle_type handle = ::open(file_path.c_str() handle_type handle = ::open(file_path.c_str()
, mode_array[static_cast<std::size_t>(mode & open_mode_t::rw_mask)] | open_mode , mode_array[static_cast<std::uint32_t>(mode & open_mode::rw_mask)] | open_mode
, permissions); , permissions);
#ifdef O_NOATIME #ifdef O_NOATIME
// O_NOATIME is not allowed for files we don't own // O_NOATIME is not allowed for files we don't own
// so, if we get EPERM when we try to open with it // so, if we get EPERM when we try to open with it
// try again without O_NOATIME // try again without O_NOATIME
if (handle == -1 && test(mode & open_mode_t::no_atime) && errno == EPERM) if (handle == -1 && (mode & open_mode::no_atime) && errno == EPERM)
{ {
mode &= ~open_mode_t::no_atime; mode &= ~open_mode::no_atime;
open_mode &= ~O_NOATIME; open_mode &= ~O_NOATIME;
handle = ::open(file_path.c_str() handle = ::open(file_path.c_str()
, mode_array[static_cast<std::size_t>(mode & open_mode_t::rw_mask)] | open_mode , mode_array[static_cast<std::uint32_t>(mode & open_mode::rw_mask)] | open_mode
, permissions); , permissions);
} }
#endif #endif
@ -628,7 +628,7 @@ static_assert((open_mode_t::sparse & open_mode_t::attribute_mask) == open_mode_t
#ifdef DIRECTIO_ON #ifdef DIRECTIO_ON
// for solaris // for solaris
if (test(mode & open_mode_t::no_cache)) if ((mode & open_mode::no_cache))
{ {
int yes = 1; int yes = 1;
directio(native_handle(), DIRECTIO_ON); directio(native_handle(), DIRECTIO_ON);
@ -637,7 +637,7 @@ static_assert((open_mode_t::sparse & open_mode_t::attribute_mask) == open_mode_t
#ifdef F_NOCACHE #ifdef F_NOCACHE
// for BSD/Mac // for BSD/Mac
if (test(mode & open_mode_t::no_cache)) if ((mode & open_mode::no_cache))
{ {
int yes = 1; int yes = 1;
fcntl(native_handle(), F_NOCACHE, &yes); fcntl(native_handle(), F_NOCACHE, &yes);
@ -650,7 +650,7 @@ static_assert((open_mode_t::sparse & open_mode_t::attribute_mask) == open_mode_t
#endif #endif
#ifdef POSIX_FADV_RANDOM #ifdef POSIX_FADV_RANDOM
if (test(mode & open_mode_t::random_access)) if ((mode & open_mode::random_access))
{ {
// disable read-ahead // disable read-ahead
posix_fadvise(native_handle(), 0, 0, POSIX_FADV_RANDOM); posix_fadvise(native_handle(), 0, 0, POSIX_FADV_RANDOM);
@ -727,9 +727,9 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
// if this file is open for writing, has the sparse // if this file is open for writing, has the sparse
// flag set, but there are no sparse regions, unset // flag set, but there are no sparse regions, unset
// the flag // the flag
open_mode_t const rw_mode = m_open_mode & open_mode_t::rw_mask; open_mode_t const rw_mode = m_open_mode & open_mode::rw_mask;
if ((rw_mode != open_mode_t::read_only) if ((rw_mode != open_mode::read_only)
&& test(m_open_mode & open_mode_t::sparse) && (m_open_mode & open_mode::sparse)
&& !is_sparse(native_handle())) && !is_sparse(native_handle()))
{ {
overlapped_t ol; overlapped_t ol;
@ -760,7 +760,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
m_file_handle = INVALID_HANDLE_VALUE; m_file_handle = INVALID_HANDLE_VALUE;
m_open_mode = open_mode_t::none; m_open_mode = open_mode_t{};
} }
namespace { namespace {
@ -954,8 +954,8 @@ namespace {
#endif #endif
return -1; return -1;
} }
TORRENT_ASSERT((m_open_mode & open_mode_t::rw_mask) == open_mode_t::read_only TORRENT_ASSERT((m_open_mode & open_mode::rw_mask) == open_mode::read_only
|| (m_open_mode & open_mode_t::rw_mask) == open_mode_t::read_write); || (m_open_mode & open_mode::rw_mask) == open_mode::read_write);
TORRENT_ASSERT(!bufs.empty()); TORRENT_ASSERT(!bufs.empty());
TORRENT_ASSERT(is_open()); TORRENT_ASSERT(is_open());
@ -967,16 +967,16 @@ namespace {
// there's no point in coalescing single buffer writes // there's no point in coalescing single buffer writes
if (bufs.size() == 1) if (bufs.size() == 1)
{ {
flags &= ~open_mode_t::coalesce_buffers; flags &= ~open_mode::coalesce_buffers;
} }
iovec_t tmp; iovec_t tmp;
span<iovec_t const> tmp_bufs = bufs; span<iovec_t const> tmp_bufs = bufs;
if (test(flags & open_mode_t::coalesce_buffers)) if (flags & open_mode::coalesce_buffers)
{ {
if (!coalesce_read_buffers(tmp_bufs, tmp)) if (!coalesce_read_buffers(tmp_bufs, tmp))
// ok, that failed, don't coalesce this read // ok, that failed, don't coalesce this read
flags &= ~open_mode_t::coalesce_buffers; flags &= ~open_mode::coalesce_buffers;
} }
#if TORRENT_USE_PREAD #if TORRENT_USE_PREAD
@ -985,7 +985,7 @@ namespace {
std::int64_t ret = iov(&::read, native_handle(), file_offset, tmp_bufs, ec); std::int64_t ret = iov(&::read, native_handle(), file_offset, tmp_bufs, ec);
#endif #endif
if (test(flags & open_mode_t::coalesce_buffers)) if (flags & open_mode::coalesce_buffers)
coalesce_read_buffers_end(bufs coalesce_read_buffers_end(bufs
, tmp.data(), !ec); , tmp.data(), !ec);
@ -1008,8 +1008,8 @@ namespace {
#endif #endif
return -1; return -1;
} }
TORRENT_ASSERT((m_open_mode & open_mode_t::rw_mask) == open_mode_t::write_only TORRENT_ASSERT((m_open_mode & open_mode::rw_mask) == open_mode::write_only
|| (m_open_mode & open_mode_t::rw_mask) == open_mode_t::read_write); || (m_open_mode & open_mode::rw_mask) == open_mode::read_write);
TORRENT_ASSERT(!bufs.empty()); TORRENT_ASSERT(!bufs.empty());
TORRENT_ASSERT(is_open()); TORRENT_ASSERT(is_open());
@ -1024,15 +1024,15 @@ namespace {
// there's no point in coalescing single buffer writes // there's no point in coalescing single buffer writes
if (bufs.size() == 1) if (bufs.size() == 1)
{ {
flags &= ~open_mode_t::coalesce_buffers; flags &= ~open_mode::coalesce_buffers;
} }
iovec_t tmp; iovec_t tmp;
if (test(flags & open_mode_t::coalesce_buffers)) if (flags & open_mode::coalesce_buffers)
{ {
if (!coalesce_write_buffers(bufs, tmp)) if (!coalesce_write_buffers(bufs, tmp))
// ok, that failed, don't coalesce writes // ok, that failed, don't coalesce writes
flags &= ~open_mode_t::coalesce_buffers; flags &= ~open_mode::coalesce_buffers;
} }
#if TORRENT_USE_PREAD #if TORRENT_USE_PREAD
@ -1041,14 +1041,14 @@ namespace {
std::int64_t ret = iov(&::write, native_handle(), file_offset, bufs, ec); std::int64_t ret = iov(&::write, native_handle(), file_offset, bufs, ec);
#endif #endif
if (test(flags & open_mode_t::coalesce_buffers)) if (flags & open_mode::coalesce_buffers)
delete[] tmp.data(); delete[] tmp.data();
#endif #endif
#if TORRENT_USE_FDATASYNC \ #if TORRENT_USE_FDATASYNC \
&& !defined F_NOCACHE && \ && !defined F_NOCACHE && \
!defined DIRECTIO_ON !defined DIRECTIO_ON
if (test(m_open_mode & open_mode_t::no_cache)) if (m_open_mode & open_mode::no_cache)
{ {
if (fdatasync(native_handle()) != 0 if (fdatasync(native_handle()) != 0
&& errno != EINVAL && errno != EINVAL
@ -1163,7 +1163,7 @@ namespace {
} }
#if _WIN32_WINNT >= 0x0600 // only if Windows Vista or newer #if _WIN32_WINNT >= 0x0600 // only if Windows Vista or newer
if (!test(m_open_mode & open_mode_t::sparse)) if (!(m_open_mode & open_mode::sparse))
{ {
typedef DWORD (WINAPI *GetFileInformationByHandleEx_t)(HANDLE hFile typedef DWORD (WINAPI *GetFileInformationByHandleEx_t)(HANDLE hFile
, FILE_INFO_BY_HANDLE_CLASS FileInformationClass , FILE_INFO_BY_HANDLE_CLASS FileInformationClass
@ -1218,7 +1218,7 @@ namespace {
// is less than the file size. Otherwise we would just // is less than the file size. Otherwise we would just
// update the modification time of the file for no good // update the modification time of the file for no good
// reason. // reason.
if (!test(m_open_mode & open_mode_t::sparse) if (!(m_open_mode & open_mode::sparse)
&& std::int64_t(st.st_blocks) < (s + st.st_blksize - 1) / st.st_blksize) && std::int64_t(st.st_blocks) < (s + st.st_blksize - 1) / st.st_blksize)
{ {
// How do we know that the file is already allocated? // How do we know that the file is already allocated?

View File

@ -119,8 +119,8 @@ namespace libtorrent {
#endif #endif
TORRENT_ASSERT(is_complete(p)); TORRENT_ASSERT(is_complete(p));
TORRENT_ASSERT((m & open_mode_t::rw_mask) == open_mode_t::read_only TORRENT_ASSERT((m & open_mode::rw_mask) == open_mode::read_only
|| (m & open_mode_t::rw_mask) == open_mode_t::read_write); || (m & open_mode::rw_mask) == open_mode::read_write);
auto const i = m_files.find(std::make_pair(st, file_index)); auto const i = m_files.find(std::make_pair(st, file_index));
if (i != m_files.end()) if (i != m_files.end())
{ {
@ -130,9 +130,9 @@ namespace libtorrent {
// if we asked for a file in write mode, // if we asked for a file in write mode,
// and the cached file is is not opened in // and the cached file is is not opened in
// write mode, re-open it // write mode, re-open it
if ((((e.mode & open_mode_t::rw_mask) != open_mode_t::read_write) if ((((e.mode & open_mode::rw_mask) != open_mode::read_write)
&& ((m & open_mode_t::rw_mask) == open_mode_t::read_write)) && ((m & open_mode::rw_mask) == open_mode::read_write))
|| (e.mode & open_mode_t::random_access) != (m & open_mode_t::random_access)) || (e.mode & open_mode::random_access) != (m & open_mode::random_access))
{ {
file_handle new_file = std::make_shared<file>(); file_handle new_file = std::make_shared<file>();
@ -185,20 +185,20 @@ namespace libtorrent {
std::uint32_t to_file_open_mode(open_mode_t const mode) std::uint32_t to_file_open_mode(open_mode_t const mode)
{ {
std::uint32_t ret = 0; std::uint32_t ret = 0;
open_mode_t const rw_mode = mode & open_mode_t::rw_mask; open_mode_t const rw_mode = mode & open_mode::rw_mask;
ret = (rw_mode == open_mode_t::read_only) ret = (rw_mode == open_mode::read_only)
? file_open_mode::read_only ? file_open_mode::read_only
: (rw_mode == open_mode_t::write_only) : (rw_mode == open_mode::write_only)
? file_open_mode::write_only ? file_open_mode::write_only
: (rw_mode == open_mode_t::read_write) : (rw_mode == open_mode::read_write)
? file_open_mode::read_write ? file_open_mode::read_write
: 0; : 0;
if (test(mode & open_mode_t::sparse)) ret |= file_open_mode::sparse; if (mode & open_mode::sparse) ret |= file_open_mode::sparse;
if (test(mode & open_mode_t::no_atime)) ret |= file_open_mode::no_atime; if (mode & open_mode::no_atime) ret |= file_open_mode::no_atime;
if (test(mode & open_mode_t::random_access)) ret |= file_open_mode::random_access; if (mode & open_mode::random_access) ret |= file_open_mode::random_access;
if (test(mode & open_mode_t::lock_file)) ret |= file_open_mode::locked; if (mode & open_mode::lock_file) ret |= file_open_mode::locked;
return ret; return ret;
} }

View File

@ -88,7 +88,7 @@ http_connection::http_connection(io_service& ios
, m_rate_limit(0) , m_rate_limit(0)
, m_download_quota(0) , m_download_quota(0)
, m_priority(0) , m_priority(0)
, m_resolve_flags(resolver_flags::none) , m_resolve_flags{}
, m_port(0) , m_port(0)
, m_bottled(bottled) , m_bottled(bottled)
, m_called(false) , m_called(false)

View File

@ -223,8 +223,8 @@ namespace libtorrent {
, ps.proxy_tracker_connections ? &ps : nullptr , ps.proxy_tracker_connections ? &ps : nullptr
, 5, user_agent, bind_interface() , 5, user_agent, bind_interface()
, (tracker_req().event == tracker_request::stopped , (tracker_req().event == tracker_request::stopped
? resolver_flags::cache_only : resolver_flags::none) ? resolver_interface::cache_only : resolver_flags{})
| resolver_flags::abort_on_shutdown | resolver_interface::abort_on_shutdown
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
, tracker_req().auth , tracker_req().auth
#else #else

View File

@ -92,7 +92,7 @@ namespace libtorrent {
error_code ec; error_code ec;
std::string fn = combine_path(m_path, m_name); std::string fn = combine_path(m_path, m_name);
m_file.open(fn, open_mode_t::read_only, ec); m_file.open(fn, open_mode::read_only, ec);
if (ec) return; if (ec) return;
// parse header // parse header
@ -178,7 +178,7 @@ namespace libtorrent {
TORRENT_ASSERT(offset >= 0); TORRENT_ASSERT(offset >= 0);
std::unique_lock<std::mutex> l(m_mutex); std::unique_lock<std::mutex> l(m_mutex);
open_file(open_mode_t::read_write, ec); open_file(open_mode::read_write, ec);
if (ec) return -1; if (ec) return -1;
auto const i = m_piece_map.find(piece); auto const i = m_piece_map.find(piece);
@ -206,7 +206,7 @@ namespace libtorrent {
} }
slot_index_t const slot = i->second; slot_index_t const slot = i->second;
open_file(open_mode_t::read_write, ec); open_file(open_mode::read_write, ec);
if (ec) return -1; if (ec) return -1;
l.unlock(); l.unlock();
@ -218,12 +218,12 @@ namespace libtorrent {
void part_file::open_file(open_mode_t const mode, error_code& ec) void part_file::open_file(open_mode_t const mode, error_code& ec)
{ {
if (m_file.is_open() if (m_file.is_open()
&& ((m_file.open_mode() & open_mode_t::rw_mask) == mode && ((m_file.open_mode() & open_mode::rw_mask) == mode
|| mode == open_mode_t::read_only)) return; || mode == open_mode::read_only)) return;
std::string fn = combine_path(m_path, m_name); std::string fn = combine_path(m_path, m_name);
m_file.open(fn, mode, ec); m_file.open(fn, mode, ec);
if (((mode & open_mode_t::rw_mask) != open_mode_t::read_only) if (((mode & open_mode::rw_mask) != open_mode::read_only)
&& ec == boost::system::errc::no_such_file_or_directory) && ec == boost::system::errc::no_such_file_or_directory)
{ {
// this means the directory the file is in doesn't exist. // this means the directory the file is in doesn't exist.
@ -301,7 +301,7 @@ namespace libtorrent {
if (i != m_piece_map.end()) if (i != m_piece_map.end())
{ {
slot_index_t const slot = i->second; slot_index_t const slot = i->second;
open_file(open_mode_t::read_only, ec); open_file(open_mode::read_only, ec);
if (ec) return; if (ec) return;
if (!buf) buf.reset(new char[m_piece_size]); if (!buf) buf.reset(new char[m_piece_size]);
@ -375,7 +375,7 @@ namespace libtorrent {
return; return;
} }
open_file(open_mode_t::read_write, ec); open_file(open_mode::read_write, ec);
if (ec) return; if (ec) return;
std::vector<char> header(static_cast<std::size_t>(m_header_size)); std::vector<char> header(static_cast<std::size_t>(m_header_size));

View File

@ -36,6 +36,10 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent { namespace libtorrent {
constexpr resolver_flags resolver_interface::cache_only;
constexpr resolver_flags resolver_interface::abort_on_shutdown;
resolver::resolver(io_service& ios) resolver::resolver(io_service& ios)
: m_ios(ios) : m_ios(ios)
, m_resolver(ios) , m_resolver(ios)
@ -103,7 +107,7 @@ namespace libtorrent {
if (i != m_cache.end()) if (i != m_cache.end())
{ {
// keep cache entries valid for m_timeout seconds // keep cache entries valid for m_timeout seconds
if (test(flags & resolver_flags::cache_only) if ((flags & resolver_interface::cache_only)
|| i->second.last_seen + m_timeout >= aux::time_now()) || i->second.last_seen + m_timeout >= aux::time_now())
{ {
m_ios.post(std::bind(h, ec, i->second.addresses)); m_ios.post(std::bind(h, ec, i->second.addresses));
@ -111,7 +115,7 @@ namespace libtorrent {
} }
} }
if (test(flags & resolver_flags::cache_only)) if (flags & resolver_interface::cache_only)
{ {
// we did not find a cache entry, fail the lookup // we did not find a cache entry, fail the lookup
m_ios.post(std::bind(h, boost::asio::error::host_not_found m_ios.post(std::bind(h, boost::asio::error::host_not_found
@ -124,7 +128,7 @@ namespace libtorrent {
using namespace std::placeholders; using namespace std::placeholders;
ADD_OUTSTANDING_ASYNC("resolver::on_lookup"); ADD_OUTSTANDING_ASYNC("resolver::on_lookup");
if (test(flags & resolver_flags::abort_on_shutdown)) if (flags & resolver_interface::abort_on_shutdown)
{ {
m_resolver.async_resolve(q, std::bind(&resolver::on_lookup, this, _1, _2 m_resolver.async_resolve(q, std::bind(&resolver::on_lookup, this, _1, _2
, h, host)); , h, host));

View File

@ -5769,7 +5769,7 @@ namespace {
void session_impl::add_dht_node_name(std::pair<std::string, int> const& node) void session_impl::add_dht_node_name(std::pair<std::string, int> const& node)
{ {
ADD_OUTSTANDING_ASYNC("session_impl::on_dht_name_lookup"); ADD_OUTSTANDING_ASYNC("session_impl::on_dht_name_lookup");
m_host_resolver.async_resolve(node.first, resolver_flags::abort_on_shutdown m_host_resolver.async_resolve(node.first, resolver::abort_on_shutdown
, std::bind(&session_impl::on_dht_name_lookup , std::bind(&session_impl::on_dht_name_lookup
, this, _1, _2, node.second)); , this, _1, _2, node.second));
} }
@ -5798,7 +5798,7 @@ namespace {
{ {
ADD_OUTSTANDING_ASYNC("session_impl::on_dht_router_name_lookup"); ADD_OUTSTANDING_ASYNC("session_impl::on_dht_router_name_lookup");
++m_outstanding_router_lookups; ++m_outstanding_router_lookups;
m_host_resolver.async_resolve(node.first, resolver_flags::abort_on_shutdown m_host_resolver.async_resolve(node.first, resolver::abort_on_shutdown
, std::bind(&session_impl::on_dht_router_name_lookup , std::bind(&session_impl::on_dht_router_name_lookup
, this, _1, _2, node.second)); , this, _1, _2, node.second));
} }

View File

@ -127,7 +127,7 @@ namespace libtorrent {
if (old_prio == 0 && new_prio != 0) if (old_prio == 0 && new_prio != 0)
{ {
// move stuff out of the part file // move stuff out of the part file
file_handle f = open_file(i, open_mode_t::read_write, ec); file_handle f = open_file(i, open_mode::read_write, ec);
if (ec) return; if (ec) return;
need_partfile(); need_partfile();
@ -157,7 +157,7 @@ namespace libtorrent {
if (exists(fp)) if (exists(fp))
new_prio = 1; new_prio = 1;
/* /*
file_handle f = open_file(i, open_mode_t::read_only, ec); file_handle f = open_file(i, open_mode::read_only, ec);
if (ec.ec != boost::system::errc::no_such_file_or_directory) if (ec.ec != boost::system::errc::no_such_file_or_directory)
{ {
if (ec) return; if (ec) return;
@ -260,8 +260,8 @@ namespace libtorrent {
} }
} }
ec.ec.clear(); ec.ec.clear();
file_handle f = open_file(file_index, open_mode_t::read_write file_handle f = open_file(file_index, open_mode::read_write
| open_mode_t::random_access, ec); | open_mode::random_access, ec);
if (ec) if (ec)
{ {
ec.file(file_index); ec.file(file_index);
@ -478,7 +478,7 @@ namespace libtorrent {
} }
file_handle handle = open_file(file_index file_handle handle = open_file(file_index
, open_mode_t::read_only | flags, ec); , open_mode::read_only | flags, ec);
if (ec) return -1; if (ec) return -1;
error_code e; error_code e;
@ -545,7 +545,7 @@ namespace libtorrent {
m_stat_cache.set_dirty(file_index); m_stat_cache.set_dirty(file_index);
file_handle handle = open_file(file_index file_handle handle = open_file(file_index
, open_mode_t::read_write, ec); , open_mode::read_write, ec);
if (ec) return -1; if (ec) return -1;
error_code e; error_code e;
@ -575,7 +575,7 @@ namespace libtorrent {
, open_mode_t mode, storage_error& ec) const , open_mode_t mode, storage_error& ec) const
{ {
file_handle h = open_file_impl(file, mode, ec.ec); file_handle h = open_file_impl(file, mode, ec.ec);
if (((mode & open_mode_t::rw_mask) != open_mode_t::read_only) if (((mode & open_mode::rw_mask) != open_mode::read_only)
&& ec.ec == boost::system::errc::no_such_file_or_directory) && ec.ec == boost::system::errc::no_such_file_or_directory)
{ {
// this means the directory the file is in doesn't exist. // this means the directory the file is in doesn't exist.
@ -603,7 +603,7 @@ namespace libtorrent {
} }
TORRENT_ASSERT(h); TORRENT_ASSERT(h);
if (m_allocate_files && (mode & open_mode_t::rw_mask) != open_mode_t::read_only) if (m_allocate_files && (mode & open_mode::rw_mask) != open_mode::read_only)
{ {
std::unique_lock<std::mutex> l(m_file_created_mutex); std::unique_lock<std::mutex> l(m_file_created_mutex);
if (m_file_created.size() != files().num_files()) if (m_file_created.size() != files().num_files())
@ -638,33 +638,33 @@ namespace libtorrent {
, error_code& ec) const , error_code& ec) const
{ {
bool const lock_files = m_settings ? settings().get_bool(settings_pack::lock_files) : false; bool const lock_files = m_settings ? settings().get_bool(settings_pack::lock_files) : false;
if (lock_files) mode |= open_mode_t::lock_file; if (lock_files) mode |= open_mode::lock_file;
if (!m_allocate_files) mode |= open_mode_t::sparse; if (!m_allocate_files) mode |= open_mode::sparse;
// files with priority 0 should always be sparse // files with priority 0 should always be sparse
if (m_file_priority.end_index() > file && m_file_priority[file] == 0) if (m_file_priority.end_index() > file && m_file_priority[file] == 0)
mode |= open_mode_t::sparse; mode |= open_mode::sparse;
if (m_settings && settings().get_bool(settings_pack::no_atime_storage)) mode |= open_mode_t::no_atime; if (m_settings && settings().get_bool(settings_pack::no_atime_storage)) mode |= open_mode::no_atime;
// if we have a cache already, don't store the data twice by leaving it in the OS cache as well // if we have a cache already, don't store the data twice by leaving it in the OS cache as well
if (m_settings if (m_settings
&& settings().get_int(settings_pack::disk_io_write_mode) && settings().get_int(settings_pack::disk_io_write_mode)
== settings_pack::disable_os_cache) == settings_pack::disable_os_cache)
{ {
mode |= open_mode_t::no_cache; mode |= open_mode::no_cache;
} }
file_handle ret = m_pool.open_file(storage_index(), m_save_path, file file_handle ret = m_pool.open_file(storage_index(), m_save_path, file
, files(), mode, ec); , files(), mode, ec);
if (ec && test(mode & open_mode_t::lock_file)) if (ec && (mode & open_mode::lock_file))
{ {
// we failed to open the file and we're trying to lock it. It's // we failed to open the file and we're trying to lock it. It's
// possible we're failing because we have another handle to this // possible we're failing because we have another handle to this
// file in use (but waiting to be closed). Just retry to open it // file in use (but waiting to be closed). Just retry to open it
// without locking. // without locking.
mode &= ~open_mode_t::lock_file; mode &= ~open_mode::lock_file;
ret = m_pool.open_file(storage_index(), m_save_path, file, files() ret = m_pool.open_file(storage_index(), m_save_path, file, files()
, mode, ec); , mode, ec);
} }

View File

@ -3137,7 +3137,7 @@ namespace libtorrent {
#endif #endif
{ {
ADD_OUTSTANDING_ASYNC("torrent::on_peer_name_lookup"); ADD_OUTSTANDING_ASYNC("torrent::on_peer_name_lookup");
m_ses.get_resolver().async_resolve(i.hostname, resolver_flags::abort_on_shutdown m_ses.get_resolver().async_resolve(i.hostname, resolver_interface::abort_on_shutdown
, std::bind(&torrent::on_peer_name_lookup, shared_from_this(), _1, _2, i.port)); , std::bind(&torrent::on_peer_name_lookup, shared_from_this(), _1, _2, i.port));
} }
} }
@ -5627,7 +5627,7 @@ namespace libtorrent {
// use proxy // use proxy
web->resolving = true; web->resolving = true;
m_ses.get_resolver().async_resolve(ps.hostname, resolver_flags::abort_on_shutdown m_ses.get_resolver().async_resolve(ps.hostname, resolver_interface::abort_on_shutdown
, [self, web, proxy_port](error_code const& e, std::vector<address> const& addrs) , [self, web, proxy_port](error_code const& e, std::vector<address> const& addrs)
{ {
self->wrap(&torrent::on_proxy_name_lookup, e, addrs, web, proxy_port); self->wrap(&torrent::on_proxy_name_lookup, e, addrs, web, proxy_port);
@ -5649,7 +5649,7 @@ namespace libtorrent {
auto self = shared_from_this(); auto self = shared_from_this();
web->resolving = true; web->resolving = true;
m_ses.get_resolver().async_resolve(hostname, resolver_flags::abort_on_shutdown m_ses.get_resolver().async_resolve(hostname, resolver_interface::abort_on_shutdown
, [self, web, port](error_code const& e, std::vector<address> const& addrs) , [self, web, port](error_code const& e, std::vector<address> const& addrs)
{ {
self->wrap(&torrent::on_name_lookup, e, addrs, port, web); self->wrap(&torrent::on_name_lookup, e, addrs, port, web);
@ -5734,7 +5734,7 @@ namespace libtorrent {
auto self = shared_from_this(); auto self = shared_from_this();
web->resolving = true; web->resolving = true;
m_ses.get_resolver().async_resolve(hostname, resolver_flags::abort_on_shutdown m_ses.get_resolver().async_resolve(hostname, resolver_interface::abort_on_shutdown
, [self, web, port](error_code const& err, std::vector<address> const& addr) , [self, web, port](error_code const& err, std::vector<address> const& addr)
{ {
self->wrap(&torrent::on_name_lookup, err, addr, port, web); self->wrap(&torrent::on_name_lookup, err, addr, port, web);

View File

@ -552,7 +552,7 @@ namespace libtorrent {
{ {
ec.clear(); ec.clear();
file f; file f;
if (!f.open(filename, open_mode_t::read_only, ec)) return -1; if (!f.open(filename, open_mode::read_only, ec)) return -1;
std::int64_t s = f.get_size(ec); std::int64_t s = f.get_size(ec);
if (ec) return -1; if (ec) return -1;
v.resize(std::size_t(s)); v.resize(std::size_t(s));

View File

@ -107,8 +107,8 @@ namespace libtorrent {
// don't want to get stuck on DNS lookups when shutting down // don't want to get stuck on DNS lookups when shutting down
m_man.host_resolver().async_resolve(hostname m_man.host_resolver().async_resolve(hostname
, (tracker_req().event == tracker_request::stopped , (tracker_req().event == tracker_request::stopped
? resolver_flags::cache_only : resolver_flags::none) ? resolver_interface::cache_only : resolver_flags{})
| resolver_flags::abort_on_shutdown | resolver_interface::abort_on_shutdown
, std::bind(&udp_tracker_connection::name_lookup , std::bind(&udp_tracker_connection::name_lookup
, shared_from_this(), _1, _2, port)); , shared_from_this(), _1, _2, port));

View File

@ -199,7 +199,7 @@ void generate_files(lt::torrent_info const& ti, std::string const& path
iovec_t b = { &buffer[0], size_t(piece_size) }; iovec_t b = { &buffer[0], size_t(piece_size) };
storage_error ec; storage_error ec;
int ret = st.writev(b, i, 0, open_mode_t::read_only, ec); int ret = st.writev(b, i, 0, open_mode::read_only, ec);
if (ret != piece_size || ec) if (ret != piece_size || ec)
{ {
std::printf("ERROR writing files: (%d expected %d) %s\n" std::printf("ERROR writing files: (%d expected %d) %s\n"

View File

@ -658,7 +658,7 @@ void create_random_files(std::string const& path, const int file_sizes[], int nu
full_path = combine_path(full_path, filename); full_path = combine_path(full_path, filename);
int to_write = file_sizes[i]; int to_write = file_sizes[i];
file f(full_path, open_mode_t::write_only, ec); file f(full_path, open_mode::write_only, ec);
if (ec) std::printf("failed to create file \"%s\": (%d) %s\n" if (ec) std::printf("failed to create file \"%s\": (%d) %s\n"
, full_path.c_str(), ec.value(), ec.message().c_str()); , full_path.c_str(), ec.value(), ec.message().c_str());
std::int64_t offset = 0; std::int64_t offset = 0;

View File

@ -132,7 +132,7 @@ void test_checking(int flags = read_only_files)
path = combine_path(path, name); path = combine_path(path, name);
error_code ec; error_code ec;
file f(path, open_mode_t::read_write, ec); file f(path, open_mode::read_write, ec);
if (ec) std::printf("ERROR: opening file \"%s\": (%d) %s\n" if (ec) std::printf("ERROR: opening file \"%s\": (%d) %s\n"
, path.c_str(), ec.value(), ec.message().c_str()); , path.c_str(), ec.value(), ec.message().c_str());
f.set_size(file_sizes[i] / 2, ec); f.set_size(file_sizes[i] / 2, ec);

View File

@ -52,7 +52,7 @@ int touch_file(std::string const& filename, int size)
file f; file f;
error_code ec; error_code ec;
if (!f.open(filename, open_mode_t::write_only, ec)) return -1; if (!f.open(filename, open_mode::write_only, ec)) return -1;
if (ec) return -1; if (ec) return -1;
iovec_t b = {&v[0], v.size()}; iovec_t b = {&v[0], v.size()};
std::int64_t written = f.writev(0, b, ec); std::int64_t written = f.writev(0, b, ec);
@ -283,9 +283,9 @@ TORRENT_TEST(file)
error_code ec; error_code ec;
file f; file f;
#if TORRENT_USE_UNC_PATHS || !defined _WIN32 #if TORRENT_USE_UNC_PATHS || !defined _WIN32
TEST_CHECK(f.open("con", open_mode_t::read_write, ec)); TEST_CHECK(f.open("con", open_mode::read_write, ec));
#else #else
TEST_CHECK(f.open("test_file", open_mode_t::read_write, ec)); TEST_CHECK(f.open("test_file", open_mode::read_write, ec));
#endif #endif
if (ec) if (ec)
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());
@ -316,7 +316,7 @@ TORRENT_TEST(hard_link)
// read that file and assert we get the same stuff we wrote to the first file // read that file and assert we get the same stuff we wrote to the first file
error_code ec; error_code ec;
file f; file f;
TEST_CHECK(f.open("original_file", open_mode_t::read_write, ec)); TEST_CHECK(f.open("original_file", open_mode::read_write, ec));
if (ec) if (ec)
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());
@ -336,7 +336,7 @@ TORRENT_TEST(hard_link)
TEST_EQUAL(ec, error_code()); TEST_EQUAL(ec, error_code());
TEST_CHECK(f.open("second_link", open_mode_t::read_write, ec)); TEST_CHECK(f.open("second_link", open_mode::read_write, ec));
if (ec) if (ec)
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());
@ -363,7 +363,7 @@ TORRENT_TEST(coalesce_buffer)
{ {
error_code ec; error_code ec;
file f; file f;
TEST_CHECK(f.open("test_file", open_mode_t::read_write, ec)); TEST_CHECK(f.open("test_file", open_mode::read_write, ec));
if (ec) if (ec)
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());
@ -371,7 +371,7 @@ TORRENT_TEST(coalesce_buffer)
char test[] = "test"; char test[] = "test";
char foobar[] = "foobar"; char foobar[] = "foobar";
iovec_t b[2] = {{test, 4}, {foobar, 6}}; iovec_t b[2] = {{test, 4}, {foobar, 6}};
TEST_EQUAL(f.writev(0, b, ec, open_mode_t::coalesce_buffers), 4 + 6); TEST_EQUAL(f.writev(0, b, ec, open_mode::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);

View File

@ -121,7 +121,7 @@ void run_test(std::string const& url, int size, int status, int connected
std::shared_ptr<http_connection> h = std::make_shared<http_connection>(ios std::shared_ptr<http_connection> h = std::make_shared<http_connection>(ios
, res, &::http_handler, true, 1024*1024, &::http_connect_handler); , res, &::http_handler, true, 1024*1024, &::http_connect_handler);
h->get(url, seconds(1), 0, &ps, 5, "test/user-agent", address(address_v4::any()) h->get(url, seconds(1), 0, &ps, 5, "test/user-agent", address(address_v4::any())
, resolver_flags::none, auth); , resolver_flags{}, auth);
ios.reset(); ios.reset();
error_code e; error_code e;
ios.run(e); ios.run(e);
@ -146,7 +146,7 @@ void write_test_file()
std::srand(unsigned(std::time(nullptr))); std::srand(unsigned(std::time(nullptr)));
std::generate(data_buffer, data_buffer + sizeof(data_buffer), &std::rand); std::generate(data_buffer, data_buffer + sizeof(data_buffer), &std::rand);
error_code ec; error_code ec;
file test_file("test_file", open_mode_t::write_only, ec); file test_file("test_file", open_mode::write_only, ec);
TEST_CHECK(!ec); TEST_CHECK(!ec);
if (ec) std::printf("file error: %s\n", ec.message().c_str()); if (ec) std::printf("file error: %s\n", ec.message().c_str());
iovec_t b = { data_buffer, 3216}; iovec_t b = { data_buffer, 3216};

View File

@ -843,23 +843,17 @@ TORRENT_TEST(zero_file_prio)
test_zero_file_prio(); test_zero_file_prio();
} }
enum class test_mode_t struct test_mode_tag;
{ using test_mode_t = flags::bitfield_flag<std::uint8_t, test_mode_tag>;
none = 0,
file_prio = 1,
pieces_have = 2,
piece_prio = 4,
all_files_zero = 8,
deprecated = 16
};
namespace libtorrent { namespace test_mode {
namespace flags { constexpr test_mode_t file_prio{1};
constexpr test_mode_t pieces_have{2};
template <> constexpr test_mode_t piece_prio{4};
struct enable_flag_operators<test_mode_t> : std::true_type {}; constexpr test_mode_t all_files_zero{8};
#ifndef TORRENT_NO_DEPRECATE
} constexpr test_mode_t deprecated{16};
#endif
} }
void test_seed_mode(test_mode_t const flags) void test_seed_mode(test_mode_t const flags)
@ -877,12 +871,12 @@ void test_seed_mode(test_mode_t const flags)
rd["info-hash"] = ti->info_hash().to_string(); rd["info-hash"] = ti->info_hash().to_string();
rd["blocks per piece"] = (std::max)(1, ti->piece_length() / 0x4000); rd["blocks per piece"] = (std::max)(1, ti->piece_length() / 0x4000);
if (test(flags & test_mode_t::file_prio)) if (flags & test_mode::file_prio)
{ {
// this should take it out of seed_mode // this should take it out of seed_mode
entry::list_type& file_prio = rd["file_priority"].list(); entry::list_type& file_prio = rd["file_priority"].list();
file_prio.push_back(entry(0)); file_prio.push_back(entry(0));
if (test(flags & test_mode_t::all_files_zero)) if (flags & test_mode::all_files_zero)
{ {
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
{ {
@ -892,14 +886,14 @@ void test_seed_mode(test_mode_t const flags)
} }
std::string pieces(ti->num_pieces(), '\x01'); std::string pieces(ti->num_pieces(), '\x01');
if (test(flags & test_mode_t::pieces_have)) if (flags & test_mode::pieces_have)
{ {
pieces[0] = '\0'; pieces[0] = '\0';
} }
rd["pieces"] = pieces; rd["pieces"] = pieces;
std::string pieces_prio(ti->num_pieces(), '\x01'); std::string pieces_prio(ti->num_pieces(), '\x01');
if (test(flags & test_mode_t::piece_prio)) if (flags & test_mode::piece_prio)
{ {
pieces_prio[0] = '\0'; pieces_prio[0] = '\0';
} }
@ -911,7 +905,7 @@ void test_seed_mode(test_mode_t const flags)
bencode(back_inserter(resume_data), rd); bencode(back_inserter(resume_data), rd);
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
if (test(flags & test_mode_t::deprecated)) if (flags & test_mode::deprecated)
{ {
p.resume_data = resume_data; p.resume_data = resume_data;
} }
@ -928,9 +922,9 @@ void test_seed_mode(test_mode_t const flags)
torrent_handle h = ses.add_torrent(p); torrent_handle h = ses.add_torrent(p);
torrent_status s = h.status(); torrent_status s = h.status();
if (test(flags & (test_mode_t::file_prio if (flags & (test_mode::file_prio
| test_mode_t::piece_prio | test_mode::piece_prio
| test_mode_t::pieces_have))) | test_mode::pieces_have))
{ {
TEST_EQUAL(s.seed_mode, false); TEST_EQUAL(s.seed_mode, false);
} }
@ -942,43 +936,43 @@ void test_seed_mode(test_mode_t const flags)
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
TORRENT_TEST(seed_mode_file_prio_deprecated) TORRENT_TEST(seed_mode_file_prio_deprecated)
{ {
test_seed_mode(test_mode_t::file_prio | test_mode_t::deprecated); test_seed_mode(test_mode::file_prio | test_mode::deprecated);
} }
TORRENT_TEST(seed_mode_piece_prio_deprecated) TORRENT_TEST(seed_mode_piece_prio_deprecated)
{ {
test_seed_mode(test_mode_t::pieces_have | test_mode_t::deprecated); test_seed_mode(test_mode::pieces_have | test_mode::deprecated);
} }
TORRENT_TEST(seed_mode_piece_have_deprecated) TORRENT_TEST(seed_mode_piece_have_deprecated)
{ {
test_seed_mode(test_mode_t::piece_prio | test_mode_t::deprecated); test_seed_mode(test_mode::piece_prio | test_mode::deprecated);
} }
TORRENT_TEST(seed_mode_preserve_deprecated) TORRENT_TEST(seed_mode_preserve_deprecated)
{ {
test_seed_mode(test_mode_t::deprecated); test_seed_mode(test_mode::deprecated);
} }
#endif #endif
TORRENT_TEST(seed_mode_file_prio) TORRENT_TEST(seed_mode_file_prio)
{ {
test_seed_mode(test_mode_t::file_prio); test_seed_mode(test_mode::file_prio);
} }
TORRENT_TEST(seed_mode_piece_prio) TORRENT_TEST(seed_mode_piece_prio)
{ {
test_seed_mode(test_mode_t::pieces_have); test_seed_mode(test_mode::pieces_have);
} }
TORRENT_TEST(seed_mode_piece_have) TORRENT_TEST(seed_mode_piece_have)
{ {
test_seed_mode(test_mode_t::piece_prio); test_seed_mode(test_mode::piece_prio);
} }
TORRENT_TEST(seed_mode_preserve) TORRENT_TEST(seed_mode_preserve)
{ {
test_seed_mode(test_mode_t::none); test_seed_mode(test_mode_t{});
} }
TORRENT_TEST(resume_save_load) TORRENT_TEST(resume_save_load)

View File

@ -256,50 +256,50 @@ void run_storage_tests(std::shared_ptr<torrent_info> info
// write piece 1 (in slot 0) // write piece 1 (in slot 0)
iovec_t iov = { piece1.data(), half}; iovec_t iov = { piece1.data(), half};
ret = s->writev(iov, piece_index_t(0), 0, open_mode_t::read_write, ec); ret = s->writev(iov, piece_index_t(0), 0, open_mode::read_write, ec);
if (ret != half) print_error("writev", ret, ec); if (ret != half) print_error("writev", ret, ec);
iov = { piece1.data() + half, half }; iov = { piece1.data() + half, half };
ret = s->writev(iov, piece_index_t(0), half, open_mode_t::read_write, ec); ret = s->writev(iov, piece_index_t(0), half, open_mode::read_write, 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 = { piece + 3, piece_size - 9}; iov = { piece + 3, piece_size - 9};
ret = s->readv(iov, piece_index_t(0), 3, open_mode_t::read_write, ec); ret = s->readv(iov, piece_index_t(0), 3, open_mode::read_write, 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 = { piece, piece_size - 9}; iov = { piece, piece_size - 9};
ret = s->readv(iov, piece_index_t(0), 3, open_mode_t::read_write, ec); ret = s->readv(iov, piece_index_t(0), 3, open_mode::read_write, 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 = { piece, piece_size }; iov = { piece, piece_size };
ret = s->readv(iov, piece_index_t(0), 0, open_mode_t::read_write, ec); ret = s->readv(iov, piece_index_t(0), 0, open_mode::read_write, 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 = { piece0.data(), piece_size }; iov = { piece0.data(), piece_size };
ret = s->writev(iov, piece_index_t(1), 0, open_mode_t::read_write, ec); ret = s->writev(iov, piece_index_t(1), 0, open_mode::read_write, ec);
if (ret != piece_size) print_error("writev", ret, ec); if (ret != piece_size) print_error("writev", ret, ec);
iov = { piece2.data(), piece_size }; iov = { piece2.data(), piece_size };
ret = s->writev(iov, piece_index_t(2), 0, open_mode_t::read_write, ec); ret = s->writev(iov, piece_index_t(2), 0, open_mode::read_write, 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 = { piece, piece_size }; iov = { piece, piece_size };
ret = s->readv(iov, piece_index_t(1), 0, open_mode_t::read_write, ec); ret = s->readv(iov, piece_index_t(1), 0, open_mode::read_write, 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 = { piece, piece_size }; iov = { piece, piece_size };
ret = s->readv(iov, piece_index_t(2), 0, open_mode_t::read_write, ec); ret = s->readv(iov, piece_index_t(2), 0, open_mode::read_write, 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()));
@ -351,7 +351,7 @@ void test_remove(std::string const& test_path, bool unbuffered)
iovec_t b = {&buf[0], 4}; iovec_t b = {&buf[0], 4};
storage_error se; storage_error se;
s->writev(b, piece_index_t(2), 0, open_mode_t::read_write, se); s->writev(b, piece_index_t(2), 0, open_mode::read_write, se);
TEST_CHECK(exists(combine_path(test_path, combine_path("temp_storage" TEST_CHECK(exists(combine_path(test_path, combine_path("temp_storage"
, combine_path("folder1", "test2.tmp"))))); , combine_path("folder1", "test2.tmp")))));
@ -362,7 +362,7 @@ void test_remove(std::string const& test_path, bool unbuffered)
, combine_path("folder1", "test2.tmp"))), &st, ec); , combine_path("folder1", "test2.tmp"))), &st, ec);
TEST_EQUAL(st.file_size, 8); TEST_EQUAL(st.file_size, 8);
s->writev(b, piece_index_t(4), 0, open_mode_t::read_write, se); s->writev(b, piece_index_t(4), 0, open_mode::read_write, se);
TEST_CHECK(exists(combine_path(test_path, combine_path("temp_storage" TEST_CHECK(exists(combine_path(test_path, combine_path("temp_storage"
, combine_path("_folder3", combine_path("subfolder", "test5.tmp")))))); , combine_path("_folder3", combine_path("subfolder", "test5.tmp"))))));
@ -1383,7 +1383,7 @@ TORRENT_TEST(move_storage_to_self)
iovec_t const b = {&buf[0], 4}; iovec_t const b = {&buf[0], 4};
storage_error se; storage_error se;
s->writev(b, piece_index_t(1), 0, open_mode_t::read_write, se); s->writev(b, piece_index_t(1), 0, open_mode::read_write, se);
TEST_CHECK(exists(combine_path(test_path, combine_path("folder2", "test3.tmp")))); TEST_CHECK(exists(combine_path(test_path, combine_path("folder2", "test3.tmp"))));
TEST_CHECK(exists(combine_path(test_path, combine_path("_folder3", "test4.tmp")))); TEST_CHECK(exists(combine_path(test_path, combine_path("_folder3", "test4.tmp"))));
@ -1412,7 +1412,7 @@ TORRENT_TEST(move_storage_into_self)
iovec_t const b = {&buf[0], 4}; iovec_t const b = {&buf[0], 4};
storage_error se; storage_error se;
s->writev(b, piece_index_t(2), 0, open_mode_t::read_write, se); s->writev(b, piece_index_t(2), 0, open_mode::read_write, se);
std::string const test_path = combine_path(save_path, combine_path("temp_storage", "folder1")); std::string const test_path = combine_path(save_path, combine_path("temp_storage", "folder1"));
s->move_storage(test_path, move_flags_t::always_replace_files, se); s->move_storage(test_path, move_flags_t::always_replace_files, se);
@ -1458,7 +1458,7 @@ TORRENT_TEST(dont_move_intermingled_files)
iovec_t b = {&buf[0], 4}; iovec_t b = {&buf[0], 4};
storage_error se; storage_error se;
s->writev(b, piece_index_t(2), 0, open_mode_t::read_write, se); s->writev(b, piece_index_t(2), 0, open_mode::read_write, se);
error_code ec; error_code ec;
create_directory(combine_path(save_path, combine_path("temp_storage" create_directory(combine_path(save_path, combine_path("temp_storage"
@ -1466,11 +1466,11 @@ TORRENT_TEST(dont_move_intermingled_files)
TEST_EQUAL(ec, boost::system::errc::success); TEST_EQUAL(ec, boost::system::errc::success);
file f; file f;
f.open(combine_path(save_path, combine_path("temp_storage", "alien1.tmp")) f.open(combine_path(save_path, combine_path("temp_storage", "alien1.tmp"))
, open_mode_t::write_only, ec); , open_mode::write_only, ec);
f.close(); f.close();
TEST_EQUAL(ec, boost::system::errc::success); TEST_EQUAL(ec, boost::system::errc::success);
f.open(combine_path(save_path, combine_path("temp_storage" f.open(combine_path(save_path, combine_path("temp_storage"
, combine_path("folder1", "alien2.tmp"))), open_mode_t::write_only, ec); , combine_path("folder1", "alien2.tmp"))), open_mode::write_only, ec);
f.close(); f.close();
TEST_EQUAL(ec, boost::system::errc::success); TEST_EQUAL(ec, boost::system::errc::success);

View File

@ -50,7 +50,7 @@ TORRENT_TEST(web_seed_redirect)
char random_data[16000]; char random_data[16000];
std::generate(random_data, random_data + sizeof(random_data), random_byte); std::generate(random_data, random_data + sizeof(random_data), random_byte);
file f("test_file", open_mode_t::write_only, ec); file f("test_file", open_mode::write_only, ec);
if (ec) if (ec)
{ {
std::printf("failed to create file \"test_file\": (%d) %s\n" std::printf("failed to create file \"test_file\": (%d) %s\n"