#pragma once #include "fs/AbsPath.h" #include "tl/ptr.h" #include "fs/Error.h" #include "fs/Mode.h" #include "fs/ISource.h" #include "fs/IMapSource.h" #include "fs/ISink.h" #include "fs/IMapSink.h" #include "fs/Api.h" #include namespace fs { using OpenSourceResult = tl::result, Error>; using OpenStreamSourceResult = tl::result, Error>; using OpenMapSourceResult = tl::result, Error>; using OpenSinkResult = tl::result, Error>; using OpenStreamSinkResult = tl::result, Error>; using OpenMapSinkResult = tl::result, Error>; using ConvertToNativePathResult = tl::result; using IsFileResult = tl::result; using IsFolderResult = tl::result; using ExistsResult = tl::result; using MakeFolderResult = tl::result; using RenameResult = tl::result; using RemoveResult = tl::result; using CopyResult = tl::result; using MakeHardLinkResult = tl::result; using MakeSoftLinkResult = tl::result; using RemoveRecursivelyResult = tl::result; struct Stat { uint64_t size = 0; time_t mTime = 0; time_t aTime = 0; }; using GetStatResult = tl::result; using SetWriteTimeResult = tl::result; struct EnumerateEntry { RelPathView path; bool isFolder = false; }; class FS_API IFilesystem { public: ////////////////////////////////////////////////////////////////////////// virtual ~IFilesystem() = default; using SourceFlag = ISource::Flag; using SourceFlags = ISource::Flags; struct MapView { MapView(uint64_t offset = 0, size_t size = 0) : offset(offset), size(size) {} uint64_t offset; size_t size; //zero size means full size }; //Opens a Read-only Stream //Searches for the stream in the packs from the mountpoint in top to bottom order, and opens if found virtual OpenSourceResult openSource(AbsPathView path, SourceFlags flags = SourceFlags()) const = 0; virtual OpenStreamSourceResult openStreamSource(AbsPathView path, SourceFlags flags = SourceFlags()) const = 0; virtual OpenMapSourceResult openMapSource(AbsPathView path, MapView mapView = MapView(), SourceFlags flags = SourceFlags()) const = 0; using SinkFlag = ISink::Flag; using SinkFlags = ISink::Flags; //Opens a Write-only Stream //Searches for the stream in the packs from the mountpoint in top to bottom order, and opens if found. //If used with the CREATE flag, it will create the stream if not found. //NOTE: this will fail if the mountpoint has only read-only packs (zip files, etc) virtual OpenSinkResult openSink(AbsPathView path, Mode mode, SinkFlags flags = SinkFlags()) = 0; virtual OpenStreamSinkResult openStreamSink(AbsPathView path, Mode mode, SinkFlags flags = SinkFlags()) = 0; virtual OpenMapSinkResult openMapSink(AbsPathView path, Mode mode, size_t size, SinkFlags flags = SinkFlags()) = 0; ////////////////////////////////////////////////////////////////////////// //Returns the physical location of the virtual pack. virtual ConvertToNativePathResult convertToNativePath(AbsPathView path) const = 0; virtual IsFileResult isFile(AbsPathView path) const = 0; virtual IsFolderResult isFolder(AbsPathView path) const = 0; virtual ExistsResult exists(AbsPathView path) const = 0; virtual GetStatResult getStat(AbsPathView path) const = 0; virtual MakeFolderResult makeFolder(AbsPathView path) = 0; virtual RenameResult rename(AbsPathView path, AbsPathView newPath) = 0; //this removes one file or one folder. The folder is removed ONLY if it's empty. If you want to remove a non-empty folder, use RemoveRecursively virtual RemoveResult remove(AbsPathView path) = 0; virtual CopyResult copy(AbsPathView path, AbsPathView newPath) = 0; // Hard links are essentially a new name for the same file data. // The file becomes reference counted and the data will be deleted when all handles to it are removed from the FS. virtual MakeHardLinkResult makeHardLink(AbsPathView sourcePath, AbsPathView linkPath) = 0; // Soft links are like 'weak' pointers to a file. If the original gets deleted the soft link becomes 'null'. virtual MakeSoftLinkResult makeSymLink(AbsPathView sourcePath, AbsPathView linkPath) = 0; //Use this function in order to remove the set folder and all of the files and folders contained inside. //This function is not atomic; if the removal of any of the folders or files fails, the process will be stopped //and the function will return false, but any of the previously removed files will be already removed. virtual RemoveRecursivelyResult removeRecursively(AbsPathView path) = 0; virtual SetWriteTimeResult setWriteTime(AbsPathView path, time_t time) = 0; //The AbsPath is a copy, because there are lifetime subtleties when using coroutines. //In particular, without pass-by-value, this would crash because nobody is storing the rvalue: // for (auto e: fs.enumerate(path + "other folder")) // {} virtual cppcoro::generator enumerate(AbsPath path) const = 0; virtual cppcoro::generator enumerateRecursively(AbsPath path) const = 0; }; }