aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/path.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-06-16 14:16:39 +0200
committerEelco Dolstra <edolstra@gmail.com>2020-06-16 14:28:41 +0200
commit759947bf72c134592f0ce23d385e48095bd0a301 (patch)
tree98868cbafb2baa1d369cf2a1464e9fa4805ab3a7 /src/libstore/path.cc
parent72e17290d457a8e911f126d21b74c315b034189d (diff)
StorePath: Rewrite in C++
On nix-env -qa -f '<nixpkgs>', this reduces maximum RSS by 20970 KiB and runtime by 0.8%. This is mostly because we're not parsing the hash part as a hash anymore (just validating that it consists of base-32 characters). Also, replace storePathToHash() by StorePath::hashPart().
Diffstat (limited to 'src/libstore/path.cc')
-rw-r--r--src/libstore/path.cc66
1 files changed, 30 insertions, 36 deletions
diff --git a/src/libstore/path.cc b/src/libstore/path.cc
index 9a28aa96a..bb2089ea4 100644
--- a/src/libstore/path.cc
+++ b/src/libstore/path.cc
@@ -2,38 +2,38 @@
namespace nix {
-extern "C" {
- rust::Result<StorePath> ffi_StorePath_new(rust::StringSlice path, rust::StringSlice storeDir);
- rust::Result<StorePath> ffi_StorePath_new2(unsigned char hash[20], rust::StringSlice storeDir);
- rust::Result<StorePath> ffi_StorePath_fromBaseName(rust::StringSlice baseName);
- rust::String ffi_StorePath_to_string(const StorePath & _this);
- StorePath ffi_StorePath_clone(const StorePath & _this);
- rust::StringSlice ffi_StorePath_name(const StorePath & _this);
-}
-
-StorePath StorePath::make(std::string_view path, std::string_view storeDir)
-{
- return ffi_StorePath_new((rust::StringSlice) path, (rust::StringSlice) storeDir).unwrap();
-}
-
-StorePath StorePath::make(unsigned char hash[20], std::string_view name)
-{
- return ffi_StorePath_new2(hash, (rust::StringSlice) name).unwrap();
-}
+MakeError(BadStorePath, Error);
-StorePath StorePath::fromBaseName(std::string_view baseName)
+static void checkName(std::string_view path, std::string_view name)
{
- return ffi_StorePath_fromBaseName((rust::StringSlice) baseName).unwrap();
+ if (name.empty())
+ throw BadStorePath("store path '%s' has an empty name", path);
+ if (name.size() > 211)
+ throw BadStorePath("store path '%s' has a name longer than 211 characters", path);
+ for (auto c : name)
+ if (!((c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || c == '+' || c == '-' || c == '.' || c == '_' || c == '?' || c == '='))
+ throw BadStorePath("store path '%s' contains illegal character '%s'", path, c);
}
-rust::String StorePath::to_string() const
+StorePath::StorePath(std::string_view _baseName)
+ : baseName(_baseName)
{
- return ffi_StorePath_to_string(*this);
+ if (baseName.size() < HashLen + 1)
+ throw BadStorePath("'%s' is too short to be a valid store path", baseName);
+ for (auto c : hashPart())
+ if (c == 'e' || c == 'o' || c == 'u' || c == 't'
+ || !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z')))
+ throw BadStorePath("store path '%s' contains illegal base-32 character '%s'", baseName, c);
+ checkName(baseName, name());
}
-StorePath StorePath::clone() const
+StorePath::StorePath(const Hash & hash, std::string_view _name)
+ : baseName((hash.to_string(Base32, false) + "-").append(std::string(_name)))
{
- return ffi_StorePath_clone(*this);
+ checkName(baseName, name());
}
bool StorePath::isDerivation() const
@@ -41,18 +41,14 @@ bool StorePath::isDerivation() const
return hasSuffix(name(), drvExtension);
}
-std::string_view StorePath::name() const
-{
- return ffi_StorePath_name(*this);
-}
-
-StorePath StorePath::dummy(
- StorePath::make(
- (unsigned char *) "xxxxxxxxxxxxxxxxxxxx", "x"));
+StorePath StorePath::dummy("ffffffffffffffffffffffffffffffff-x");
StorePath Store::parseStorePath(std::string_view path) const
{
- return StorePath::make(path, storeDir);
+ auto p = canonPath(std::string(path));
+ if (dirOf(p) != storeDir)
+ throw BadStorePath("path '%s' is not in the Nix store", p);
+ return StorePath(baseNameOf(p));
}
std::optional<StorePath> Store::maybeParseStorePath(std::string_view path) const
@@ -78,9 +74,7 @@ StorePathSet Store::parseStorePathSet(const PathSet & paths) const
std::string Store::printStorePath(const StorePath & path) const
{
- auto s = storeDir + "/";
- s += (std::string_view) path.to_string();
- return s;
+ return (storeDir + "/").append(path.to_string());
}
PathSet Store::printStorePathSet(const StorePathSet & paths) const