#pragma once #include "fs/IPack.h" #include "fs/IFilesystem.h" #include "fs/Error.h" #include "fs/Mode.h" #include "fs/Api.h" #include "tl/vector.h" #include "tl/identifier.h" namespace fs { class FS_API CustomFilesystem final : public IFilesystem { public: CustomFilesystem() = default; CustomFilesystem(CustomFilesystem&&) = delete; CustomFilesystem& operator=(CustomFilesystem&&) = delete; CustomFilesystem(const CustomFilesystem&) = delete; CustomFilesystem& operator=(const CustomFilesystem&) = delete; ////////////////////////////////////////////////////////////////////////// // New API TL_DECLARE_INTEGRAL_ID(PackId, uint64_t) tl::result mountFront(AbsPath mountPoint, tl::unique_ref pack); tl::result mountBack(AbsPath mountPoint, tl::unique_ref pack); //unmounts all the packs for this point. It basically deletes the mount point cppcoro::generator> unmountAll(); //When unmounting, the Filesystem returns the pack back to you (if found) tl::unique_ptr unmount(PackId packId); //Returns the physical location of the virtual pack. ConvertToNativePathResult convertToNativePath(const AbsPath& path) const override; OpenSourceResult openSource(const AbsPath& path, SourceFlags flags = SourceFlags()) const override; OpenStreamSourceResult openStreamSource(const AbsPath& path, SourceFlags flags = SourceFlags()) const override; OpenMapSourceResult openMapSource(const AbsPath& path, MapView mapView = MapView(), SourceFlags flags = SourceFlags()) const override; OpenSinkResult openSink(const AbsPath& path, Mode mode, SinkFlags flags = SinkFlags()) override; OpenStreamSinkResult openStreamSink(const AbsPath& path, Mode mode, SinkFlags flags = SinkFlags()) override; OpenMapSinkResult openMapSink(const AbsPath& path, Mode mode, size_t size, SinkFlags flags = SinkFlags()) override; IsFileResult isFile(const AbsPath& path) const override; IsFolderResult isFolder(const AbsPath& path) const override; ExistsResult exists(const AbsPath& path) const override; MakeFolderResult makeFolder(const AbsPath& path) override; RenameResult rename(const AbsPath& path, const AbsPath& newPath) override; RemoveResult remove(const AbsPath& path) override; RemoveRecursivelyResult removeRecursively(const AbsPath& path) override; CopyResult copy(const AbsPath& path, const AbsPath& newPath) override; MakeHardLinkResult makeHardLink(const AbsPath& sourcePath, const AbsPath& linkPath) override; MakeSoftLinkResult makeSymLink(const AbsPath& sourcePath, const AbsPath& linkPath) override; SetWriteTimeResult setWriteTime(const AbsPath& path, time_t time) override; GetStatResult getStat(const AbsPath& path) const override; cppcoro::generator enumerate(const AbsPath& path) const override; cppcoro::generator enumerateRecursively(const AbsPath& path) const override; private: struct PackData { PackId id; tl::unique_ref pack; AbsPath mountPoint; explicit PackData(tl::unique_ref&& pack, PackId i_packId) noexcept : pack(std::move(pack)) , id(i_packId) {} PackData(PackData&& other) noexcept = default; PackData& operator=(PackData&& other) noexcept = default; PackData(const PackData& other) noexcept = delete; PackData& operator=(const PackData& other) noexcept = delete; }; tl::vector m_packsData; void convertToPackPath(AbsPath& packPath, const AbsPath& path, const AbsPath& mountPoint) const; enum class MountPolicy { Front, //the pack will be mounted over packs from the same mount point. This pack will take precedence Back //the pack will be at the bottom of existing packs from the same mount point. Its streams will be searched last }; tl::result mount(AbsPath mountPoint, tl::unique_ref pack, MountPolicy policy); }; }