#pragma once #include "FileSystem.h" #include "UnixTypes.h" #include class SynthFSInode; class SynthFS : public FS { public: virtual ~SynthFS() override; static Retained create(); virtual bool initialize() override; virtual const char* class_name() const override; virtual InodeIdentifier root_inode() const override; virtual RetainPtr create_inode(InodeIdentifier parentInode, const String& name, mode_t, unsigned size, int& error) override; virtual RetainPtr create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override; virtual RetainPtr get_inode(InodeIdentifier) const override; protected: typedef unsigned InodeIndex; InodeIndex generate_inode_index(); static constexpr InodeIndex RootInodeIndex = 1; SynthFS(); Retained create_directory(String&& name); Retained create_text_file(String&& name, ByteBuffer&&, mode_t = 0010644); Retained create_generated_file(String&& name, Function&&, mode_t = 0100644); Retained create_generated_file(String&& name, Function&&, Function&&, mode_t = 0100644); InodeIdentifier add_file(RetainPtr&&, InodeIndex parent = RootInodeIndex); bool remove_file(InodeIndex); private: InodeIndex m_next_inode_index { 2 }; HashMap> m_inodes; }; struct SynthFSInodeCustomData { virtual ~SynthFSInodeCustomData(); }; class SynthFSInode final : public Inode { friend class SynthFS; friend class DevPtsFS; public: virtual ~SynthFSInode() override; void set_custom_data(OwnPtr&& custom_data) { m_custom_data = move(custom_data); } SynthFSInodeCustomData* custom_data() { return m_custom_data.ptr(); } const SynthFSInodeCustomData* custom_data() const { return m_custom_data.ptr(); } private: // ^Inode virtual ssize_t read_bytes(off_t, ssize_t, byte* buffer, FileDescriptor*) const override; virtual InodeMetadata metadata() const override; virtual bool traverse_as_directory(Function) const override; virtual InodeIdentifier lookup(const String& name) override; virtual String reverse_lookup(InodeIdentifier) override; virtual void flush_metadata() override; virtual ssize_t write_bytes(off_t, ssize_t, const byte* buffer, FileDescriptor*) override; virtual KResult add_child(InodeIdentifier child_id, const String& name, byte file_type) override; virtual KResult remove_child(const String& name) override; virtual RetainPtr parent() const override; virtual size_t directory_entry_count() const override; virtual KResult chmod(mode_t) override; virtual KResult chown(uid_t, gid_t) override; SynthFS& fs(); const SynthFS& fs() const; SynthFSInode(SynthFS&, unsigned index); String m_name; InodeIdentifier m_parent; ByteBuffer m_data; Function m_generator; Function m_write_callback; Vector m_children; InodeMetadata m_metadata; OwnPtr m_custom_data; }; inline SynthFS& SynthFSInode::fs() { return static_cast(Inode::fs()); } inline const SynthFS& SynthFSInode::fs() const { return static_cast(Inode::fs()); }