From 348bc2b4fe7a10d825c4bceeb64847339ed2ac62 Mon Sep 17 00:00:00 2001 From: arvidn Date: Sun, 28 Jan 2018 19:29:35 +0100 Subject: [PATCH] remove some uses of memset in favour of std::array. add some noexcept to sha1_hash operations --- include/libtorrent/sha1_hash.hpp | 99 ++++++++++++++++---------------- test/test_part_file.cpp | 8 ++- 2 files changed, 55 insertions(+), 52 deletions(-) diff --git a/include/libtorrent/sha1_hash.hpp b/include/libtorrent/sha1_hash.hpp index acc88b15c..172f6d046 100644 --- a/include/libtorrent/sha1_hash.hpp +++ b/include/libtorrent/sha1_hash.hpp @@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include "libtorrent/config.hpp" #include "libtorrent/assert.hpp" @@ -67,11 +68,11 @@ namespace aux { class digest32 { static_assert(N % 32 == 0, "N must be a multiple of 32"); - static constexpr int number_size = N / 32; + static constexpr std::size_t number_size = N / 32; public: // the size of the hash in bytes - static constexpr std::size_t size() { return N / 8; } + static constexpr std::size_t size() noexcept { return N / 8; } // constructs an all-zero digest digest32() noexcept { clear(); } @@ -82,17 +83,17 @@ namespace aux { // returns an all-F digest. i.e. the maximum value // representable by an N bit number (N/8 bytes). This is // a static member function. - static digest32 (max)() + static digest32 (max)() noexcept { digest32 ret; - std::memset(ret.m_number, 0xff, size()); + ret.m_number.fill(0xffffffff); return ret; } // returns an all-zero digest. i.e. the minimum value // representable by an N bit number (N/8 bytes). This is // a static member function. - static digest32 (min)() + static digest32 (min)() noexcept { digest32 ret; // all bits are already 0 @@ -102,10 +103,10 @@ namespace aux { // copies N/8 bytes from the pointer provided, into the digest. // The passed in string MUST be at least N/8 bytes. 0-terminators // are ignored, ``s`` is treated like a raw memory buffer. - explicit digest32(char const* s) + explicit digest32(char const* s) noexcept { if (s == nullptr) clear(); - else std::memcpy(m_number, s, size()); + else std::memcpy(m_number.data(), s, size()); } #ifndef TORRENT_NO_DEPRECATE TORRENT_DEPRECATED @@ -114,58 +115,58 @@ namespace aux { assign(s.data()); } #endif - explicit digest32(span s) + explicit digest32(span s) noexcept { assign(s); } - void assign(span s) + void assign(span s) noexcept { TORRENT_ASSERT(s.size() >= N / 8); std::size_t const sl = s.size() < size() ? s.size() : size(); - std::memcpy(m_number, s.data(), sl); + std::memcpy(m_number.data(), s.data(), sl); } - void assign(char const* str) { std::memcpy(m_number, str, size()); } + void assign(char const* str) noexcept { std::memcpy(m_number.data(), str, size()); } - char const* data() const { return reinterpret_cast(&m_number[0]); } - char* data() { return reinterpret_cast(&m_number[0]); } + char const* data() const noexcept { return reinterpret_cast(m_number.data()); } + char* data() noexcept { return reinterpret_cast(m_number.data()); } // set the digest to all zeros. - void clear() noexcept { std::memset(m_number, 0, size()); } + void clear() noexcept { m_number.fill(0); } // return true if the digest is all zero. - bool is_all_zeros() const + bool is_all_zeros() const noexcept { - for (int i = 0; i < number_size; ++i) - if (m_number[i] != 0) return false; + for (auto const& v : m_number) + if (v != 0) return false; return true; } // shift left ``n`` bits. - digest32& operator<<=(int n) + digest32& operator<<=(int const n) noexcept { - aux::bits_shift_left({m_number, std::size_t(number_size)}, n); + aux::bits_shift_left(m_number, n); return *this; } // shift right ``n`` bits. - digest32& operator>>=(int n) + digest32& operator>>=(int const n) noexcept { - aux::bits_shift_right({m_number, std::size_t(number_size)}, n); + aux::bits_shift_right(m_number, n); return *this; } // standard comparison operators - bool operator==(digest32 const& n) const + bool operator==(digest32 const& n) const noexcept { - return std::equal(n.m_number, n.m_number + number_size, m_number); + return std::equal(n.m_number.begin(), n.m_number.end(), m_number.begin()); } - bool operator!=(digest32 const& n) const + bool operator!=(digest32 const& n) const noexcept { - return !std::equal(n.m_number, n.m_number + number_size, m_number); + return !std::equal(n.m_number.begin(), n.m_number.end(), m_number.begin()); } - bool operator<(digest32 const& n) const + bool operator<(digest32 const& n) const noexcept { - for (int i = 0; i < number_size; ++i) + for (std::size_t i = 0; i < number_size; ++i) { std::uint32_t const lhs = aux::network_to_host(m_number[i]); std::uint32_t const rhs = aux::network_to_host(n.m_number[i]); @@ -175,22 +176,22 @@ namespace aux { return false; } - int count_leading_zeroes() const + int count_leading_zeroes() const noexcept { - return aux::count_leading_zeros({m_number, std::size_t(number_size)}); + return aux::count_leading_zeros(m_number); } // returns a bit-wise negated copy of the digest - digest32 operator~() const + digest32 operator~() const noexcept { digest32 ret; - for (int i = 0; i < number_size; ++i) + for (std::size_t i = 0; i < number_size; ++i) ret.m_number[i] = ~m_number[i]; return ret; } // returns the bit-wise XOR of the two digests. - digest32 operator^(digest32 const& n) const + digest32 operator^(digest32 const& n) const noexcept { digest32 ret = *this; ret ^= n; @@ -198,15 +199,15 @@ namespace aux { } // in-place bit-wise XOR with the passed in digest. - digest32& operator^=(digest32 const& n) + digest32& operator^=(digest32 const& n) noexcept { - for (int i = 0; i < number_size; ++i) + for (std::size_t i = 0; i < number_size; ++i) m_number[i] ^= n.m_number[i]; return *this; } // returns the bit-wise AND of the two digests. - digest32 operator&(digest32 const& n) const + digest32 operator&(digest32 const& n) const noexcept { digest32 ret = *this; ret &= n; @@ -214,31 +215,31 @@ namespace aux { } // in-place bit-wise AND of the passed in digest - digest32& operator&=(digest32 const& n) + digest32& operator&=(digest32 const& n) noexcept { - for (int i = 0; i < number_size; ++i) + for (std::size_t i = 0; i < number_size; ++i) m_number[i] &= n.m_number[i]; return *this; } // in-place bit-wise OR of the two digests. - digest32& operator|=(digest32 const& n) + digest32& operator|=(digest32 const& n) noexcept { - for (int i = 0; i < number_size; ++i) + for (std::size_t i = 0; i < number_size; ++i) m_number[i] |= n.m_number[i]; return *this; } // accessors for specific bytes - std::uint8_t& operator[](std::size_t i) + std::uint8_t& operator[](std::size_t i) noexcept { TORRENT_ASSERT(i < size()); - return reinterpret_cast(m_number)[i]; + return reinterpret_cast(m_number.data())[i]; } - std::uint8_t const& operator[](std::size_t i) const + std::uint8_t const& operator[](std::size_t i) const noexcept { TORRENT_ASSERT(i < size()); - return reinterpret_cast(m_number)[i]; + return reinterpret_cast(m_number.data())[i]; } using const_iterator = std::uint8_t const*; @@ -247,24 +248,24 @@ namespace aux { // start and end iterators for the hash. The value type // of these iterators is ``std::uint8_t``. const_iterator begin() const - { return reinterpret_cast(m_number); } + { return reinterpret_cast(m_number.data()); } const_iterator end() const - { return reinterpret_cast(m_number) + size(); } + { return reinterpret_cast(m_number.data()) + size(); } iterator begin() - { return reinterpret_cast(m_number); } + { return reinterpret_cast(m_number.data()); } iterator end() - { return reinterpret_cast(m_number) + size(); } + { return reinterpret_cast(m_number.data()) + size(); } // return a copy of the N/8 bytes representing the digest as a std::string. // It's still a binary string with N/8 binary characters. std::string to_string() const { - return std::string(reinterpret_cast(&m_number[0]), size()); + return std::string(reinterpret_cast(m_number.data()), size()); } private: - std::uint32_t m_number[number_size]; + std::array m_number; }; diff --git a/test/test_part_file.cpp b/test/test_part_file.cpp index f5acb9d7e..ce525d338 100644 --- a/test/test_part_file.cpp +++ b/test/test_part_file.cpp @@ -31,6 +31,8 @@ POSSIBILITY OF SUCH DAMAGE. */ #include +#include + #include "test.hpp" #include "libtorrent/part_file.hpp" #include "libtorrent/aux_/path.hpp" @@ -49,7 +51,7 @@ TORRENT_TEST(part_file) if (ec) std::printf("remove_all: %s\n", ec.message().c_str()); int piece_size = 16 * 0x4000; - char buf[1024]; + std::array buf; { create_directory(combine_path(cwd, "partfile_test_dir"), ec); @@ -86,7 +88,7 @@ TORRENT_TEST(part_file) TEST_CHECK(!exists(combine_path(combine_path(cwd, "partfile_test_dir"), "partfile.parts"))); TEST_CHECK(exists(combine_path(combine_path(cwd, "partfile_test_dir2"), "partfile.parts"))); - std::memset(buf, 0, sizeof(buf)); + buf.fill(0); pf.readv(v, piece_index_t(10), 0, ec); if (ec) std::printf("part_file::readv: %s\n", ec.message().c_str()); @@ -99,7 +101,7 @@ TORRENT_TEST(part_file) // load the part file back in part_file pf(combine_path(cwd, "partfile_test_dir2"), "partfile.parts", 100, piece_size); - std::memset(buf, 0, sizeof(buf)); + buf.fill(0); iovec_t v = buf; pf.readv(v, piece_index_t(10), 0, ec);