#pragma once #include #include #include #include #include class SynthFSInode; class SynthFS : public FS { public: virtual ~SynthFS() override; static NonnullRefPtr create(); virtual bool initialize() override; virtual const char* class_name() const override; virtual InodeIdentifier root_inode() const override; virtual RefPtr create_inode(InodeIdentifier parentInode, const String& name, mode_t, off_t size, dev_t, int& error) override; virtual RefPtr create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override; virtual RefPtr get_inode(InodeIdentifier) const override; protected: typedef unsigned InodeIndex; InodeIndex generate_inode_index(); static constexpr InodeIndex RootInodeIndex = 1; SynthFS(); NonnullRefPtr create_directory(String&& name); NonnullRefPtr create_generated_file(String&& name, Function&&, mode_t = 0100644); NonnullRefPtr create_generated_file(String&& name, Function&&, Function&&, mode_t = 0100644); InodeIdentifier add_file(RefPtr&&, 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, u8* buffer, FileDescription*) const override; virtual InodeMetadata metadata() const override; virtual bool traverse_as_directory(Function) const override; virtual InodeIdentifier lookup(StringView name) override; virtual void flush_metadata() override; virtual ssize_t write_bytes(off_t, ssize_t, const u8* buffer, FileDescription*) override; virtual KResult add_child(InodeIdentifier child_id, const StringView& name, mode_t) override; virtual KResult remove_child(const StringView& name) 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; 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()); }