summaryrefslogtreecommitdiff
path: root/src/buildtool/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/buildtool/common')
-rw-r--r--src/buildtool/common/TARGETS4
-rw-r--r--src/buildtool/common/bazel_digest_factory.cpp49
-rw-r--r--src/buildtool/common/bazel_digest_factory.hpp44
3 files changed, 85 insertions, 12 deletions
diff --git a/src/buildtool/common/TARGETS b/src/buildtool/common/TARGETS
index e2db528c..88364386 100644
--- a/src/buildtool/common/TARGETS
+++ b/src/buildtool/common/TARGETS
@@ -43,12 +43,16 @@
{ "type": ["@", "rules", "CC", "library"]
, "name": ["bazel_digest_factory"]
, "hdrs": ["bazel_digest_factory.hpp"]
+ , "srcs": ["bazel_digest_factory.cpp"]
, "deps":
[ "bazel_types"
, ["src/buildtool/crypto", "hash_function"]
+ , ["src/buildtool/crypto", "hash_info"]
, ["src/buildtool/file_system", "object_type"]
, ["src/utils/cpp", "gsl"]
+ , ["src/utils/cpp", "expected"]
]
+ , "private-deps": [["src/buildtool/crypto", "hasher"]]
, "stage": ["src", "buildtool", "common"]
}
, "common":
diff --git a/src/buildtool/common/bazel_digest_factory.cpp b/src/buildtool/common/bazel_digest_factory.cpp
new file mode 100644
index 00000000..4ff885aa
--- /dev/null
+++ b/src/buildtool/common/bazel_digest_factory.cpp
@@ -0,0 +1,49 @@
+// Copyright 2024 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/common/bazel_digest_factory.hpp"
+
+#include <utility>
+
+#include "src/buildtool/crypto/hasher.hpp"
+
+auto BazelDigestFactory::Create(HashInfo const& hash_info,
+ std::int64_t size) noexcept
+ -> bazel_re::Digest {
+ auto hash = hash_info.HashType() == HashFunction::Type::GitSHA1
+ ? Prefix(hash_info.Hash(), hash_info.IsTree())
+ : hash_info.Hash();
+
+ bazel_re::Digest digest{};
+ digest.set_hash(std::move(hash));
+ digest.set_size_bytes(size);
+ return digest;
+}
+
+auto BazelDigestFactory::ToHashInfo(HashFunction::Type hash_type,
+ bazel_re::Digest const& digest) noexcept
+ -> expected<HashInfo, std::string> {
+ bool const is_prefixed = IsPrefixed(hash_type, digest.hash());
+
+ auto hash = is_prefixed ? Unprefix(digest.hash()) : digest.hash();
+ auto const is_tree = is_prefixed and digest.hash().starts_with(kTreeTag);
+ return HashInfo::Create(hash_type, std::move(hash), is_tree);
+}
+
+auto BazelDigestFactory::IsPrefixed(HashFunction::Type hash_type,
+ std::string const& hash) noexcept -> bool {
+ auto const tagged_length =
+ HashFunction{hash_type}.MakeHasher().GetHashLength() + kTagLength;
+ return hash.size() == tagged_length;
+}
diff --git a/src/buildtool/common/bazel_digest_factory.hpp b/src/buildtool/common/bazel_digest_factory.hpp
index e08eabb7..67ee35cb 100644
--- a/src/buildtool/common/bazel_digest_factory.hpp
+++ b/src/buildtool/common/bazel_digest_factory.hpp
@@ -22,13 +22,33 @@
#include "gsl/gsl"
#include "src/buildtool/common/bazel_types.hpp"
#include "src/buildtool/crypto/hash_function.hpp"
+#include "src/buildtool/crypto/hash_info.hpp"
#include "src/buildtool/file_system/object_type.hpp"
+#include "src/utils/cpp/expected.hpp"
class BazelDigestFactory final {
static constexpr auto kBlobTag = "62";
static constexpr auto kTreeTag = "74";
+ static constexpr std::size_t kTagLength = 2;
public:
+ /// \brief Create bazel_re::Digest from preliminarily validated data.
+ /// \param hash_data Validated hash
+ /// \param size Size of the content
+ [[nodiscard]] static auto Create(HashInfo const& hash_info,
+ std::int64_t size) noexcept
+ -> bazel_re::Digest;
+
+ /// \brief Validate bazel_re::Digest
+ /// \param hash_type Type of the hash function that was used for creation
+ /// of the hash
+ /// \param digest Digest to be validated
+ /// \return Validated hash on success or an error message on failure.
+ [[nodiscard]] static auto ToHashInfo(
+ HashFunction::Type hash_type,
+ bazel_re::Digest const& digest) noexcept
+ -> expected<HashInfo, std::string>;
+
/// \brief Hash content using hash function and return a valid
/// bazel_re::Digest
/// \tparam kType Type of the hashing algorithm to be used
@@ -39,18 +59,9 @@ class BazelDigestFactory final {
[[nodiscard]] static auto HashDataAs(HashFunction hash_function,
std::string const& content)
-> bazel_re::Digest {
- static constexpr bool kIsTree = IsTreeObject(kType);
- auto const hash_digest = kIsTree ? hash_function.HashTreeData(content)
- : hash_function.HashBlobData(content);
-
- auto hash = hash_function.GetType() == HashFunction::Type::GitSHA1
- ? Prefix(hash_digest.HexString(), kIsTree)
- : hash_digest.HexString();
-
- bazel_re::Digest digest{};
- digest.set_hash(std::move(hash));
- digest.set_size_bytes(gsl::narrow<std::int64_t>(content.size()));
- return digest;
+ auto const hash_info =
+ HashInfo::HashData(hash_function, content, IsTreeObject(kType));
+ return Create(hash_info, gsl::narrow<std::int64_t>(content.size()));
}
private:
@@ -58,6 +69,15 @@ class BazelDigestFactory final {
bool is_tree) noexcept -> std::string {
return (is_tree ? kTreeTag : kBlobTag) + hash;
}
+
+ [[nodiscard]] static auto Unprefix(std::string const& hash) noexcept
+ -> std::string {
+ return hash.substr(kTagLength);
+ }
+
+ [[nodiscard]] static auto IsPrefixed(HashFunction::Type hash_type,
+ std::string const& hash) noexcept
+ -> bool;
};
#endif // INCLUDED_SRC_BUILDTOOL_COMMON_BAZEL_DIGEST_FACTORY_HPP