Skip to content

Commit

Permalink
Create MemorySink
Browse files Browse the repository at this point in the history
This is for writing to a `MemorySourceAccessor`.
  • Loading branch information
Ericson2314 committed Nov 4, 2023
1 parent 9b880e3 commit 3015a7b
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/libutil/memory-source-accessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,60 @@ CanonPath MemorySourceAccessor::addFile(CanonPath path, std::string && contents)
return path;
}


using File = MemorySourceAccessor::File;

void MemorySink::createDirectory(const Path & path)
{
auto * f = dst.open(CanonPath{path}, File { File::Directory { } });
if (!f)
throw Error("file '%s' cannot be made because some parent file is not a directory", path);

if (!std::holds_alternative<File::Directory>(f->raw))
throw Error("file '%s' is not a directory", path);
};

void MemorySink::createRegularFile(const Path & path)
{
auto * f = dst.open(CanonPath{path}, File { File::Regular {} });
if (!f)
throw Error("file '%s' cannot be made because some parent file is not a directory", path);
if (!(r = std::get_if<File::Regular>(&f->raw)))
throw Error("file '%s' is not a regular file", path);
}

void MemorySink::closeRegularFile()
{
r = nullptr;
}

void MemorySink::isExecutable()
{
assert(r);
r->executable = true;
}

void MemorySink::preallocateContents(uint64_t len)
{
assert(r);
r->contents.reserve(len);
}

void MemorySink::receiveContents(std::string_view data)
{
assert(r);
r->contents += data;
}

void MemorySink::createSymlink(const Path & path, const std::string & target)
{
auto * f = dst.open(CanonPath{path}, File { File::Symlink { } });
if (!f)
throw Error("file '%s' cannot be made because some parent file is not a directory", path);
if (auto * s = std::get_if<File::Symlink>(&f->raw))
s->target = target;
else
throw Error("file '%s' is not a symbolic link", path);
}

}
25 changes: 25 additions & 0 deletions src/libutil/memory-source-accessor.hh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "source-accessor.hh"
#include "fs-sink.hh"
#include "variant-wrapper.hh"

namespace nix {
Expand Down Expand Up @@ -71,4 +72,28 @@ struct MemorySourceAccessor : virtual SourceAccessor
CanonPath addFile(CanonPath path, std::string && contents);
};

/**
* Write to a `MemorySourceAccessor` at the given path
*/
struct MemorySink : ParseSink
{
MemorySourceAccessor & dst;

MemorySink(MemorySourceAccessor & dst) : dst(dst) { }

void createDirectory(const Path & path) override;

void createRegularFile(const Path & path) override;
void receiveContents(std::string_view data) override;
void isExecutable() override;
void closeRegularFile() override;

void createSymlink(const Path & path, const std::string & target) override;

void preallocateContents(uint64_t size) override;

private:
MemorySourceAccessor::File::Regular * r;
};

}

0 comments on commit 3015a7b

Please sign in to comment.