summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/crypto/TARGETS5
-rw-r--r--src/buildtool/crypto/hash_function.cpp56
-rw-r--r--src/buildtool/crypto/hash_function.hpp8
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 {