diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/crypto/TARGETS | 5 | ||||
-rw-r--r-- | src/buildtool/crypto/hash_function.cpp | 56 | ||||
-rw-r--r-- | src/buildtool/crypto/hash_function.hpp | 8 |
3 files changed, 69 insertions, 0 deletions
diff --git a/src/buildtool/crypto/TARGETS b/src/buildtool/crypto/TARGETS index ab2d6b21..47309f72 100644 --- a/src/buildtool/crypto/TARGETS +++ b/src/buildtool/crypto/TARGETS @@ -22,7 +22,12 @@ { "type": ["@", "rules", "CC", "library"] , "name": ["hash_function"] , "hdrs": ["hash_function.hpp"] + , "srcs": ["hash_function.cpp"] , "deps": ["hasher", ["@", "gsl", "", "gsl"]] + , "private-deps": + [ ["src/buildtool/logging", "logging"] + , ["src/buildtool/logging", "log_level"] + ] , "stage": ["src", "buildtool", "crypto"] } } diff --git a/src/buildtool/crypto/hash_function.cpp b/src/buildtool/crypto/hash_function.cpp new file mode 100644 index 00000000..89bb0cb8 --- /dev/null +++ b/src/buildtool/crypto/hash_function.cpp @@ -0,0 +1,56 @@ +// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/buildtool/crypto/hash_function.hpp" + +#include <fstream> +#include <string> + +#include "src/buildtool/logging/log_level.hpp" +#include "src/buildtool/logging/logger.hpp" + +[[nodiscard]] auto HashFunction::ComputeHashFile( + const std::filesystem::path& file_path, + bool as_tree) noexcept + -> std::optional<std::pair<Hasher::HashDigest, std::uintmax_t>> { + static constexpr std::size_t kChunkSize{4048}; + try { + auto hasher = Hasher(); + auto size = std::filesystem::file_size(file_path); + if (HashType() == JustHash::Native) { + hasher.Update( + (as_tree ? std::string{"tree "} : std::string{"blob "}) + + std::to_string(size) + '\0'); + } + std::string chunk{}; + chunk.resize(kChunkSize); + std::ifstream file_reader(file_path.string(), std::ios::binary); + if (file_reader.is_open()) { + auto chunk_size = gsl::narrow<std::streamsize>(chunk.size()); + do { + file_reader.read(chunk.data(), chunk_size); + auto count = file_reader.gcount(); + hasher.Update(chunk.substr(0, gsl::narrow<std::size_t>(count))); + } while (file_reader.good()); + file_reader.close(); + return std::make_pair(std::move(hasher).Finalize(), size); + } + } catch (std::exception const& e) { + Logger::Log(LogLevel::Debug, + "Error while trying to hash {}: {}", + file_path.string(), + e.what()); + } + return std::nullopt; +} diff --git a/src/buildtool/crypto/hash_function.hpp b/src/buildtool/crypto/hash_function.hpp index 44341777..fa141ed2 100644 --- a/src/buildtool/crypto/hash_function.hpp +++ b/src/buildtool/crypto/hash_function.hpp @@ -16,9 +16,11 @@ #define INCLUDED_SRC_BUILDTOOL_CRYPTO_HASH_FUNCTION_HPP #include <cstdint> +#include <filesystem> #include <functional> #include <optional> #include <string> +#include <utility> #include "src/buildtool/crypto/hasher.hpp" @@ -53,6 +55,12 @@ class HashFunction { return ComputeTaggedHash(data, kBlobTagCreator); } + /// \brief Compute the blob hash of a file or std::nullopt on IO error. + [[nodiscard]] static auto ComputeHashFile( + const std::filesystem::path& file_path, + bool as_tree) noexcept + -> std::optional<std::pair<Hasher::HashDigest, std::uintmax_t>>; + /// \brief Compute a tree hash. [[nodiscard]] static auto ComputeTreeHash(std::string const& data) noexcept -> Hasher::HashDigest { |