diff options
author | Maksim Denisov <denisov.maksim@huawei.com> | 2024-07-17 12:57:28 +0200 |
---|---|---|
committer | Maksim Denisov <denisov.maksim@huawei.com> | 2024-07-22 17:02:34 +0200 |
commit | b2f51059cc034f03c70df28a5597a591ed3e5c5d (patch) | |
tree | fa607f601f623f70a05aabc18801c6daed4c2a18 | |
parent | 0b80611163ffedb87dc2305320906f27e502cbcd (diff) | |
download | justbuild-b2f51059cc034f03c70df28a5597a591ed3e5c5d.tar.gz |
Create Hasher using a static function
-rw-r--r-- | src/buildtool/crypto/TARGETS | 8 | ||||
-rw-r--r-- | src/buildtool/crypto/hash_function.hpp | 10 | ||||
-rw-r--r-- | src/buildtool/crypto/hasher.cpp | 42 | ||||
-rw-r--r-- | src/buildtool/crypto/hasher.hpp | 33 | ||||
-rw-r--r-- | src/other_tools/utils/content.hpp | 6 | ||||
-rw-r--r-- | test/buildtool/crypto/hasher.test.cpp | 9 |
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); } |