aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/content-address.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/content-address.cc')
-rw-r--r--src/libstore/content-address.cc132
1 files changed, 103 insertions, 29 deletions
diff --git a/src/libstore/content-address.cc b/src/libstore/content-address.cc
index d9a8a4535..034a9485b 100644
--- a/src/libstore/content-address.cc
+++ b/src/libstore/content-address.cc
@@ -22,6 +22,27 @@ std::string makeFileIngestionPrefix(FileIngestionMethod m)
}
}
+std::string makeContentAddressingPrefix(ContentAddressMethod m) {
+ return std::visit(overloaded {
+ [](TextHashMethod) -> std::string { return "text:"; },
+ [](FileIngestionMethod m2) {
+ /* Not prefixed for back compat with things that couldn't produce text before. */
+ return makeFileIngestionPrefix(m2);
+ },
+ }, m);
+}
+
+ContentAddressMethod parseContentAddressingPrefix(std::string_view & m)
+{
+ ContentAddressMethod method = FileIngestionMethod::Flat;
+ if (splitPrefix(m, "r:"))
+ method = FileIngestionMethod::Recursive;
+ else if (splitPrefix(m, "text:"))
+ method = TextHashMethod {};
+ return method;
+}
+
+
std::string makeFixedOutputCA(FileIngestionMethod method, const Hash & hash)
{
return "fixed:"
@@ -44,14 +65,14 @@ std::string renderContentAddress(ContentAddress ca)
}, ca);
}
-std::string renderContentAddressMethod(ContentAddressMethod cam)
+std::string renderContentAddressMethodAndHash(ContentAddressMethod cam, HashType ht)
{
return std::visit(overloaded {
- [](TextHashMethod & th) {
- return std::string{"text:"} + printHashType(htSHA256);
+ [&](TextHashMethod & th) {
+ return std::string{"text:"} + printHashType(ht);
},
- [](FixedOutputHashMethod & fshm) {
- return "fixed:" + makeFileIngestionPrefix(fshm.fileIngestionMethod) + printHashType(fshm.hashType);
+ [&](FileIngestionMethod & fim) {
+ return "fixed:" + makeFileIngestionPrefix(fim) + printHashType(ht);
}
}, cam);
}
@@ -59,7 +80,7 @@ std::string renderContentAddressMethod(ContentAddressMethod cam)
/*
Parses content address strings up to the hash.
*/
-static ContentAddressMethod parseContentAddressMethodPrefix(std::string_view & rest)
+static std::pair<ContentAddressMethod, HashType> parseContentAddressMethodPrefix(std::string_view & rest)
{
std::string_view wholeInput { rest };
@@ -83,19 +104,19 @@ static ContentAddressMethod parseContentAddressMethodPrefix(std::string_view & r
if (prefix == "text") {
// No parsing of the ingestion method, "text" only support flat.
HashType hashType = parseHashType_();
- if (hashType != htSHA256)
- throw Error("text content address hash should use %s, but instead uses %s",
- printHashType(htSHA256), printHashType(hashType));
- return TextHashMethod {};
+ return {
+ TextHashMethod {},
+ std::move(hashType),
+ };
} else if (prefix == "fixed") {
// Parse method
auto method = FileIngestionMethod::Flat;
if (splitPrefix(rest, "r:"))
method = FileIngestionMethod::Recursive;
HashType hashType = parseHashType_();
- return FixedOutputHashMethod {
- .fileIngestionMethod = method,
- .hashType = std::move(hashType),
+ return {
+ std::move(method),
+ std::move(hashType),
};
} else
throw UsageError("content address prefix '%s' is unrecognized. Recogonized prefixes are 'text' or 'fixed'", prefix);
@@ -104,25 +125,25 @@ static ContentAddressMethod parseContentAddressMethodPrefix(std::string_view & r
ContentAddress parseContentAddress(std::string_view rawCa) {
auto rest = rawCa;
- ContentAddressMethod caMethod = parseContentAddressMethodPrefix(rest);
+ auto [caMethod, hashType_] = parseContentAddressMethodPrefix(rest);
+ auto hashType = hashType_; // work around clang bug
- return std::visit(
- overloaded {
- [&](TextHashMethod & thm) {
- return ContentAddress(TextHash {
- .hash = Hash::parseNonSRIUnprefixed(rest, htSHA256)
- });
- },
- [&](FixedOutputHashMethod & fohMethod) {
- return ContentAddress(FixedOutputHash {
- .method = fohMethod.fileIngestionMethod,
- .hash = Hash::parseNonSRIUnprefixed(rest, std::move(fohMethod.hashType)),
- });
- },
- }, caMethod);
+ return std::visit(overloaded {
+ [&](TextHashMethod &) {
+ return ContentAddress(TextHash {
+ .hash = Hash::parseNonSRIUnprefixed(rest, hashType)
+ });
+ },
+ [&](FileIngestionMethod & fim) {
+ return ContentAddress(FixedOutputHash {
+ .method = fim,
+ .hash = Hash::parseNonSRIUnprefixed(rest, hashType),
+ });
+ },
+ }, caMethod);
}
-ContentAddressMethod parseContentAddressMethod(std::string_view caMethod)
+std::pair<ContentAddressMethod, HashType> parseContentAddressMethod(std::string_view caMethod)
{
std::string asPrefix = std::string{caMethod} + ":";
// parseContentAddressMethodPrefix takes its argument by reference
@@ -140,6 +161,42 @@ std::string renderContentAddress(std::optional<ContentAddress> ca)
return ca ? renderContentAddress(*ca) : "";
}
+ContentAddressWithReferences contentAddressFromMethodHashAndRefs(
+ ContentAddressMethod method, Hash && hash, StoreReferences && refs)
+{
+ return std::visit(overloaded {
+ [&](TextHashMethod _) -> ContentAddressWithReferences {
+ if (refs.self)
+ throw UsageError("Cannot have a self reference with text hashing scheme");
+ return TextInfo {
+ .hash = { .hash = std::move(hash) },
+ .references = std::move(refs.others),
+ };
+ },
+ [&](FileIngestionMethod m2) -> ContentAddressWithReferences {
+ return FixedOutputInfo {
+ .hash = {
+ .method = m2,
+ .hash = std::move(hash),
+ },
+ .references = std::move(refs),
+ };
+ },
+ }, method);
+}
+
+ContentAddressMethod getContentAddressMethod(const ContentAddressWithReferences & ca)
+{
+ return std::visit(overloaded {
+ [](const TextInfo & th) -> ContentAddressMethod {
+ return TextHashMethod {};
+ },
+ [](const FixedOutputInfo & fsh) -> ContentAddressMethod {
+ return fsh.hash.method;
+ },
+ }, ca);
+}
+
Hash getContentAddressHash(const ContentAddress & ca)
{
return std::visit(overloaded {
@@ -179,4 +236,21 @@ ContentAddressWithReferences caWithoutRefs(const ContentAddress & ca) {
}, ca);
}
+Hash getContentAddressHash(const ContentAddressWithReferences & ca)
+{
+ return std::visit(overloaded {
+ [](const TextInfo & th) {
+ return th.hash.hash;
+ },
+ [](const FixedOutputInfo & fsh) {
+ return fsh.hash.hash;
+ },
+ }, ca);
+}
+
+std::string printMethodAlgo(const ContentAddressWithReferences & ca) {
+ return makeContentAddressingPrefix(getContentAddressMethod(ca))
+ + printHashType(getContentAddressHash(ca).type);
+}
+
}