1 /*
2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2015, 2021 Vladimir Golovnev <glassez@yandex.ru>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 * In addition, as a special exception, the copyright holders give permission to
20 * link this program with the OpenSSL project's "OpenSSL" library (or with
21 * modified versions of it that use the same license as the "OpenSSL" library),
22 * and distribute the linked executables. You must obey the GNU General Public
23 * License in all respects for all of the code used other than "OpenSSL". If you
24 * modify file(s), you may extend this exception to your version of the file(s),
25 * but you are not obligated to do so. If you do not wish to do so, delete this
26 * exception statement from your version.
27 */
28
29 #pragma once
30
31 #include <libtorrent/sha1_hash.hpp>
32
33 #include <QByteArray>
34 #include <QHash>
35 #include <QString>
36
37 template <int N>
38 class Digest32
39 {
40 public:
41 using UnderlyingType = lt::digest32<N>;
42
43 Digest32() = default;
44 Digest32(const Digest32 &other) = default;
45
Digest32(const UnderlyingType & nativeDigest)46 Digest32(const UnderlyingType &nativeDigest)
47 : m_valid {true}
48 , m_nativeDigest {nativeDigest}
49 {
50 const QByteArray raw = QByteArray::fromRawData(nativeDigest.data(), length());
51 m_hashString = QString::fromLatin1(raw.toHex());
52 }
53
length()54 static constexpr int length()
55 {
56 return UnderlyingType::size();
57 }
58
isValid()59 bool isValid() const
60 {
61 return m_valid;
62 }
63
UnderlyingType()64 operator UnderlyingType() const
65 {
66 return m_nativeDigest;
67 }
68
fromString(const QString & digestString)69 static Digest32 fromString(const QString &digestString)
70 {
71 if (digestString.size() != (length() * 2))
72 return {};
73
74 const QByteArray raw = QByteArray::fromHex(digestString.toLatin1());
75 if (raw.size() != length()) // QByteArray::fromHex() will skip over invalid characters
76 return {};
77
78 Digest32 result;
79 result.m_valid = true;
80 result.m_hashString = digestString;
81 result.m_nativeDigest.assign(raw.constData());
82
83 return result;
84 }
85
toString()86 QString toString() const
87 {
88 return m_hashString;
89 }
90
91 private:
92 bool m_valid = false;
93 UnderlyingType m_nativeDigest;
94 QString m_hashString;
95 };
96
97 template <int N>
98 bool operator==(const Digest32<N> &left, const Digest32<N> &right)
99 {
100 return (static_cast<typename Digest32<N>::UnderlyingType>(left)
101 == static_cast<typename Digest32<N>::UnderlyingType>(right));
102 }
103
104 template <int N>
105 bool operator!=(const Digest32<N> &left, const Digest32<N> &right)
106 {
107 return !(left == right);
108 }
109
110 template <int N>
111 bool operator<(const Digest32<N> &left, const Digest32<N> &right)
112 {
113 return static_cast<typename Digest32<N>::UnderlyingType>(left)
114 < static_cast<typename Digest32<N>::UnderlyingType>(right);
115 }
116
117 template <int N>
qHash(const Digest32<N> & key,const uint seed)118 uint qHash(const Digest32<N> &key, const uint seed)
119 {
120 return ::qHash(std::hash<typename Digest32<N>::UnderlyingType>()(key), seed);
121 }
122