aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/archive.hh
diff options
context:
space:
mode:
authorJade Lovelace <lix@jade.fyi>2024-09-11 00:27:39 -0700
committerJade Lovelace <lix@jade.fyi>2024-09-13 17:11:43 -0700
commitca1dc3f70bf98e2424b7b2666ee2180675b67451 (patch)
tree95b6456887db362a627223dda55f22192f5832b0 /src/libutil/archive.hh
parent81c2e0ac8e76ddb3fd3c8e2ce59929853614b1b6 (diff)
archive: refactor bad mutable-state API in the NAR parse listener
Remove the mutable state stuff that assumes that one file is being written a time. It's true that we don't write multiple files interleaved, but that mutable state is evil. Change-Id: Ia1481da48255d901e4b09a9b783e7af44fae8cff
Diffstat (limited to 'src/libutil/archive.hh')
-rw-r--r--src/libutil/archive.hh43
1 files changed, 34 insertions, 9 deletions
diff --git a/src/libutil/archive.hh b/src/libutil/archive.hh
index 5e8db4c53..c633bee00 100644
--- a/src/libutil/archive.hh
+++ b/src/libutil/archive.hh
@@ -83,15 +83,40 @@ WireFormatGenerator dumpString(std::string_view s);
*/
struct NARParseVisitor
{
- virtual void createDirectory(const Path & path) { };
-
- virtual void createRegularFile(const Path & path) { };
- virtual void closeRegularFile() { };
- virtual void isExecutable() { };
- virtual void preallocateContents(uint64_t size) { };
- virtual void receiveContents(std::string_view data) { };
-
- virtual void createSymlink(const Path & path, const std::string & target) { };
+ /**
+ * A type-erased file handle specific to this particular NARParseVisitor.
+ */
+ struct FileHandle
+ {
+ FileHandle() {}
+ FileHandle(FileHandle const &) = delete;
+ FileHandle & operator=(FileHandle &) = delete;
+
+ /** Puts one block of data into the file */
+ virtual void receiveContents(std::string_view data) { }
+
+ /**
+ * Explicitly closes the file. Further operations may throw an assert.
+ * This exists so that closing can fail and throw an exception without doing so in a destructor.
+ */
+ virtual void close() { }
+
+ virtual ~FileHandle() = default;
+ };
+
+ virtual void createDirectory(const Path & path) { }
+
+ /**
+ * Creates a regular file in the extraction output with the given size and executable flag.
+ * The size is guaranteed to be the true size of the file.
+ */
+ [[nodiscard]]
+ virtual std::unique_ptr<FileHandle> createRegularFile(const Path & path, uint64_t size, bool executable)
+ {
+ return std::make_unique<FileHandle>();
+ }
+
+ virtual void createSymlink(const Path & path, const std::string & target) { }
};
namespace nar {