From 8f0cf7e1a9f196f9cdbfd029f82612b334fa17ac Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 25 Jul 2018 09:10:34 +0200 Subject: [PATCH] some refactor to reduce duplicate code --- include/libtorrent/Makefile.am | 1 + include/libtorrent/aux_/array.hpp | 52 +------ include/libtorrent/aux_/container_wrapper.hpp | 137 ++++++++++++++++++ include/libtorrent/aux_/deque.hpp | 85 +---------- include/libtorrent/aux_/vector.hpp | 102 +------------ src/file.cpp | 44 +++--- src/proxy_settings.cpp | 43 +++--- 7 files changed, 183 insertions(+), 281 deletions(-) create mode 100644 include/libtorrent/aux_/container_wrapper.hpp diff --git a/include/libtorrent/Makefile.am b/include/libtorrent/Makefile.am index 9a8df6104..0901ff635 100644 --- a/include/libtorrent/Makefile.am +++ b/include/libtorrent/Makefile.am @@ -166,6 +166,7 @@ nobase_include_HEADERS = \ aux_/aligned_union.hpp \ aux_/bind_to_device.hpp \ aux_/block_cache_reference.hpp \ + aux_/container_wrapper.hpp \ aux_/cpuid.hpp \ aux_/disable_warnings_push.hpp \ aux_/disable_warnings_pop.hpp \ diff --git a/include/libtorrent/aux_/array.hpp b/include/libtorrent/aux_/array.hpp index 539b42d25..5ec7b7599 100644 --- a/include/libtorrent/aux_/array.hpp +++ b/include/libtorrent/aux_/array.hpp @@ -35,60 +35,12 @@ POSSIBILITY OF SUCH DAMAGE. #include -#include "libtorrent/units.hpp" -#include "libtorrent/assert.hpp" -#include "libtorrent/index_range.hpp" +#include "libtorrent/aux_/container_wrapper.hpp" namespace libtorrent { namespace aux { template - struct array : std::array - { - using base = std::array; - using underlying_index = typename underlying_index_t::type; - - static_assert(Size <= std::size_t((std::numeric_limits::max)()) - , "size is to big for index type"); - - array() = default; - explicit array(std::array&& arr) : base(arr) {} - - auto operator[](IndexType idx) const -> -#if TORRENT_AUTO_RETURN_TYPES - decltype(auto) -#else - decltype(this->base::operator[](underlying_index())) -#endif - { - TORRENT_ASSERT(idx >= IndexType(0)); - TORRENT_ASSERT(idx < end_index()); - return this->base::operator[](std::size_t(static_cast(idx))); - } - - auto operator[](IndexType idx) -> -#if TORRENT_AUTO_RETURN_TYPES - decltype(auto) -#else - decltype(this->base::operator[](underlying_index())) -#endif - { - TORRENT_ASSERT(idx >= IndexType(0)); - TORRENT_ASSERT(idx < end_index()); - return this->base::operator[](std::size_t(static_cast(idx))); - } - - constexpr IndexType end_index() const - { - return IndexType(static_cast(Size)); - } - - // returns an object that can be used in a range-for to iterate over all - // indices - constexpr index_range range() const noexcept - { - return {IndexType{0}, end_index()}; - } - }; + using array = container_wrapper>; }} diff --git a/include/libtorrent/aux_/container_wrapper.hpp b/include/libtorrent/aux_/container_wrapper.hpp new file mode 100644 index 000000000..837e04cf2 --- /dev/null +++ b/include/libtorrent/aux_/container_wrapper.hpp @@ -0,0 +1,137 @@ +/* + +Copyright (c) 2018, 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_CONTAINER_WRAPPER_HPP +#define TORRENT_CONTAINER_WRAPPER_HPP + +#include "libtorrent/config.hpp" +#include "libtorrent/assert.hpp" +#include "libtorrent/index_range.hpp" +#include "libtorrent/units.hpp" + +#include + +namespace libtorrent { namespace aux { + + template + struct container_wrapper : Base + { + using underlying_index = typename underlying_index_t::type; + + // pull in constructors from Base class + using Base::Base; + container_wrapper() = default; + explicit container_wrapper(Base&& b) : Base(std::move(b)) {} + + auto operator[](IndexType idx) const -> +#if TORRENT_AUTO_RETURN_TYPES + decltype(auto) +#else + decltype(this->Base::operator[](underlying_index())) +#endif + { + TORRENT_ASSERT(idx >= IndexType(0)); + TORRENT_ASSERT(idx < end_index()); + return this->Base::operator[](std::size_t(static_cast(idx))); + } + + auto operator[](IndexType idx) -> +#if TORRENT_AUTO_RETURN_TYPES + decltype(auto) +#else + decltype(this->Base::operator[](underlying_index())) +#endif + { + TORRENT_ASSERT(idx >= IndexType(0)); + TORRENT_ASSERT(idx < end_index()); + return this->Base::operator[](std::size_t(static_cast(idx))); + } + + IndexType end_index() const + { + TORRENT_ASSERT(this->size() <= std::size_t((std::numeric_limits::max)())); + return IndexType(static_cast(this->size())); + } + + // returns an object that can be used in a range-for to iterate over all + // indices + index_range range() const noexcept + { + return {IndexType{0}, end_index()}; + } + + template ::value>::type> + void resize(underlying_index s) + { + TORRENT_ASSERT(s >= 0); + this->Base::resize(std::size_t(s)); + } + + template ::value>::type> + void resize(underlying_index s, T const& v) + { + TORRENT_ASSERT(s >= 0); + this->Base::resize(std::size_t(s), v); + } + + void resize(std::size_t s) + { + TORRENT_ASSERT(s <= std::size_t((std::numeric_limits::max)())); + this->Base::resize(s); + } + + void resize(std::size_t s, T const& v) + { + TORRENT_ASSERT(s <= std::size_t((std::numeric_limits::max)())); + this->Base::resize(s, v); + } + + template ::value>::type> + void reserve(underlying_index s) + { + TORRENT_ASSERT(s >= 0); + this->Base::reserve(std::size_t(s)); + } + + void reserve(std::size_t s) + { + TORRENT_ASSERT(s <= std::size_t((std::numeric_limits::max)())); + this->Base::reserve(s); + } + }; +}} + +#endif + diff --git a/include/libtorrent/aux_/deque.hpp b/include/libtorrent/aux_/deque.hpp index 2f71d5987..a6200d5f5 100644 --- a/include/libtorrent/aux_/deque.hpp +++ b/include/libtorrent/aux_/deque.hpp @@ -34,94 +34,13 @@ POSSIBILITY OF SUCH DAMAGE. #define TORRENT_DEQUE_HPP #include -#include -#include "libtorrent/units.hpp" -#include "libtorrent/assert.hpp" +#include "libtorrent/aux_/container_wrapper.hpp" namespace libtorrent { namespace aux { template - struct deque : std::deque - { - using base = std::deque; - using underlying_index = typename underlying_index_t::type; - - // pull in constructors from base class - using base::base; - - auto operator[](IndexType idx) const -> -#if TORRENT_AUTO_RETURN_TYPES - decltype(auto) -#else - decltype(this->base::operator[](underlying_index())) -#endif - { - TORRENT_ASSERT(idx >= IndexType(0)); - TORRENT_ASSERT(idx < end_index()); - return this->base::operator[](std::size_t(static_cast(idx))); - } - - auto operator[](IndexType idx) -> -#if TORRENT_AUTO_RETURN_TYPES - decltype(auto) -#else - decltype(this->base::operator[](underlying_index())) -#endif - { - TORRENT_ASSERT(idx >= IndexType(0)); - TORRENT_ASSERT(idx < end_index()); - return this->base::operator[](std::size_t(static_cast(idx))); - } - - IndexType end_index() const - { - TORRENT_ASSERT(this->size() <= std::size_t((std::numeric_limits::max)())); - return IndexType(static_cast(this->size())); - } - - template ::value>::type> - void resize(underlying_index s) - { - TORRENT_ASSERT(s >= 0); - this->base::resize(std::size_t(s)); - } - - template ::value>::type> - void resize(underlying_index s, T const& v) - { - TORRENT_ASSERT(s >= 0); - this->base::resize(std::size_t(s), v); - } - - void resize(std::size_t s) - { - TORRENT_ASSERT(s <= std::size_t((std::numeric_limits::max)())); - this->base::resize(s); - } - - void resize(std::size_t s, T const& v) - { - TORRENT_ASSERT(s <= std::size_t((std::numeric_limits::max)())); - this->base::resize(s, v); - } - - template ::value>::type> - void reserve(underlying_index s) - { - TORRENT_ASSERT(s >= 0); - this->base::reserve(std::size_t(s)); - } - - void reserve(std::size_t s) - { - TORRENT_ASSERT(s <= std::size_t((std::numeric_limits::max)())); - this->base::reserve(s); - } - }; + using deque = container_wrapper>; }} diff --git a/include/libtorrent/aux_/vector.hpp b/include/libtorrent/aux_/vector.hpp index 4e161fdc7..cf4e01b6b 100644 --- a/include/libtorrent/aux_/vector.hpp +++ b/include/libtorrent/aux_/vector.hpp @@ -34,111 +34,13 @@ POSSIBILITY OF SUCH DAMAGE. #define TORRENT_VECTOR_HPP #include -#include -#include "libtorrent/units.hpp" -#include "libtorrent/assert.hpp" -#include "libtorrent/index_range.hpp" +#include "libtorrent/aux_/container_wrapper.hpp" namespace libtorrent { namespace aux { template - struct vector : std::vector - { - using base = std::vector; - using underlying_index = typename underlying_index_t::type; - - // pull in constructors from base class - using base::base; - - vector() noexcept {} - vector(vector const&) = default; - vector& operator=(vector const&) = default; - - // the move constructor of std::vector isn't noexcept until C++17 - vector(vector&& rhs) noexcept : base(std::forward(rhs)) {} - vector& operator=(vector&& rhs) noexcept - { this->base::operator=(std::forward(rhs)); return *this; } - - auto operator[](IndexType idx) const -> -#if TORRENT_AUTO_RETURN_TYPES - decltype(auto) -#else - decltype(this->base::operator[](underlying_index())) -#endif - { - TORRENT_ASSERT(idx >= IndexType(0)); - TORRENT_ASSERT(idx < end_index()); - return this->base::operator[](std::size_t(static_cast(idx))); - } - - auto operator[](IndexType idx) -> -#if TORRENT_AUTO_RETURN_TYPES - decltype(auto) -#else - decltype(this->base::operator[](underlying_index())) -#endif - { - TORRENT_ASSERT(idx >= IndexType(0)); - TORRENT_ASSERT(idx < end_index()); - return this->base::operator[](std::size_t(static_cast(idx))); - } - - IndexType end_index() const - { - TORRENT_ASSERT(this->size() <= std::size_t((std::numeric_limits::max)())); - return IndexType(static_cast(this->size())); - } - - // returns an object that can be used in a range-for to iterate over all - // indices - index_range range() const noexcept - { - return {IndexType{0}, end_index()}; - } - - template ::value>::type> - void resize(underlying_index s) - { - TORRENT_ASSERT(s >= 0); - this->base::resize(std::size_t(s)); - } - - template ::value>::type> - void resize(underlying_index s, T const& v) - { - TORRENT_ASSERT(s >= 0); - this->base::resize(std::size_t(s), v); - } - - void resize(std::size_t s) - { - TORRENT_ASSERT(s <= std::size_t((std::numeric_limits::max)())); - this->base::resize(s); - } - - void resize(std::size_t s, T const& v) - { - TORRENT_ASSERT(s <= std::size_t((std::numeric_limits::max)())); - this->base::resize(s, v); - } - - template ::value>::type> - void reserve(underlying_index s) - { - TORRENT_ASSERT(s >= 0); - this->base::reserve(std::size_t(s)); - } - - void reserve(std::size_t s) - { - TORRENT_ASSERT(s <= std::size_t((std::numeric_limits::max)())); - this->base::reserve(s); - } - }; + using vector = container_wrapper>; }} diff --git a/src/file.cpp b/src/file.cpp index 327e72f80..c467188d5 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -32,6 +32,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/config.hpp" #include "libtorrent/aux_/disable_warnings_push.hpp" +#include "libtorrent/span.hpp" #include // for call_once #ifdef __GNUC__ @@ -179,14 +180,11 @@ namespace { return WAIT_FAILED; } - int preadv(HANDLE fd, ::iovec const* bufs, int num_bufs, std::int64_t file_offset) + int allocate_overlapped(::iovec const* bufs, lt::span ol + , lt::span h, std::int64_t file_offset) { - TORRENT_ALLOCA(ol, OVERLAPPED, num_bufs); - std::memset(ol.data(), 0, sizeof(OVERLAPPED) * num_bufs); - - TORRENT_ALLOCA(h, HANDLE, num_bufs); - - for (int i = 0; i < num_bufs; ++i) + std::memset(ol.data(), 0, sizeof(OVERLAPPED) * ol.size()); + for (std::size_t i = 0; i < ol.size(); ++i) { ol[i].OffsetHigh = file_offset >> 32; ol[i].Offset = file_offset & 0xffffffff; @@ -195,11 +193,20 @@ namespace { if (h[i] == nullptr) { // we failed to create the event, roll-back and return an error - for (int j = 0; j < i; ++j) CloseHandle(h[i]); + for (std::size_t j = 0; j < i; ++j) CloseHandle(h[i]); return -1; } file_offset += bufs[i].iov_len; } + return 0; + } + + int preadv(HANDLE fd, ::iovec const* bufs, int num_bufs, std::int64_t const file_offset) + { + TORRENT_ALLOCA(ol, OVERLAPPED, num_bufs); + TORRENT_ALLOCA(h, HANDLE, num_bufs); + + if (allocate_overlapped(bufs, ol, h, file_offset) < 0) return -1; BOOST_SCOPE_EXIT_ALL(&h) { for (auto hnd : h) @@ -235,7 +242,7 @@ namespace { return -1; int ret = 0; - for (auto& o : libtorrent::span(ol).first(num_waits)) + for (auto& o : ol.first(num_waits)) { if (WaitForSingleObject(o.hEvent, INFINITE) == WAIT_FAILED) return -1; @@ -258,27 +265,12 @@ namespace { return ret; } - int pwritev(HANDLE fd, ::iovec const* bufs, int num_bufs, std::int64_t file_offset) + int pwritev(HANDLE fd, ::iovec const* bufs, int num_bufs, std::int64_t const file_offset) { TORRENT_ALLOCA(ol, OVERLAPPED, num_bufs); - std::memset(ol.data(), 0, sizeof(OVERLAPPED) * num_bufs); - TORRENT_ALLOCA(h, HANDLE, num_bufs); - for (int i = 0; i < num_bufs; ++i) - { - ol[i].OffsetHigh = file_offset >> 32; - ol[i].Offset = file_offset & 0xffffffff; - ol[i].hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr); - h[i] = ol[i].hEvent; - if (h[i] == nullptr) - { - // we failed to create the event, roll-back and return an error - for (int j = 0; j < i; ++j) CloseHandle(h[i]); - return -1; - } - file_offset += bufs[i].iov_len; - } + if (allocate_overlapped(bufs, ol, h, file_offset) < 0) return -1; BOOST_SCOPE_EXIT_ALL(&h) { for (auto hnd : h) diff --git a/src/proxy_settings.cpp b/src/proxy_settings.cpp index 8daff1e67..39cbdd806 100644 --- a/src/proxy_settings.cpp +++ b/src/proxy_settings.cpp @@ -36,33 +36,32 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { namespace aux { +namespace { + +template +void init(proxy_settings& p, Settings const& sett) +{ + p.hostname = sett.get_str(settings_pack::proxy_hostname); + p.username = sett.get_str(settings_pack::proxy_username); + p.password = sett.get_str(settings_pack::proxy_password); + p.type = std::uint8_t(sett.get_int(settings_pack::proxy_type)); + p.port = std::uint16_t(sett.get_int(settings_pack::proxy_port)); + p.proxy_hostnames = sett.get_bool(settings_pack::proxy_hostnames); + p.proxy_peer_connections = sett.get_bool( + settings_pack::proxy_peer_connections); + p.proxy_tracker_connections = sett.get_bool( + settings_pack::proxy_tracker_connections); +} + +} + proxy_settings::proxy_settings() = default; proxy_settings::proxy_settings(settings_pack const& sett) - : hostname(sett.get_str(settings_pack::proxy_hostname)) - , username(sett.get_str(settings_pack::proxy_username)) - , password(sett.get_str(settings_pack::proxy_password)) - , type(std::uint8_t(sett.get_int(settings_pack::proxy_type))) - , port(std::uint16_t(sett.get_int(settings_pack::proxy_port))) - , proxy_hostnames(sett.get_bool(settings_pack::proxy_hostnames)) - , proxy_peer_connections(sett.get_bool( - settings_pack::proxy_peer_connections)) - , proxy_tracker_connections(sett.get_bool( - settings_pack::proxy_tracker_connections)) -{} +{ init(*this, sett); } proxy_settings::proxy_settings(aux::session_settings const& sett) - : hostname(sett.get_str(settings_pack::proxy_hostname)) - , username(sett.get_str(settings_pack::proxy_username)) - , password(sett.get_str(settings_pack::proxy_password)) - , type(std::uint8_t(sett.get_int(settings_pack::proxy_type))) - , port(std::uint16_t(sett.get_int(settings_pack::proxy_port))) - , proxy_hostnames(sett.get_bool(settings_pack::proxy_hostnames)) - , proxy_peer_connections(sett.get_bool( - settings_pack::proxy_peer_connections)) - , proxy_tracker_connections(sett.get_bool( - settings_pack::proxy_tracker_connections)) -{} +{ init(*this, sett); } } // namespace aux } // namespace libtorrent