#pragma once
#include "file.h"
namespace wasmfs {
static inline std::shared_ptr<File> devirtualize(std::shared_ptr<File>);
class VirtualDataFile : public DataFile {
protected:
std::shared_ptr<DataFile> real;
public:
VirtualDataFile(std::shared_ptr<DataFile> real, backend_t backend)
: DataFile(real->locked().getMode(), backend), real(real) {}
protected:
virtual off_t getSize() override { return real->locked().getSize(); }
virtual int open(oflags_t flags) override {
return real->locked().open(flags);
}
virtual int close() override { return real->locked().close(); }
virtual ssize_t read(uint8_t* buf, size_t len, off_t offset) override {
return real->locked().read(buf, len, offset);
}
virtual ssize_t write(const uint8_t* buf, size_t len, off_t offset) override {
return real->locked().write(buf, len, offset);
}
virtual int setSize(off_t size) override {
return real->locked().setSize(size);
}
virtual int flush() override { return real->locked().flush(); }
friend std::shared_ptr<File> devirtualize(std::shared_ptr<File>);
};
class VirtualDirectory : public Directory {
protected:
std::shared_ptr<Directory> real;
public:
VirtualDirectory(std::shared_ptr<Directory> real, backend_t backend)
: Directory(real->locked().getMode(), backend), real(real) {}
protected:
virtual std::shared_ptr<File> getChild(const std::string& name) override {
return real->locked().getChild(name);
}
virtual std::shared_ptr<DataFile> insertDataFile(const std::string& name,
mode_t mode) override {
return real->locked().insertDataFile(name, mode);
}
virtual std::shared_ptr<Directory> insertDirectory(const std::string& name,
mode_t mode) override {
return real->locked().insertDirectory(name, mode);
}
virtual std::shared_ptr<Symlink>
insertSymlink(const std::string& name, const std::string& target) override {
return real->locked().insertSymlink(name, target);
}
virtual int insertMove(const std::string& name,
std::shared_ptr<File> file) override {
return real->locked().insertMove(name, file);
}
virtual int removeChild(const std::string& name) override {
return real->locked().removeChild(name);
}
virtual ssize_t getNumEntries() override {
return real->locked().getNumEntries();
}
virtual MaybeEntries getEntries() override {
return real->locked().getEntries();
}
virtual std::string getName(std::shared_ptr<File> file) override {
return real->locked().getName(file);
}
friend std::shared_ptr<File> devirtualize(std::shared_ptr<File>);
};
class VirtualSymlink : public Symlink {
protected:
std::shared_ptr<Symlink> real;
public:
VirtualSymlink(std::shared_ptr<Symlink> real, backend_t backend)
: Symlink(backend), real(real) {}
protected:
virtual std::string getTarget() const override { return real->getTarget(); }
friend std::shared_ptr<File> devirtualize(std::shared_ptr<File>);
};
inline std::shared_ptr<File> devirtualize(std::shared_ptr<File> file) {
if (file->is<DataFile>()) {
return std::static_pointer_cast<VirtualDataFile>(file)->real;
} else if (file->is<Directory>()) {
return std::static_pointer_cast<VirtualDirectory>(file)->real;
} else if (file->is<Symlink>()) {
return std::static_pointer_cast<VirtualDirectory>(file)->real;
}
WASMFS_UNREACHABLE("unexpected file kind");
}
}