From ffaabd846cc783829f22ab9eba6e9e73650ebe95 Mon Sep 17 00:00:00 2001 From: arvidn Date: Fri, 26 May 2017 14:49:21 -0400 Subject: [PATCH] make file open mode flags be an enum class for type-safety --- examples/connection_tester.cpp | 2 +- include/libtorrent/Makefile.am | 1 + include/libtorrent/file.hpp | 130 +++++++++++++++++-------------- include/libtorrent/file_pool.hpp | 4 +- include/libtorrent/flags.hpp | 89 +++++++++++++++++++++ include/libtorrent/part_file.hpp | 2 +- include/libtorrent/storage.hpp | 12 +-- src/disk_io_thread.cpp | 22 +++--- src/file.cpp | 103 ++++++++++++------------ src/file_pool.cpp | 43 +++++----- src/part_file.cpp | 18 ++--- src/storage.cpp | 46 +++++------ src/torrent_info.cpp | 2 +- test/make_torrent.cpp | 2 +- test/setup_transfer.cpp | 2 +- test/test_block_cache.cpp | 4 +- test/test_checking.cpp | 2 +- test/test_file.cpp | 14 ++-- test/test_http_connection.cpp | 2 +- test/test_storage.cpp | 32 ++++---- test/test_transfer.cpp | 2 +- test/test_web_seed_redirect.cpp | 2 +- 22 files changed, 317 insertions(+), 219 deletions(-) create mode 100644 include/libtorrent/flags.hpp diff --git a/examples/connection_tester.cpp b/examples/connection_tester.cpp index 3262c9d60..b32251244 100644 --- a/examples/connection_tester.cpp +++ b/examples/connection_tester.cpp @@ -869,7 +869,7 @@ void generate_data(char const* path, torrent_info const& ti) iovec_t const b = { reinterpret_cast(piece) , size_t(std::min(left_in_piece, 0x4000))}; storage_error error; - st->writev(b, i, j, 0, error); + st->writev(b, i, j, open_mode_t::write_only, error); if (error) std::fprintf(stderr, "storage error: %s\n", error.ec.message().c_str()); } diff --git a/include/libtorrent/Makefile.am b/include/libtorrent/Makefile.am index e748972fd..0f8385eae 100644 --- a/include/libtorrent/Makefile.am +++ b/include/libtorrent/Makefile.am @@ -51,6 +51,7 @@ nobase_include_HEADERS = \ file_pool.hpp \ file_storage.hpp \ fingerprint.hpp \ + flags.hpp \ fwd.hpp \ gzip.hpp \ hasher.hpp \ diff --git a/include/libtorrent/file.hpp b/include/libtorrent/file.hpp index f63234337..c8fb2b9e9 100644 --- a/include/libtorrent/file.hpp +++ b/include/libtorrent/file.hpp @@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/string_view.hpp" #include "libtorrent/span.hpp" #include "libtorrent/aux_/storage_utils.hpp" +#include "libtorrent/flags.hpp" #include "libtorrent/aux_/disable_warnings_push.hpp" @@ -125,77 +126,86 @@ namespace libtorrent { using file_handle = std::shared_ptr; + // the open mode for files. Used for the file constructor or + // file::open(). + enum class open_mode_t : std::uint32_t + { + none = 0, + + // open the file for reading only + read_only = 0, + + // open the file for writing only + write_only = 1, + + // open the file for reading and writing + read_write = 2, + + // the mask for the bits determining read or write mode + rw_mask = read_only | write_only | read_write, + + // open the file in sparse mode (if supported by the + // filesystem). + sparse = 0x4, + + // don't update the access timestamps on the file (if + // supported by the operating system and filesystem). + // this generally improves disk performance. + no_atime = 0x8, + + // open the file for random access. This disables read-ahead + // logic + random_access = 0x10, + + // prevent the file from being opened by another process + // while it's still being held open by this handle + lock_file = 0x20, + + // don't put any pressure on the OS disk cache + // because of access to this file. We expect our + // files to be fairly large, and there is already + // a cache at the bittorrent block level. This + // may improve overall system performance by + // leaving running applications in the page cache + no_cache = 0x40, + + // this is only used for readv/writev flags + coalesce_buffers = 0x100, + + // when creating a file, set the hidden attribute (windows only) + attribute_hidden = 0x200, + + // when creating a file, set the executable attribute + attribute_executable = 0x400, + + // the mask of all attribute bits + attribute_mask = attribute_hidden | attribute_executable + }; + +namespace flags { + template <> + struct enable_flag_operators : std::true_type {}; +} + + using namespace flags; + struct TORRENT_EXTRA_EXPORT file : boost::noncopyable { - // the open mode for files. Used for the file constructor or - // file::open(). - enum open_mode_t : std::uint32_t - { - // open the file for reading only - read_only = 0, - - // open the file for writing only - write_only = 1, - - // open the file for reading and writing - read_write = 2, - - // the mask for the bits determining read or write mode - rw_mask = read_only | write_only | read_write, - - // open the file in sparse mode (if supported by the - // filesystem). - sparse = 0x4, - - // don't update the access timestamps on the file (if - // supported by the operating system and filesystem). - // this generally improves disk performance. - no_atime = 0x8, - - // open the file for random access. This disables read-ahead - // logic - random_access = 0x10, - - // prevent the file from being opened by another process - // while it's still being held open by this handle - lock_file = 0x20, - - // don't put any pressure on the OS disk cache - // because of access to this file. We expect our - // files to be fairly large, and there is already - // a cache at the bittorrent block level. This - // may improve overall system performance by - // leaving running applications in the page cache - no_cache = 0x40, - - // this is only used for readv/writev flags - coalesce_buffers = 0x100, - - // when creating a file, set the hidden attribute (windows only) - attribute_hidden = 0x200, - - // when creating a file, set the executable attribute - attribute_executable = 0x400, - - // the mask of all attribute bits - attribute_mask = attribute_hidden | attribute_executable - }; - file(); - file(std::string const& p, std::uint32_t m, error_code& ec); + file(std::string const& p, open_mode_t m, error_code& ec); ~file(); - bool open(std::string const& p, std::uint32_t m, error_code& ec); + bool open(std::string const& p, open_mode_t m, error_code& ec); bool is_open() const; void close(); bool set_size(std::int64_t size, error_code& ec); - std::uint32_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 bufs - , error_code& ec, std::uint32_t flags = 0); + , error_code& ec, open_mode_t flags = open_mode_t::none); std::int64_t readv(std::int64_t file_offset, span bufs - , error_code& ec, std::uint32_t flags = 0); + , error_code& ec, open_mode_t flags = open_mode_t::none); std::int64_t get_size(error_code& ec) const; @@ -209,7 +219,7 @@ namespace libtorrent { handle_type m_file_handle; - std::uint32_t m_open_mode; + open_mode_t m_open_mode = open_mode_t::none; #if defined TORRENT_WINDOWS static bool has_manage_volume_privs; #endif diff --git a/include/libtorrent/file_pool.hpp b/include/libtorrent/file_pool.hpp index 54eafb0fc..24593958a 100644 --- a/include/libtorrent/file_pool.hpp +++ b/include/libtorrent/file_pool.hpp @@ -64,7 +64,7 @@ namespace libtorrent { // file_storage ``fs`` opened at save path ``p``. ``m`` is the // file open mode (see file::open_mode_t). file_handle open_file(storage_index_t st, std::string const& p - , file_index_t file_index, file_storage const& fs, std::uint32_t m + , file_index_t file_index, file_storage const& fs, open_mode_t m , error_code& ec); // release all files belonging to the specified storage_interface (``st``) // the overload that takes ``file_index`` releases only the file with @@ -111,7 +111,7 @@ namespace libtorrent { file_handle file_ptr; time_point const opened{aux::time_now()}; time_point last_use{opened}; - std::uint32_t mode = 0; + open_mode_t mode = open_mode_t::none; }; // maps storage pointer, file index pairs to the diff --git a/include/libtorrent/flags.hpp b/include/libtorrent/flags.hpp new file mode 100644 index 000000000..9ffac48b5 --- /dev/null +++ b/include/libtorrent/flags.hpp @@ -0,0 +1,89 @@ +/* + +Copyright (c) 2017, Arvid Norberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef 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 // for enable_if + +namespace libtorrent { +namespace flags { + +template +struct enable_flag_operators : std::false_type {}; + +#define ENUM_OPERATOR(op) \ + template \ + constexpr typename std::enable_if::value, E>::type \ + operator op (E const lhs, E const rhs) { \ + using underlying = typename std::underlying_type::type; \ + return static_cast( \ + static_cast(lhs) op static_cast(rhs)); \ + } \ + \ + template \ + typename std::enable_if::value, E&>::type \ + operator op##= (E& lhs, E const rhs) { \ + using underlying = typename std::underlying_type::type; \ + lhs = static_cast( \ + static_cast(lhs) op static_cast(rhs)); \ + return lhs; \ + } + +ENUM_OPERATOR(|) +ENUM_OPERATOR(&) +ENUM_OPERATOR(^) + + template + constexpr typename std::enable_if::value, E>::type + operator~ (E const operand) { + using underlying = typename std::underlying_type::type; + return static_cast(~static_cast(operand)); + } + + template + constexpr typename std::enable_if::value, bool>::type + test(E const operand) { + using underlying = typename std::underlying_type::type; + return static_cast(operand) != 0; + } + +#undef ENUM_OPERATOR + +} // flags +} // libtorrent + +#endif + diff --git a/include/libtorrent/part_file.hpp b/include/libtorrent/part_file.hpp index 4a7b0fd6d..3353f724d 100644 --- a/include/libtorrent/part_file.hpp +++ b/include/libtorrent/part_file.hpp @@ -76,7 +76,7 @@ namespace libtorrent { private: - void open_file(std::uint32_t mode, error_code& ec); + void open_file(open_mode_t mode, error_code& ec); void flush_metadata_impl(error_code& ec); std::string m_path; diff --git a/include/libtorrent/storage.hpp b/include/libtorrent/storage.hpp index b5c26fb67..8fc9b6413 100644 --- a/include/libtorrent/storage.hpp +++ b/include/libtorrent/storage.hpp @@ -208,9 +208,9 @@ namespace libtorrent { // error. If there's an error, the ``storage_error`` must be filled out // to represent the error that occurred. virtual int readv(span bufs - , piece_index_t piece, int offset, std::uint32_t flags, storage_error& ec) = 0; + , piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) = 0; virtual int writev(span bufs - , piece_index_t piece, int offset, std::uint32_t flags, storage_error& ec) = 0; + , piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) = 0; // This function is called when first checking (or re-checking) the // storage for a torrent. It should return true if any of the files that @@ -398,9 +398,9 @@ namespace libtorrent { virtual bool tick() override; int readv(span bufs - , piece_index_t piece, int offset, std::uint32_t flags, storage_error& ec) override; + , piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) override; int writev(span bufs - , piece_index_t piece, int offset, std::uint32_t flags, storage_error& ec) override; + , piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) override; // if the files in this storage are mapped, returns the mapped // file_storage, otherwise returns the original file_storage object. @@ -424,8 +424,8 @@ namespace libtorrent { mutable stat_cache m_stat_cache; // helper function to open a file in the file pool with the right mode - file_handle open_file(file_index_t file, std::uint32_t mode, storage_error& ec) const; - file_handle open_file_impl(file_index_t file, std::uint32_t mode, error_code& ec) const; + file_handle open_file(file_index_t file, open_mode_t mode, storage_error& ec) const; + file_handle open_file_impl(file_index_t file, open_mode_t mode, error_code& ec) const; aux::vector m_file_priority; std::string m_save_path; diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index 8e4618731..776e12177 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -117,12 +117,12 @@ namespace libtorrent { #endif // DEBUG_DISK_THREAD - std::uint32_t file_flags_for_job(disk_io_job* j + open_mode_t file_flags_for_job(disk_io_job* j , bool const coalesce_buffers) { - std::uint32_t ret = 0; - if (!(j->flags & disk_interface::sequential_access)) ret |= file::random_access; - if (coalesce_buffers) ret |= file::coalesce_buffers; + open_mode_t ret = open_mode_t::none; + if (!(j->flags & disk_interface::sequential_access)) ret |= open_mode_t::random_access; + if (coalesce_buffers) ret |= open_mode_t::coalesce_buffers; return ret; } @@ -664,8 +664,8 @@ namespace libtorrent { DLOG("]\n"); #endif - std::uint32_t const file_flags = m_settings.get_bool(settings_pack::coalesce_writes) - ? file::coalesce_buffers : static_cast(0); + open_mode_t const file_flags = m_settings.get_bool(settings_pack::coalesce_writes) + ? open_mode_t::coalesce_buffers : open_mode_t::none; // issue the actual write operation auto iov_start = iov; @@ -1232,7 +1232,7 @@ namespace libtorrent { time_point const start_time = clock_type::now(); - std::uint32_t const file_flags = file_flags_for_job(j + open_mode_t const file_flags = file_flags_for_job(j , m_settings.get_bool(settings_pack::coalesce_reads)); iovec_t b = {buffer.get(), std::size_t(j->d.io.buffer_size)}; @@ -1308,7 +1308,7 @@ namespace libtorrent { // can remove them. We can now release the cache std::mutex and dive into the // disk operations. - std::uint32_t const file_flags = file_flags_for_job(j + open_mode_t const file_flags = file_flags_for_job(j , m_settings.get_bool(settings_pack::coalesce_reads)); time_point const start_time = clock_type::now(); @@ -1467,7 +1467,7 @@ namespace libtorrent { auto buffer = std::move(boost::get(j->argument)); iovec_t const b = { buffer.get(), std::size_t(j->d.io.buffer_size)}; - std::uint32_t const file_flags = file_flags_for_job(j + open_mode_t const file_flags = file_flags_for_job(j , m_settings.get_bool(settings_pack::coalesce_writes)); m_stats_counters.inc_stats_counter(counters::num_writing_threads, 1); @@ -2155,7 +2155,7 @@ namespace libtorrent { int const piece_size = j->storage->files().piece_size(j->piece); int const block_size = m_disk_cache.block_size(); int const blocks_in_piece = (piece_size + block_size - 1) / block_size; - std::uint32_t const file_flags = file_flags_for_job(j + open_mode_t const file_flags = file_flags_for_job(j , m_settings.get_bool(settings_pack::coalesce_reads)); iovec_t iov = { m_disk_cache.allocate_buffer("hashing") @@ -2200,7 +2200,7 @@ namespace libtorrent { status_t disk_io_thread::do_hash(disk_io_job* j, jobqueue_t& /* completed_jobs */ ) { int const piece_size = j->storage->files().piece_size(j->piece); - std::uint32_t const file_flags = file_flags_for_job(j + open_mode_t const file_flags = file_flags_for_job(j , m_settings.get_bool(settings_pack::coalesce_reads)); std::unique_lock l(m_cache_mutex); diff --git a/src/file.cpp b/src/file.cpp index 673af7c67..e111af7d5 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -326,10 +326,6 @@ done: # endif #endif -static_assert((libtorrent::file::rw_mask & libtorrent::file::sparse) == 0, "internal flags error"); -static_assert((libtorrent::file::rw_mask & libtorrent::file::attribute_mask) == 0, "internal flags error"); -static_assert((libtorrent::file::sparse & libtorrent::file::attribute_mask) == 0, "internal flags error"); - #if defined TORRENT_WINDOWS && defined UNICODE && !TORRENT_USE_WSTRING #ifdef _MSC_VER @@ -342,6 +338,10 @@ static_assert((libtorrent::file::sparse & libtorrent::file::attribute_mask) == 0 namespace libtorrent { +static_assert((open_mode_t::rw_mask & open_mode_t::sparse) == open_mode_t::none, "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_t::sparse & open_mode_t::attribute_mask) == open_mode_t::none, "internal flags error"); + directory::directory(std::string const& path, error_code& ec) : m_done(false) { @@ -505,14 +505,11 @@ namespace libtorrent { bool file::has_manage_volume_privs = get_manage_volume_privs(); #endif - file::file() - : m_file_handle(INVALID_HANDLE_VALUE) - , m_open_mode(0) + file::file() : m_file_handle(INVALID_HANDLE_VALUE) {} - file::file(std::string const& path, std::uint32_t const mode, error_code& ec) + file::file(std::string const& path, open_mode_t const mode, error_code& ec) : m_file_handle(INVALID_HANDLE_VALUE) - , m_open_mode(0) { // the return value is not important, since the // error code contains the same information @@ -524,20 +521,20 @@ namespace libtorrent { close(); } - bool file::open(std::string const& path, std::uint32_t mode, error_code& ec) + bool file::open(std::string const& path, open_mode_t mode, error_code& ec) { close(); native_path_string file_path = convert_to_native_path_string(path); #ifdef TORRENT_WINDOWS - struct open_mode_t + struct win_open_mode_t { DWORD rw_mode; DWORD create_mode; }; - static const open_mode_t mode_array[] = + static std::array const mode_array{ { // read_only {GENERIC_READ, OPEN_EXISTING}, @@ -545,15 +542,15 @@ namespace libtorrent { {GENERIC_WRITE, OPEN_ALWAYS}, // read_write {GENERIC_WRITE | GENERIC_READ, OPEN_ALWAYS}, - }; + }}; - static const DWORD attrib_array[] = + static std::array const attrib_array{ { FILE_ATTRIBUTE_NORMAL, // no attrib FILE_ATTRIBUTE_HIDDEN, // hidden FILE_ATTRIBUTE_NORMAL, // executable FILE_ATTRIBUTE_HIDDEN, // hidden + executable - }; + }}; #if TORRENT_USE_WSTRING #define CreateFile_ CreateFileW @@ -561,21 +558,21 @@ namespace libtorrent { #define CreateFile_ CreateFileA #endif - TORRENT_ASSERT((mode & rw_mask) < sizeof(mode_array)/sizeof(mode_array[0])); - open_mode_t const& m = mode_array[mode & rw_mask]; - DWORD a = attrib_array[(mode & attribute_mask) >> 12]; + TORRENT_ASSERT(static_cast(mode & open_mode_t::rw_mask) < mode_array.size()); + win_open_mode_t const& m = mode_array[static_cast(mode & open_mode_t::rw_mask)]; + DWORD a = attrib_array[static_cast(mode & open_mode_t::attribute_mask) >> 12]; // 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: // http://support.microsoft.com/kb/2549369 - DWORD flags = ((mode & random_access) ? 0 : FILE_FLAG_SEQUENTIAL_SCAN) + DWORD const flags = (test(mode & open_mode_t::random_access) ? 0 : FILE_FLAG_SEQUENTIAL_SCAN) | (a ? a : FILE_ATTRIBUTE_NORMAL) | FILE_FLAG_OVERLAPPED - | ((mode & no_cache) ? FILE_FLAG_WRITE_THROUGH : 0); + | (test(mode & open_mode_t::no_cache) ? FILE_FLAG_WRITE_THROUGH : 0); handle_type handle = CreateFile_(file_path.c_str(), m.rw_mode - , (mode & lock_file) ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE + , test(mode & open_mode_t::lock_file) ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE , 0, m.create_mode, flags, 0); #undef CreateFile_ @@ -591,7 +588,8 @@ namespace libtorrent { // try to make the file sparse if supported // only set this flag if the file is opened for writing - if ((mode & file::sparse) && (mode & rw_mask) != read_only) + if (test(mode & open_mode_t::sparse) + && (mode & open_mode_t::rw_mask) != open_mode_t::read_only) { DWORD temp; overlapped_t ol; @@ -609,7 +607,7 @@ namespace libtorrent { | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - if (mode & attribute_executable) + if (test(mode & open_mode_t::attribute_executable)) permissions |= S_IXGRP | S_IXOTH | S_IXUSR; #ifdef O_BINARY static const int mode_array[] = {O_RDONLY | O_BINARY, O_WRONLY | O_CREAT | O_BINARY, O_RDWR | O_CREAT | O_BINARY}; @@ -619,26 +617,27 @@ namespace libtorrent { int open_mode = 0 #ifdef O_NOATIME - | ((mode & no_atime) ? O_NOATIME : 0) + | (test(mode & open_mode_t::no_atime) ? O_NOATIME : 0) #endif #ifdef O_SYNC - | ((mode & no_cache) ? O_SYNC : 0) + | (test(mode & open_mode_t::no_cache) ? O_SYNC : 0) #endif ; handle_type handle = ::open(file_path.c_str() - , mode_array[mode & rw_mask] | open_mode + , mode_array[static_cast(mode & open_mode_t::rw_mask)] | open_mode , permissions); #ifdef O_NOATIME // O_NOATIME is not allowed for files we don't own // so, if we get EPERM when we try to open with it // try again without O_NOATIME - if (handle == -1 && (mode & no_atime) && errno == EPERM) + if (handle == -1 && test(mode & open_mode_t::no_atime) && errno == EPERM) { - mode &= ~no_atime; + mode &= ~open_mode_t::no_atime; open_mode &= ~O_NOATIME; - handle = ::open(file_path.c_str(), mode_array[mode & rw_mask] | open_mode + handle = ::open(file_path.c_str() + , mode_array[static_cast(mode & open_mode_t::rw_mask)] | open_mode , permissions); } #endif @@ -659,7 +658,7 @@ namespace libtorrent { #ifdef DIRECTIO_ON // for solaris - if (mode & no_cache) + if (test(mode & open_mode_t::no_cache)) { int yes = 1; directio(native_handle(), DIRECTIO_ON); @@ -668,7 +667,7 @@ namespace libtorrent { #ifdef F_NOCACHE // for BSD/Mac - if (mode & no_cache) + if (test(mode & open_mode_t::no_cache)) { int yes = 1; fcntl(native_handle(), F_NOCACHE, &yes); @@ -681,7 +680,7 @@ namespace libtorrent { #endif #ifdef POSIX_FADV_RANDOM - if (mode & random_access) + if (test(mode & open_mode_t::random_access)) { // disable read-ahead posix_fadvise(native_handle(), 0, 0, POSIX_FADV_RANDOM); @@ -758,9 +757,9 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER { // if this file is open for writing, has the sparse // flag set, but there are no sparse regions, unset // the flag - std::uint32_t rw_mode = m_open_mode & rw_mask; - if ((rw_mode != read_only) - && (m_open_mode & sparse) + open_mode_t const rw_mode = m_open_mode & open_mode_t::rw_mask; + if ((rw_mode != open_mode_t::read_only) + && test(m_open_mode & open_mode_t::sparse) && !is_sparse(native_handle())) { overlapped_t ol; @@ -791,7 +790,7 @@ typedef struct _FILE_ALLOCATED_RANGE_BUFFER { m_file_handle = INVALID_HANDLE_VALUE; - m_open_mode = 0; + m_open_mode = open_mode_t::none; } namespace { @@ -974,7 +973,7 @@ namespace { // this has to be thread safe and atomic. i.e. on posix systems it has to be // turned into a series of pread() calls std::int64_t file::readv(std::int64_t file_offset, span bufs - , error_code& ec, std::uint32_t flags) + , error_code& ec, open_mode_t flags) { if (m_file_handle == INVALID_HANDLE_VALUE) { @@ -985,7 +984,8 @@ namespace { #endif return -1; } - TORRENT_ASSERT((m_open_mode & rw_mask) == read_only || (m_open_mode & rw_mask) == read_write); + TORRENT_ASSERT((m_open_mode & open_mode_t::rw_mask) == open_mode_t::read_only + || (m_open_mode & open_mode_t::rw_mask) == open_mode_t::read_write); TORRENT_ASSERT(!bufs.empty()); TORRENT_ASSERT(is_open()); @@ -997,16 +997,16 @@ namespace { // there's no point in coalescing single buffer writes if (bufs.size() == 1) { - flags &= ~file::coalesce_buffers; + flags &= ~open_mode_t::coalesce_buffers; } iovec_t tmp; span tmp_bufs = bufs; - if ((flags & file::coalesce_buffers)) + if (test(flags & open_mode_t::coalesce_buffers)) { if (!coalesce_read_buffers(tmp_bufs, tmp)) // ok, that failed, don't coalesce this read - flags &= ~file::coalesce_buffers; + flags &= ~open_mode_t::coalesce_buffers; } #if TORRENT_USE_PREAD @@ -1015,7 +1015,7 @@ namespace { std::int64_t ret = iov(&::read, native_handle(), file_offset, tmp_bufs, ec); #endif - if ((flags & file::coalesce_buffers)) + if (test(flags & open_mode_t::coalesce_buffers)) coalesce_read_buffers_end(bufs , tmp.data(), !ec); @@ -1027,7 +1027,7 @@ namespace { // that means, on posix this has to be turned into a series of // pwrite() calls std::int64_t file::writev(std::int64_t file_offset, span bufs - , error_code& ec, std::uint32_t flags) + , error_code& ec, open_mode_t flags) { if (m_file_handle == INVALID_HANDLE_VALUE) { @@ -1038,7 +1038,8 @@ namespace { #endif return -1; } - TORRENT_ASSERT((m_open_mode & rw_mask) == write_only || (m_open_mode & rw_mask) == read_write); + TORRENT_ASSERT((m_open_mode & open_mode_t::rw_mask) == open_mode_t::write_only + || (m_open_mode & open_mode_t::rw_mask) == open_mode_t::read_write); TORRENT_ASSERT(!bufs.empty()); TORRENT_ASSERT(is_open()); @@ -1053,15 +1054,15 @@ namespace { // there's no point in coalescing single buffer writes if (bufs.size() == 1) { - flags &= ~file::coalesce_buffers; + flags &= ~open_mode_t::coalesce_buffers; } iovec_t tmp; - if (flags & file::coalesce_buffers) + if (test(flags & open_mode_t::coalesce_buffers)) { if (!coalesce_write_buffers(bufs, tmp)) // ok, that failed, don't coalesce writes - flags &= ~file::coalesce_buffers; + flags &= ~open_mode_t::coalesce_buffers; } #if TORRENT_USE_PREAD @@ -1070,14 +1071,14 @@ namespace { std::int64_t ret = iov(&::write, native_handle(), file_offset, bufs, ec); #endif - if (flags & file::coalesce_buffers) + if (test(flags & open_mode_t::coalesce_buffers)) delete[] tmp.data(); #endif #if TORRENT_USE_FDATASYNC \ && !defined F_NOCACHE && \ !defined DIRECTIO_ON - if (m_open_mode & no_cache) + if (test(m_open_mode & open_mode_t::no_cache)) { if (fdatasync(native_handle()) != 0 && errno != EINVAL @@ -1192,7 +1193,7 @@ namespace { } #if _WIN32_WINNT >= 0x0600 // only if Windows Vista or newer - if ((m_open_mode & sparse) == 0) + if (!test(m_open_mode & open_mode_t::sparse)) { typedef DWORD (WINAPI *GetFileInformationByHandleEx_t)(HANDLE hFile , FILE_INFO_BY_HANDLE_CLASS FileInformationClass @@ -1247,7 +1248,7 @@ namespace { // is less than the file size. Otherwise we would just // update the modification time of the file for no good // reason. - if ((m_open_mode & sparse) == 0 + if (!test(m_open_mode & open_mode_t::sparse) && std::int64_t(st.st_blocks) < (s + st.st_blksize - 1) / st.st_blksize) { // How do we know that the file is already allocated? diff --git a/src/file_pool.cpp b/src/file_pool.cpp index 18da455ba..c57f53bee 100644 --- a/src/file_pool.cpp +++ b/src/file_pool.cpp @@ -99,7 +99,7 @@ namespace libtorrent { file_handle file_pool::open_file(storage_index_t st, std::string const& p , file_index_t const file_index, file_storage const& fs - , std::uint32_t const m, error_code& ec) + , open_mode_t const m, error_code& ec) { // potentially used to hold a reference to a file object that's // about to be destructed. If we have such object we assign it to @@ -119,8 +119,8 @@ namespace libtorrent { #endif TORRENT_ASSERT(is_complete(p)); - TORRENT_ASSERT((m & file::rw_mask) == file::read_only - || (m & file::rw_mask) == file::read_write); + TORRENT_ASSERT((m & open_mode_t::rw_mask) == open_mode_t::read_only + || (m & open_mode_t::rw_mask) == open_mode_t::read_write); auto const i = m_files.find(std::make_pair(st, file_index)); if (i != m_files.end()) { @@ -130,9 +130,9 @@ namespace libtorrent { // if we asked for a file in write mode, // and the cached file is is not opened in // write mode, re-open it - if ((((e.mode & file::rw_mask) != file::read_write) - && ((m & file::rw_mask) == file::read_write)) - || (e.mode & file::random_access) != (m & file::random_access)) + if ((((e.mode & open_mode_t::rw_mask) != open_mode_t::read_write) + && ((m & open_mode_t::rw_mask) == open_mode_t::read_write)) + || (e.mode & open_mode_t::random_access) != (m & open_mode_t::random_access)) { file_handle new_file = std::make_shared(); @@ -182,26 +182,23 @@ namespace libtorrent { namespace { - std::uint32_t to_file_open_mode(std::uint32_t const mode) + std::uint32_t to_file_open_mode(open_mode_t const mode) { std::uint32_t ret = 0; - switch (mode & file::rw_mask) - { - case file::read_only: - ret = file_open_mode::read_only; - break; - case file::write_only: - ret = file_open_mode::write_only; - break; - case file::read_write: - ret = file_open_mode::read_write; - break; - } + open_mode_t const rw_mode = mode & open_mode_t::rw_mask; - if (mode & file::sparse) ret |= file_open_mode::sparse; - if (mode & file::no_atime) ret |= file_open_mode::no_atime; - if (mode & file::random_access) ret |= file_open_mode::random_access; - if (mode & file::lock_file) ret |= file_open_mode::locked; + ret = (rw_mode == open_mode_t::read_only) + ? file_open_mode::read_only + : (rw_mode == open_mode_t::write_only) + ? file_open_mode::write_only + : (rw_mode == open_mode_t::read_write) + ? file_open_mode::read_write + : 0; + + if (test(mode & open_mode_t::sparse)) ret |= file_open_mode::sparse; + if (test(mode & open_mode_t::no_atime)) ret |= file_open_mode::no_atime; + if (test(mode & open_mode_t::random_access)) ret |= file_open_mode::random_access; + if (test(mode & open_mode_t::lock_file)) ret |= file_open_mode::locked; return ret; } diff --git a/src/part_file.cpp b/src/part_file.cpp index f97c4e537..1d5f9c7f6 100644 --- a/src/part_file.cpp +++ b/src/part_file.cpp @@ -92,7 +92,7 @@ namespace libtorrent { error_code ec; std::string fn = combine_path(m_path, m_name); - m_file.open(fn, file::read_only, ec); + m_file.open(fn, open_mode_t::read_only, ec); if (ec) return; // parse header @@ -178,7 +178,7 @@ namespace libtorrent { TORRENT_ASSERT(offset >= 0); std::unique_lock l(m_mutex); - open_file(file::read_write, ec); + open_file(open_mode_t::read_write, ec); if (ec) return -1; auto const i = m_piece_map.find(piece); @@ -206,7 +206,7 @@ namespace libtorrent { } slot_index_t const slot = i->second; - open_file(file::read_write, ec); + open_file(open_mode_t::read_write, ec); if (ec) return -1; l.unlock(); @@ -215,15 +215,15 @@ namespace libtorrent { return int(m_file.readv(slot_offset + offset, bufs, ec)); } - void part_file::open_file(std::uint32_t const mode, error_code& ec) + void part_file::open_file(open_mode_t const mode, error_code& ec) { if (m_file.is_open() - && ((m_file.open_mode() & file::rw_mask) == mode - || mode == file::read_only)) return; + && ((m_file.open_mode() & open_mode_t::rw_mask) == mode + || mode == open_mode_t::read_only)) return; std::string fn = combine_path(m_path, m_name); m_file.open(fn, mode, ec); - if (((mode & file::rw_mask) != file::read_only) + if (((mode & open_mode_t::rw_mask) != open_mode_t::read_only) && ec == boost::system::errc::no_such_file_or_directory) { // this means the directory the file is in doesn't exist. @@ -301,7 +301,7 @@ namespace libtorrent { if (i != m_piece_map.end()) { slot_index_t const slot = i->second; - open_file(file::read_only, ec); + open_file(open_mode_t::read_only, ec); if (ec) return; if (!buf) buf.reset(new char[m_piece_size]); @@ -375,7 +375,7 @@ namespace libtorrent { return; } - open_file(file::read_write, ec); + open_file(open_mode_t::read_write, ec); if (ec) return; std::vector header(static_cast(m_header_size)); diff --git a/src/storage.cpp b/src/storage.cpp index 7ca60197e..fa3793d77 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -135,7 +135,7 @@ namespace libtorrent { if (old_prio == 0 && new_prio != 0) { // move stuff out of the part file - file_handle f = open_file(i, file::read_write, ec); + file_handle f = open_file(i, open_mode_t::read_write, ec); if (ec) return; need_partfile(); @@ -165,7 +165,7 @@ namespace libtorrent { if (exists(fp)) new_prio = 1; /* - file_handle f = open_file(i, file::read_only, ec); + file_handle f = open_file(i, open_mode_t::read_only, ec); if (ec.ec != boost::system::errc::no_such_file_or_directory) { if (ec) return; @@ -272,8 +272,8 @@ namespace libtorrent { } } ec.ec.clear(); - file_handle f = open_file(file_index, file::read_write - | file::random_access, ec); + file_handle f = open_file(file_index, open_mode_t::read_write + | open_mode_t::random_access, ec); if (ec) { ec.file(file_index); @@ -467,7 +467,7 @@ namespace libtorrent { int default_storage::readv(span bufs , piece_index_t const piece, int const offset - , std::uint32_t const flags, storage_error& error) + , open_mode_t const flags, storage_error& error) { #ifdef TORRENT_SIMULATE_SLOW_READ std::this_thread::sleep_for(seconds(1)); @@ -506,7 +506,7 @@ namespace libtorrent { } file_handle handle = open_file(file_index - , file::read_only | flags, ec); + , open_mode_t::read_only | flags, ec); if (ec) return -1; error_code e; @@ -534,7 +534,7 @@ namespace libtorrent { int default_storage::writev(span bufs , piece_index_t const piece, int const offset - , std::uint32_t const flags, storage_error& error) + , open_mode_t const flags, storage_error& error) { return readwritev(files(), bufs, piece, offset, error , [this, flags](file_index_t const file_index @@ -573,7 +573,7 @@ namespace libtorrent { m_stat_cache.set_dirty(file_index); file_handle handle = open_file(file_index - , file::read_write, ec); + , open_mode_t::read_write, ec); if (ec) return -1; error_code e; @@ -600,10 +600,10 @@ namespace libtorrent { } file_handle default_storage::open_file(file_index_t const file - , std::uint32_t mode, storage_error& ec) const + , open_mode_t mode, storage_error& ec) const { file_handle h = open_file_impl(file, mode, ec.ec); - if (((mode & file::rw_mask) != file::read_only) + if (((mode & open_mode_t::rw_mask) != open_mode_t::read_only) && ec.ec == boost::system::errc::no_such_file_or_directory) { // this means the directory the file is in doesn't exist. @@ -631,7 +631,7 @@ namespace libtorrent { } TORRENT_ASSERT(h); - if (m_allocate_files && (mode & file::rw_mask) != file::read_only) + if (m_allocate_files && (mode & open_mode_t::rw_mask) != open_mode_t::read_only) { std::unique_lock l(m_file_created_mutex); if (m_file_created.size() != files().num_files()) @@ -662,37 +662,37 @@ namespace libtorrent { return h; } - file_handle default_storage::open_file_impl(file_index_t file, std::uint32_t mode + file_handle default_storage::open_file_impl(file_index_t file, open_mode_t mode , error_code& ec) const { bool const lock_files = m_settings ? settings().get_bool(settings_pack::lock_files) : false; - if (lock_files) mode |= file::lock_file; + if (lock_files) mode |= open_mode_t::lock_file; - if (!m_allocate_files) mode |= file::sparse; + if (!m_allocate_files) mode |= open_mode_t::sparse; // files with priority 0 should always be sparse if (m_file_priority.end_index() > file && m_file_priority[file] == 0) - mode |= file::sparse; + mode |= open_mode_t::sparse; - if (m_settings && settings().get_bool(settings_pack::no_atime_storage)) mode |= file::no_atime; + if (m_settings && settings().get_bool(settings_pack::no_atime_storage)) mode |= open_mode_t::no_atime; // if we have a cache already, don't store the data twice by leaving it in the OS cache as well if (m_settings && settings().get_int(settings_pack::disk_io_write_mode) == settings_pack::disable_os_cache) { - mode |= file::no_cache; + mode |= open_mode_t::no_cache; } file_handle ret = m_pool.open_file(storage_index(), m_save_path, file , files(), mode, ec); - if (ec && (mode & file::lock_file)) + if (ec && test(mode & open_mode_t::lock_file)) { // 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 // file in use (but waiting to be closed). Just retry to open it // without locking. - mode &= ~file::lock_file; + mode &= ~open_mode_t::lock_file; ret = m_pool.open_file(storage_index(), m_save_path, file, files() , mode, ec); } @@ -740,12 +740,12 @@ namespace { status_t move_storage(std::string const&, int, storage_error&) override { return status_t::no_error; } int readv(span bufs - , piece_index_t, int, std::uint32_t, storage_error&) override + , piece_index_t, int, open_mode_t, storage_error&) override { return bufs_size(bufs); } int writev(span bufs - , piece_index_t, int, std::uint32_t, storage_error&) override + , piece_index_t, int, open_mode_t, storage_error&) override { return bufs_size(bufs); } @@ -773,7 +773,7 @@ namespace { void initialize(storage_error&) override {} int readv(span bufs - , piece_index_t, int, std::uint32_t, storage_error&) override + , piece_index_t, int, open_mode_t, storage_error&) override { int ret = 0; for (auto const& b : bufs) @@ -784,7 +784,7 @@ namespace { return 0; } int writev(span bufs - , piece_index_t, int, std::uint32_t, storage_error&) override + , piece_index_t, int, open_mode_t, storage_error&) override { int ret = 0; for (auto const& b : bufs) diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index f48b48de8..6f054af70 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -552,7 +552,7 @@ namespace libtorrent { { ec.clear(); file f; - if (!f.open(filename, file::read_only, ec)) return -1; + if (!f.open(filename, open_mode_t::read_only, ec)) return -1; std::int64_t s = f.get_size(ec); if (ec) return -1; v.resize(std::size_t(s)); diff --git a/test/make_torrent.cpp b/test/make_torrent.cpp index 30aedc78e..37e9283f9 100644 --- a/test/make_torrent.cpp +++ b/test/make_torrent.cpp @@ -192,7 +192,7 @@ void generate_files(lt::torrent_info const& ti, std::string const& path iovec_t b = { &buffer[0], size_t(piece_size) }; storage_error ec; - int ret = st.writev(b, i, 0, 0, ec); + int ret = st.writev(b, i, 0, open_mode_t::read_only, ec); if (ret != piece_size || ec) { std::printf("ERROR writing files: (%d expected %d) %s\n" diff --git a/test/setup_transfer.cpp b/test/setup_transfer.cpp index e89c30b53..e093341e2 100644 --- a/test/setup_transfer.cpp +++ b/test/setup_transfer.cpp @@ -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); int to_write = file_sizes[i]; - file f(full_path, file::write_only, ec); + file f(full_path, open_mode_t::write_only, ec); if (ec) std::printf("failed to create file \"%s\": (%d) %s\n" , full_path.c_str(), ec.value(), ec.message().c_str()); std::int64_t offset = 0; diff --git a/test/test_block_cache.cpp b/test/test_block_cache.cpp index 06b6b04cc..d6aa7599d 100644 --- a/test/test_block_cache.cpp +++ b/test/test_block_cache.cpp @@ -51,12 +51,12 @@ struct test_storage_impl : storage_interface void initialize(storage_error& ec) override {} int readv(span bufs - , piece_index_t piece, int offset, std::uint32_t flags, storage_error& ec) override + , piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) override { return bufs_size(bufs); } int writev(span bufs - , piece_index_t piece, int offset, std::uint32_t flags, storage_error& ec) override + , piece_index_t piece, int offset, open_mode_t flags, storage_error& ec) override { return bufs_size(bufs); } diff --git a/test/test_checking.cpp b/test/test_checking.cpp index 84d632ac7..3451c4a36 100644 --- a/test/test_checking.cpp +++ b/test/test_checking.cpp @@ -132,7 +132,7 @@ void test_checking(int flags = read_only_files) path = combine_path(path, name); error_code ec; - file f(path, file::read_write, ec); + file f(path, open_mode_t::read_write, ec); if (ec) std::printf("ERROR: opening file \"%s\": (%d) %s\n" , path.c_str(), ec.value(), ec.message().c_str()); f.set_size(file_sizes[i] / 2, ec); diff --git a/test/test_file.cpp b/test/test_file.cpp index 63991bc75..5e0b496ac 100644 --- a/test/test_file.cpp +++ b/test/test_file.cpp @@ -52,7 +52,7 @@ int touch_file(std::string const& filename, int size) file f; error_code ec; - if (!f.open(filename, file::write_only, ec)) return -1; + if (!f.open(filename, open_mode_t::write_only, ec)) return -1; if (ec) return -1; iovec_t b = {&v[0], v.size()}; std::int64_t written = f.writev(0, b, ec); @@ -283,9 +283,9 @@ TORRENT_TEST(file) error_code ec; file f; #if TORRENT_USE_UNC_PATHS || !defined _WIN32 - TEST_CHECK(f.open("con", file::read_write, ec)); + TEST_CHECK(f.open("con", open_mode_t::read_write, ec)); #else - TEST_CHECK(f.open("test_file", file::read_write, ec)); + TEST_CHECK(f.open("test_file", open_mode_t::read_write, ec)); #endif if (ec) 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 error_code ec; file f; - TEST_CHECK(f.open("original_file", file::read_write, ec)); + TEST_CHECK(f.open("original_file", open_mode_t::read_write, ec)); if (ec) std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); TEST_EQUAL(ec, error_code()); @@ -336,7 +336,7 @@ TORRENT_TEST(hard_link) TEST_EQUAL(ec, error_code()); - TEST_CHECK(f.open("second_link", file::read_write, ec)); + TEST_CHECK(f.open("second_link", open_mode_t::read_write, ec)); if (ec) std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); TEST_EQUAL(ec, error_code()); @@ -363,7 +363,7 @@ TORRENT_TEST(coalesce_buffer) { error_code ec; file f; - TEST_CHECK(f.open("test_file", file::read_write, ec)); + TEST_CHECK(f.open("test_file", open_mode_t::read_write, ec)); if (ec) std::printf("open failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); TEST_EQUAL(ec, error_code()); @@ -371,7 +371,7 @@ TORRENT_TEST(coalesce_buffer) char test[] = "test"; char foobar[] = "foobar"; iovec_t b[2] = {{test, 4}, {foobar, 6}}; - TEST_EQUAL(f.writev(0, b, ec, file::coalesce_buffers), 4 + 6); + TEST_EQUAL(f.writev(0, b, ec, open_mode_t::coalesce_buffers), 4 + 6); if (ec) std::printf("writev failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); TEST_CHECK(!ec); diff --git a/test/test_http_connection.cpp b/test/test_http_connection.cpp index 559252afc..539c031c1 100644 --- a/test/test_http_connection.cpp +++ b/test/test_http_connection.cpp @@ -146,7 +146,7 @@ void write_test_file() std::srand(unsigned(std::time(nullptr))); std::generate(data_buffer, data_buffer + sizeof(data_buffer), &std::rand); error_code ec; - file test_file("test_file", file::write_only, ec); + file test_file("test_file", open_mode_t::write_only, ec); TEST_CHECK(!ec); if (ec) std::printf("file error: %s\n", ec.message().c_str()); iovec_t b = { data_buffer, 3216}; diff --git a/test/test_storage.cpp b/test/test_storage.cpp index d79c61171..316105958 100644 --- a/test/test_storage.cpp +++ b/test/test_storage.cpp @@ -242,50 +242,50 @@ void run_storage_tests(std::shared_ptr info // write piece 1 (in slot 0) iovec_t iov = { piece1.data(), half}; - ret = s->writev(iov, piece_index_t(0), 0, 0, ec); + ret = s->writev(iov, piece_index_t(0), 0, open_mode_t::read_write, ec); if (ret != half) print_error("writev", ret, ec); iov = { piece1.data() + half, half }; - ret = s->writev(iov, piece_index_t(0), half, 0, ec); + ret = s->writev(iov, piece_index_t(0), half, open_mode_t::read_write, ec); if (ret != half) print_error("writev", ret, ec); // test unaligned read (where the bytes are aligned) iov = { piece + 3, piece_size - 9}; - ret = s->readv(iov, piece_index_t(0), 3, 0, ec); + ret = s->readv(iov, piece_index_t(0), 3, open_mode_t::read_write, 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 unaligned read (where the bytes are not aligned) iov = { piece, piece_size - 9}; - ret = s->readv(iov, piece_index_t(0), 3, 0, ec); + ret = s->readv(iov, piece_index_t(0), 3, open_mode_t::read_write, ec); TEST_CHECK(ret == piece_size - 9); if (ret != piece_size - 9) print_error("readv", ret, ec); TEST_CHECK(std::equal(piece, piece + piece_size-9, piece1.data()+3)); // verify piece 1 iov = { piece, piece_size }; - ret = s->readv(iov, piece_index_t(0), 0, 0, ec); + ret = s->readv(iov, piece_index_t(0), 0, open_mode_t::read_write, ec); TEST_CHECK(ret == piece_size); if (ret != piece_size) print_error("readv", ret, ec); TEST_CHECK(std::equal(piece, piece + piece_size, piece1.data())); // do the same with piece 0 and 2 (in slot 1 and 2) iov = { piece0.data(), piece_size }; - ret = s->writev(iov, piece_index_t(1), 0, 0, ec); + ret = s->writev(iov, piece_index_t(1), 0, open_mode_t::read_write, ec); if (ret != piece_size) print_error("writev", ret, ec); iov = { piece2.data(), piece_size }; - ret = s->writev(iov, piece_index_t(2), 0, 0, ec); + ret = s->writev(iov, piece_index_t(2), 0, open_mode_t::read_write, ec); if (ret != piece_size) print_error("writev", ret, ec); // verify piece 0 and 2 iov = { piece, piece_size }; - ret = s->readv(iov, piece_index_t(1), 0, 0, ec); + ret = s->readv(iov, piece_index_t(1), 0, open_mode_t::read_write, ec); if (ret != piece_size) print_error("readv", ret, ec); TEST_CHECK(std::equal(piece, piece + piece_size, piece0.data())); iov = { piece, piece_size }; - ret = s->readv(iov, piece_index_t(2), 0, 0, ec); + ret = s->readv(iov, piece_index_t(2), 0, open_mode_t::read_write, ec); if (ret != piece_size) print_error("readv", ret, ec); TEST_CHECK(std::equal(piece, piece + piece_size, piece2.data())); @@ -337,7 +337,7 @@ void test_remove(std::string const& test_path, bool unbuffered) iovec_t b = {&buf[0], 4}; storage_error se; - s->writev(b, piece_index_t(2), 0, 0, se); + s->writev(b, piece_index_t(2), 0, open_mode_t::read_write, se); TEST_CHECK(exists(combine_path(test_path, combine_path("temp_storage" , combine_path("folder1", "test2.tmp"))))); @@ -348,7 +348,7 @@ void test_remove(std::string const& test_path, bool unbuffered) , combine_path("folder1", "test2.tmp"))), &st, ec); TEST_EQUAL(st.file_size, 8); - s->writev(b, piece_index_t(4), 0, 0, se); + s->writev(b, piece_index_t(4), 0, open_mode_t::read_write, se); TEST_CHECK(exists(combine_path(test_path, combine_path("temp_storage" , combine_path("_folder3", combine_path("subfolder", "test5.tmp")))))); @@ -1362,7 +1362,7 @@ TORRENT_TEST(move_storage_to_self) iovec_t const b = {&buf[0], 4}; storage_error se; - s->writev(b, piece_index_t(1), 0, 0, se); + s->writev(b, piece_index_t(1), 0, open_mode_t::read_write, se); TEST_CHECK(exists(combine_path(test_path, combine_path("folder2", "test3.tmp")))); TEST_CHECK(exists(combine_path(test_path, combine_path("_folder3", "test4.tmp")))); @@ -1391,7 +1391,7 @@ TORRENT_TEST(move_storage_into_self) iovec_t const b = {&buf[0], 4}; storage_error se; - s->writev(b, piece_index_t(2), 0, 0, se); + s->writev(b, piece_index_t(2), 0, open_mode_t::read_write, se); std::string const test_path = combine_path(save_path, combine_path("temp_storage", "folder1")); s->move_storage(test_path, 0, se); @@ -1437,7 +1437,7 @@ TORRENT_TEST(dont_move_intermingled_files) iovec_t b = {&buf[0], 4}; storage_error se; - s->writev(b, piece_index_t(2), 0, 0, se); + s->writev(b, piece_index_t(2), 0, open_mode_t::read_write, se); error_code ec; create_directory(combine_path(save_path, combine_path("temp_storage" @@ -1445,11 +1445,11 @@ TORRENT_TEST(dont_move_intermingled_files) TEST_EQUAL(ec, boost::system::errc::success); file f; f.open(combine_path(save_path, combine_path("temp_storage", "alien1.tmp")) - , file::write_only, ec); + , open_mode_t::write_only, ec); f.close(); TEST_EQUAL(ec, boost::system::errc::success); f.open(combine_path(save_path, combine_path("temp_storage" - , combine_path("folder1", "alien2.tmp"))), file::write_only, ec); + , combine_path("folder1", "alien2.tmp"))), open_mode_t::write_only, ec); f.close(); TEST_EQUAL(ec, boost::system::errc::success); diff --git a/test/test_transfer.cpp b/test/test_transfer.cpp index 6d6e0aa0a..a6bf9e473 100644 --- a/test/test_transfer.cpp +++ b/test/test_transfer.cpp @@ -89,7 +89,7 @@ struct test_storage : default_storage span bufs , piece_index_t piece_index , int offset - , std::uint32_t const flags + , open_mode_t const flags , storage_error& se) override { std::unique_lock l(m_mutex); diff --git a/test/test_web_seed_redirect.cpp b/test/test_web_seed_redirect.cpp index 2358867a5..1f6774ade 100644 --- a/test/test_web_seed_redirect.cpp +++ b/test/test_web_seed_redirect.cpp @@ -50,7 +50,7 @@ TORRENT_TEST(web_seed_redirect) char random_data[16000]; std::generate(random_data, random_data + sizeof(random_data), random_byte); - file f("test_file", file::write_only, ec); + file f("test_file", open_mode_t::write_only, ec); if (ec) { std::printf("failed to create file \"test_file\": (%d) %s\n"