summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaksim Denisov <denisov.maksim@huawei.com>2024-07-17 12:57:28 +0200
committerMaksim Denisov <denisov.maksim@huawei.com>2024-07-22 17:02:34 +0200
commitb2f51059cc034f03c70df28a5597a591ed3e5c5d (patch)
treefa607f601f623f70a05aabc18801c6daed4c2a18
parent0b80611163ffedb87dc2305320906f27e502cbcd (diff)
downloadjustbuild-b2f51059cc034f03c70df28a5597a591ed3e5c5d.tar.gz
Create Hasher using a static function
-rw-r--r--src/buildtool/crypto/TARGETS8
-rw-r--r--src/buildtool/crypto/hash_function.hpp10
-rw-r--r--src/buildtool/crypto/hasher.cpp42
-rw-r--r--src/buildtool/crypto/hasher.hpp33
-rw-r--r--src/other_tools/utils/content.hpp6
-rw-r--r--test/buildtool/crypto/hasher.test.cpp9
6 files changed, 64 insertions, 44 deletions
diff --git a/src/buildtool/crypto/TARGETS b/src/buildtool/crypto/TARGETS
index 1b4a7ae7..6890b54f 100644
--- a/src/buildtool/crypto/TARGETS
+++ b/src/buildtool/crypto/TARGETS
@@ -14,12 +14,12 @@
, "hash_impl_sha512.cpp"
]
, "stage": ["src", "buildtool", "crypto"]
- , "deps":
- [ ["src/buildtool/logging", "log_level"]
+ , "deps": [["src/utils/cpp", "hex_string"]]
+ , "private-deps":
+ [ ["@", "ssl", "", "crypto"]
+ , ["src/buildtool/logging", "log_level"]
, ["src/buildtool/logging", "logging"]
- , ["src/utils/cpp", "hex_string"]
]
- , "private-deps": [["@", "ssl", "", "crypto"]]
}
, "hash_function":
{ "type": ["@", "rules", "CC", "library"]
diff --git a/src/buildtool/crypto/hash_function.hpp b/src/buildtool/crypto/hash_function.hpp
index c73458eb..99a15cdb 100644
--- a/src/buildtool/crypto/hash_function.hpp
+++ b/src/buildtool/crypto/hash_function.hpp
@@ -69,13 +69,17 @@ class HashFunction {
/// \brief Obtain incremental hasher for computing plain hashes.
[[nodiscard]] auto MakeHasher() const noexcept -> Hasher {
+ std::optional<Hasher> hasher;
switch (type_) {
case JustHash::Native:
- return Hasher{Hasher::HashType::SHA1};
+ hasher = Hasher::Create(Hasher::HashType::SHA1);
+ break;
case JustHash::Compatible:
- return Hasher{Hasher::HashType::SHA256};
+ hasher = Hasher::Create(Hasher::HashType::SHA256);
+ break;
}
- Ensures(false); // unreachable
+ Ensures(hasher.has_value());
+ return *std::move(hasher);
}
private:
diff --git a/src/buildtool/crypto/hasher.cpp b/src/buildtool/crypto/hasher.cpp
index 60a029c2..6e2f6ee3 100644
--- a/src/buildtool/crypto/hasher.cpp
+++ b/src/buildtool/crypto/hasher.cpp
@@ -17,16 +17,48 @@
#include "src/buildtool/crypto/hash_impl_sha1.hpp"
#include "src/buildtool/crypto/hash_impl_sha256.hpp"
#include "src/buildtool/crypto/hash_impl_sha512.hpp"
+#include "src/buildtool/logging/log_level.hpp"
+#include "src/buildtool/logging/logger.hpp"
-auto Hasher::CreateHashImpl(HashType type) noexcept
- -> std::unique_ptr<IHashImpl> {
+namespace {
+[[nodiscard]] auto CreateHashImpl(Hasher::HashType type) noexcept
+ -> std::unique_ptr<Hasher::IHashImpl> {
switch (type) {
- case HashType::SHA1:
+ case Hasher::HashType::SHA1:
return CreateHashImplSha1();
- case HashType::SHA256:
+ case Hasher::HashType::SHA256:
return CreateHashImplSha256();
- case HashType::SHA512:
+ case Hasher::HashType::SHA512:
return CreateHashImplSha512();
}
return nullptr; // make gcc happy
}
+} // namespace
+
+Hasher::Hasher(std::unique_ptr<IHashImpl> impl) noexcept
+ : impl_{std::move(impl)} {}
+
+auto Hasher::Create(HashType type) noexcept -> std::optional<Hasher> {
+ auto impl = CreateHashImpl(type);
+ if (impl == nullptr) {
+ return std::nullopt;
+ }
+ return Hasher{std::move(impl)};
+}
+
+auto Hasher::Update(std::string const& data) noexcept -> bool {
+ return impl_->Update(data);
+}
+
+auto Hasher::Finalize() && noexcept -> HashDigest {
+ auto hash = std::move(*impl_).Finalize();
+ if (not hash) {
+ Logger::Log(LogLevel::Error, "Failed to compute hash.");
+ std::terminate();
+ }
+ return HashDigest{std::move(*hash)};
+}
+
+auto Hasher::GetHashLength() const noexcept -> std::size_t {
+ return impl_->GetHashLength();
+}
diff --git a/src/buildtool/crypto/hasher.hpp b/src/buildtool/crypto/hasher.hpp
index a4779509..c37cd34e 100644
--- a/src/buildtool/crypto/hasher.hpp
+++ b/src/buildtool/crypto/hasher.hpp
@@ -23,12 +23,10 @@
#include <string>
#include <utility> // std::move
-#include "src/buildtool/logging/log_level.hpp"
-#include "src/buildtool/logging/logger.hpp"
#include "src/utils/cpp/hex_string.hpp"
/// \brief Incremental hasher.
-class Hasher {
+class Hasher final {
public:
/// \brief Types of hash implementations supported by generator.
enum class HashType : std::uint8_t { SHA1, SHA256, SHA512 };
@@ -36,7 +34,7 @@ class Hasher {
/// \brief The universal hash digest.
/// The type of hash and the digest length depends on the hash
/// implementation used to generated this digest.
- class HashDigest {
+ class HashDigest final {
friend Hasher;
public:
@@ -91,39 +89,24 @@ class Hasher {
/// \brief Obtain length of the resulting hash string.
[[nodiscard]] virtual auto GetHashLength() const noexcept -> size_t = 0;
-
- static auto FatalError() noexcept -> void {
- Logger::Log(LogLevel::Error, "Failed to compute hash.");
- std::terminate();
- }
};
- explicit Hasher(HashType type) : impl_{CreateHashImpl(type)} {}
+ [[nodiscard]] static auto Create(HashType type) noexcept
+ -> std::optional<Hasher>;
/// \brief Feed data to the hasher.
- auto Update(std::string const& data) noexcept -> bool {
- return impl_->Update(data);
- }
+ auto Update(std::string const& data) noexcept -> bool;
/// \brief Finalize hash.
- [[nodiscard]] auto Finalize() && noexcept -> HashDigest {
- if (auto hash = std::move(*impl_).Finalize()) {
- return HashDigest{std::move(*hash)};
- }
- IHashImpl::FatalError();
- return HashDigest{{}};
- }
+ [[nodiscard]] auto Finalize() && noexcept -> HashDigest;
/// \brief Obtain length of the resulting hash string.
- [[nodiscard]] auto GetHashLength() const noexcept -> size_t {
- return impl_->GetHashLength();
- }
+ [[nodiscard]] auto GetHashLength() const noexcept -> std::size_t;
private:
std::unique_ptr<IHashImpl> impl_;
- [[nodiscard]] static auto CreateHashImpl(HashType type) noexcept
- -> std::unique_ptr<IHashImpl>;
+ explicit Hasher(std::unique_ptr<IHashImpl> impl) noexcept;
};
#endif // INCLUDED_SRC_BUILDTOOL_CRYPTO_HASHER_HPP
diff --git a/src/other_tools/utils/content.hpp b/src/other_tools/utils/content.hpp
index 31dd7fc1..eb6aca76 100644
--- a/src/other_tools/utils/content.hpp
+++ b/src/other_tools/utils/content.hpp
@@ -89,9 +89,9 @@
template <Hasher::HashType type>
[[nodiscard]] static auto GetContentHash(std::string const& data) noexcept
-> std::string {
- Hasher hasher{type};
- hasher.Update(data);
- auto digest = std::move(hasher).Finalize();
+ auto hasher = Hasher::Create(type);
+ hasher->Update(data);
+ auto digest = std::move(*hasher).Finalize();
return digest.HexString();
}
diff --git a/test/buildtool/crypto/hasher.test.cpp b/test/buildtool/crypto/hasher.test.cpp
index 0ee0cca1..4f5e8448 100644
--- a/test/buildtool/crypto/hasher.test.cpp
+++ b/test/buildtool/crypto/hasher.test.cpp
@@ -20,10 +20,11 @@
template <Hasher::HashType type>
void test_increment_hash(std::string const& bytes, std::string const& result) {
- Hasher hasher{type};
- hasher.Update(bytes.substr(0, bytes.size() / 2));
- hasher.Update(bytes.substr(bytes.size() / 2));
- auto digest = std::move(hasher).Finalize();
+ auto hasher = Hasher::Create(type);
+ REQUIRE(hasher.has_value());
+ hasher->Update(bytes.substr(0, bytes.size() / 2));
+ hasher->Update(bytes.substr(bytes.size() / 2));
+ auto digest = std::move(*hasher).Finalize();
CHECK(digest.HexString() == result);
}