diff options
author | eldritch horrors <pennae@lix.systems> | 2024-03-23 00:47:16 +0100 |
---|---|---|
committer | eldritch horrors <pennae@lix.systems> | 2024-07-05 22:28:16 +0000 |
commit | 06220a71c1430c97bfcd8012b00530a987e40e97 (patch) | |
tree | 69f230d669db2804379a33fc1ec6e3d3fc908c67 /src/libutil | |
parent | b51ea465de48e4c5516ba0182cc642b4e644be10 (diff) |
libstore: convert dumpPath to a generator
Change-Id: Ic4cf5562504aa29130304469936f958c0426e5ef
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/archive.cc | 78 | ||||
-rw-r--r-- | src/libutil/archive.hh | 6 | ||||
-rw-r--r-- | src/libutil/hash.cc | 2 | ||||
-rw-r--r-- | src/libutil/source-path.hh | 2 |
4 files changed, 53 insertions, 35 deletions
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index 1b42ee4b5..2ac9f3dcd 100644 --- a/src/libutil/archive.cc +++ b/src/libutil/archive.cc @@ -40,10 +40,10 @@ static GlobalConfig::Register rArchiveSettings(&archiveSettings); PathFilter defaultPathFilter = [](const Path &) { return true; }; -static void dumpContents(const Path & path, off_t size, - Sink & sink) +static WireFormatGenerator dumpContents(const Path & path, off_t size) { - sink << "contents" << size; + co_yield "contents"; + co_yield size; AutoCloseFD fd{open(path.c_str(), O_RDONLY | O_CLOEXEC)}; if (!fd) throw SysError("opening file '%1%'", path); @@ -55,31 +55,35 @@ static void dumpContents(const Path & path, off_t size, auto n = std::min(left, buf.size()); readFull(fd.get(), buf.data(), n); left -= n; - sink({buf.data(), n}); + co_yield std::span{buf.data(), n}; } - writePadding(size, sink); + co_yield SerializingTransform::padding(size); } -static time_t dump(const Path & path, Sink & sink, PathFilter & filter) +static WireFormatGenerator dump(const Path & path, time_t & mtime, PathFilter & filter) { checkInterrupt(); auto st = lstat(path); - time_t result = st.st_mtime; + mtime = st.st_mtime; - sink << "("; + co_yield "("; if (S_ISREG(st.st_mode)) { - sink << "type" << "regular"; - if (st.st_mode & S_IXUSR) - sink << "executable" << ""; - dumpContents(path, st.st_size, sink); + co_yield "type"; + co_yield "regular"; + if (st.st_mode & S_IXUSR) { + co_yield "executable"; + co_yield ""; + } + co_yield dumpContents(path, st.st_size); } else if (S_ISDIR(st.st_mode)) { - sink << "type" << "directory"; + co_yield "type"; + co_yield "directory"; /* If we're on a case-insensitive system like macOS, undo the case hack applied by restorePath(). */ @@ -101,41 +105,55 @@ static time_t dump(const Path & path, Sink & sink, PathFilter & filter) for (auto & i : unhacked) if (filter(path + "/" + i.first)) { - sink << "entry" << "(" << "name" << i.first << "node"; - auto tmp_mtime = dump(path + "/" + i.second, sink, filter); - if (tmp_mtime > result) { - result = tmp_mtime; + co_yield "entry"; + co_yield "("; + co_yield "name"; + co_yield i.first; + co_yield "node"; + time_t tmp_mtime; + co_yield dump(path + "/" + i.second, tmp_mtime, filter); + if (tmp_mtime > mtime) { + mtime = tmp_mtime; } - sink << ")"; + co_yield ")"; } } - else if (S_ISLNK(st.st_mode)) - sink << "type" << "symlink" << "target" << readLink(path); + else if (S_ISLNK(st.st_mode)) { + co_yield "type"; + co_yield "symlink"; + co_yield "target"; + co_yield readLink(path); + } else throw Error("file '%1%' has an unsupported type", path); - sink << ")"; - - return result; + co_yield ")"; } -time_t dumpPathAndGetMtime(const Path & path, Sink & sink, PathFilter & filter) +WireFormatGenerator dumpPathAndGetMtime(Path path, time_t & mtime, PathFilter & filter) { - sink << narVersionMagic1; - return dump(path, sink, filter); + co_yield narVersionMagic1; + co_yield dump(path, mtime, filter); } -void dumpPath(const Path & path, Sink & sink, PathFilter & filter) +WireFormatGenerator dumpPath(Path path, PathFilter & filter) { - dumpPathAndGetMtime(path, sink, filter); + time_t ignored; + co_yield dumpPathAndGetMtime(path, ignored, filter); } -void dumpString(std::string_view s, Sink & sink) +WireFormatGenerator dumpString(std::string_view s) { - sink << narVersionMagic1 << "(" << "type" << "regular" << "contents" << s << ")"; + co_yield narVersionMagic1; + co_yield "("; + co_yield "type"; + co_yield "regular"; + co_yield "contents"; + co_yield s; + co_yield ")"; } diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh index f163a1947..7fc9b1b73 100644 --- a/src/libutil/archive.hh +++ b/src/libutil/archive.hh @@ -57,13 +57,13 @@ namespace nix { * `+` denotes string concatenation. * ``` */ -void dumpPath(const Path & path, Sink & sink, +WireFormatGenerator dumpPath(Path path, PathFilter & filter = defaultPathFilter); /** * Same as dumpPath(), but returns the last modified date of the path. */ -time_t dumpPathAndGetMtime(const Path & path, Sink & sink, +WireFormatGenerator dumpPathAndGetMtime(Path path, time_t & mtime, PathFilter & filter = defaultPathFilter); /** @@ -71,7 +71,7 @@ time_t dumpPathAndGetMtime(const Path & path, Sink & sink, * * @param s Contents of the file. */ -void dumpString(std::string_view s, Sink & sink); +WireFormatGenerator dumpString(std::string_view s); /** * \todo Fix this API, it sucks. diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index 822fa150e..c0ad7f5fa 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -370,7 +370,7 @@ HashResult hashPath( HashType ht, const Path & path, PathFilter & filter) { HashSink sink(ht); - dumpPath(path, sink, filter); + sink << dumpPath(path, filter); return sink.finish(); } diff --git a/src/libutil/source-path.hh b/src/libutil/source-path.hh index 311e9f7a6..fe5b9b777 100644 --- a/src/libutil/source-path.hh +++ b/src/libutil/source-path.hh @@ -101,7 +101,7 @@ struct SourcePath void dumpPath( Sink & sink, PathFilter & filter = defaultPathFilter) const - { return nix::dumpPath(path.abs(), sink, filter); } + { sink << nix::dumpPath(path.abs(), filter); } /** * Return the location of this path in the "real" filesystem, if |