diff --git a/src/base/CMakeLists.txt b/src/base/CMakeLists.txt index b5c48acc9..482e3c31e 100644 --- a/src/base/CMakeLists.txt +++ b/src/base/CMakeLists.txt @@ -32,6 +32,7 @@ add_library(qbt_base STATIC bittorrent/torrentinfo.h bittorrent/tracker.h bittorrent/trackerentry.h + digest32.h exceptions.h filesystemwatcher.h global.h diff --git a/src/base/base.pri b/src/base/base.pri index a9f6cbe65..95cf69246 100644 --- a/src/base/base.pri +++ b/src/base/base.pri @@ -31,6 +31,7 @@ HEADERS += \ $$PWD/bittorrent/torrentinfo.h \ $$PWD/bittorrent/tracker.h \ $$PWD/bittorrent/trackerentry.h \ + $$PWD/digest32.h \ $$PWD/exceptions.h \ $$PWD/filesystemwatcher.h \ $$PWD/global.h \ diff --git a/src/base/bittorrent/infohash.cpp b/src/base/bittorrent/infohash.cpp index f7ea61a8c..d46116e48 100644 --- a/src/base/bittorrent/infohash.cpp +++ b/src/base/bittorrent/infohash.cpp @@ -28,70 +28,14 @@ #include "infohash.h" -#include -#include +const int InfoHashTypeId = qRegisterMetaType(); -using namespace BitTorrent; - -const int InfoHashTypeId = qRegisterMetaType(); - -InfoHash::InfoHash(const lt::sha1_hash &nativeHash) - : m_valid {true} - , m_nativeHash {nativeHash} -{ - const QByteArray raw = QByteArray::fromRawData(nativeHash.data(), length()); - m_hashString = QString::fromLatin1(raw.toHex()); -} - -bool InfoHash::isValid() const -{ - return m_valid; -} - -InfoHash::operator lt::sha1_hash() const -{ - return m_nativeHash; -} - -InfoHash InfoHash::fromString(const QString &hashString) -{ - if (hashString.size() != (length() * 2)) - return {}; - - const QByteArray raw = QByteArray::fromHex(hashString.toLatin1()); - if (raw.size() != length()) // QByteArray::fromHex() will skip over invalid characters - return {}; - - InfoHash result; - result.m_valid = true; - result.m_hashString = hashString; - result.m_nativeHash.assign(raw.constData()); - - return result; -} - -QString InfoHash::toString() const -{ - return m_hashString; -} - -bool BitTorrent::operator==(const InfoHash &left, const InfoHash &right) -{ - return (static_cast(left) - == static_cast(right)); -} - -bool BitTorrent::operator!=(const InfoHash &left, const InfoHash &right) -{ - return !(left == right); -} - -bool BitTorrent::operator<(const InfoHash &left, const InfoHash &right) +BitTorrent::InfoHash BitTorrent::InfoHash::fromString(const QString &hashString) { - return static_cast(left) < static_cast(right); + return {SHA1Hash::fromString(hashString)}; } -uint BitTorrent::qHash(const InfoHash &key, const uint seed) +uint BitTorrent::qHash(const BitTorrent::InfoHash &key, const uint seed) { - return ::qHash((std::hash {})(key), seed); + return ::qHash(std::hash()(key), seed); } diff --git a/src/base/bittorrent/infohash.h b/src/base/bittorrent/infohash.h index 1e2ec3b7f..d6a4c874c 100644 --- a/src/base/bittorrent/infohash.h +++ b/src/base/bittorrent/infohash.h @@ -28,42 +28,25 @@ #pragma once -#include - +#include #include -#include + +#include "base/digest32.h" + +using SHA1Hash = Digest32<160>; +using SHA256Hash = Digest32<256>; namespace BitTorrent { - class InfoHash + class InfoHash : public SHA1Hash { public: - InfoHash() = default; - InfoHash(const lt::sha1_hash &nativeHash); - InfoHash(const InfoHash &other) = default; - - static constexpr int length() - { - return lt::sha1_hash::size(); - } - - bool isValid() const; - - operator lt::sha1_hash() const; + using SHA1Hash::SHA1Hash; static InfoHash fromString(const QString &hashString); - QString toString() const; - - private: - bool m_valid = false; - lt::sha1_hash m_nativeHash; - QString m_hashString; }; - bool operator==(const InfoHash &left, const InfoHash &right); - bool operator!=(const InfoHash &left, const InfoHash &right); - bool operator<(const InfoHash &left, const InfoHash &right); - uint qHash(const InfoHash &key, uint seed); + uint qHash(const InfoHash &key, const uint seed); } Q_DECLARE_METATYPE(BitTorrent::InfoHash) diff --git a/src/base/digest32.h b/src/base/digest32.h new file mode 100644 index 000000000..ece84af41 --- /dev/null +++ b/src/base/digest32.h @@ -0,0 +1,121 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2015, 2021 Vladimir Golovnev + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + */ + +#pragma once + +#include + +#include +#include +#include + +template +class Digest32 +{ +public: + using UnderlyingType = lt::digest32; + + Digest32() = default; + Digest32(const Digest32 &other) = default; + + Digest32(const UnderlyingType &nativeDigest) + : m_valid {true} + , m_nativeDigest {nativeDigest} + { + const QByteArray raw = QByteArray::fromRawData(nativeDigest.data(), length()); + m_hashString = QString::fromLatin1(raw.toHex()); + } + + static constexpr int length() + { + return UnderlyingType::size(); + } + + bool isValid() const + { + return m_valid; + } + + operator UnderlyingType() const + { + return m_nativeDigest; + } + + static Digest32 fromString(const QString &digestString) + { + if (digestString.size() != (length() * 2)) + return {}; + + const QByteArray raw = QByteArray::fromHex(digestString.toLatin1()); + if (raw.size() != length()) // QByteArray::fromHex() will skip over invalid characters + return {}; + + Digest32 result; + result.m_valid = true; + result.m_hashString = digestString; + result.m_nativeDigest.assign(raw.constData()); + + return result; + } + + QString toString() const + { + return m_hashString; + } + +private: + bool m_valid = false; + UnderlyingType m_nativeDigest; + QString m_hashString; +}; + +template +bool operator==(const Digest32 &left, const Digest32 &right) +{ + return (static_cast::UnderlyingType>(left) + == static_cast::UnderlyingType>(right)); +} + +template +bool operator!=(const Digest32 &left, const Digest32 &right) +{ + return !(left == right); +} + +template +bool operator<(const Digest32 &left, const Digest32 &right) +{ + return static_cast::UnderlyingType>(left) + < static_cast::UnderlyingType>(right); +} + +template +uint qHash(const Digest32 &key, const uint seed) +{ + return ::qHash(std::hash::UnderlyingType>()(key), seed); +} diff --git a/src/gui/transferlistsortmodel.h b/src/gui/transferlistsortmodel.h index 95df8426a..a8ea23dac 100644 --- a/src/gui/transferlistsortmodel.h +++ b/src/gui/transferlistsortmodel.h @@ -29,6 +29,7 @@ #pragma once #include + #include "base/torrentfilter.h" namespace BitTorrent