summaryrefslogtreecommitdiffhomepage
path: root/dev/Kernel/KernelKit/FileManager.hxx
diff options
context:
space:
mode:
authorAmlal EL Mahrouss <amlalelmahrouss@icloud.com>2024-08-15 18:35:34 +0200
committerAmlal EL Mahrouss <amlalelmahrouss@icloud.com>2024-08-15 18:35:34 +0200
commitf3d931aa7cfaf96baef8383b59a8938779541ee7 (patch)
treefdb9fc51badb3dbd03e46ab0766a49d9522e13e2 /dev/Kernel/KernelKit/FileManager.hxx
parent86640816e8b1d3595365f1fcc8a2a9e61fb40ff1 (diff)
[IMP] Moved source code into dev/ folder.
Signed-off-by: Amlal EL Mahrouss <amlalelmahrouss@icloud.com>
Diffstat (limited to 'dev/Kernel/KernelKit/FileManager.hxx')
-rw-r--r--dev/Kernel/KernelKit/FileManager.hxx419
1 files changed, 419 insertions, 0 deletions
diff --git a/dev/Kernel/KernelKit/FileManager.hxx b/dev/Kernel/KernelKit/FileManager.hxx
new file mode 100644
index 00000000..68fa1eb5
--- /dev/null
+++ b/dev/Kernel/KernelKit/FileManager.hxx
@@ -0,0 +1,419 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+/* -------------------------------------------
+
+ Revision History:
+
+ 31/01/24: Update documentation (amlel)
+ 05/07/24: NewFS support, and fork support, updated constants and specs
+ as well.
+
+ ------------------------------------------- */
+
+#pragma once
+
+#ifdef __FSKIT_USE_NEWFS__
+#include <FSKit/NewFS.hxx>
+#endif // __FSKIT_USE_NEWFS__
+
+#include <CompilerKit/CompilerKit.hxx>
+#include <HintKit/CompilerHint.hxx>
+#include <KernelKit/LPC.hxx>
+#include <KernelKit/DebugOutput.hxx>
+#include <NewKit/Stream.hxx>
+#include <NewKit/ErrorOr.hxx>
+#include <NewKit/Ref.hxx>
+
+/// @brief Filesystem manager, abstraction over mounted filesystem.
+/// Works like the VFS or IFS.
+
+#define cRestrictR "r"
+#define cRestrictRB "rb"
+#define cRestrictW "w"
+#define cRestrictWB "rw"
+#define cRestrictRWB "rwb"
+
+#define cRestrictMax 5
+
+#define node_cast(PTR) reinterpret_cast<Kernel::NodePtr>(PTR)
+
+/**
+ @note Refer to first enum.
+*/
+#define cFileOpsCount 4
+#define cFileMimeGeneric "n-application-kind/all"
+
+/** @brief invalid position. (n-pos) */
+#define kNPos (SizeT)(-1);
+
+namespace Kernel
+{
+ enum
+ {
+ cFileWriteAll = 100,
+ cFileReadAll = 101,
+ cFileReadChunk = 102,
+ cFileWriteChunk = 103,
+ cFileIOCnt = (cFileWriteChunk - cFileWriteAll) + 1,
+ };
+
+ /// @brief filesystem node generic type.
+ struct PACKED FMNode final
+ {
+ VoidPtr _Unused;
+ };
+
+ typedef FMNode* NodePtr;
+
+ /**
+ @brief Filesystem Manager Interface class
+ @brief Used to provide common I/O for a specific filesystem.
+*/
+ class FilesystemManagerInterface
+ {
+ public:
+ explicit FilesystemManagerInterface() = default;
+ virtual ~FilesystemManagerInterface() = default;
+
+ public:
+ NEWOS_COPY_DEFAULT(FilesystemManagerInterface);
+
+ public:
+ /// @brief Mounts a new filesystem into an active state.
+ /// @param interface the filesystem interface
+ /// @return
+ static bool Mount(FilesystemManagerInterface* interface);
+
+ /// @brief Unmounts the active filesystem
+ /// @return
+ static FilesystemManagerInterface* Unmount();
+
+ /// @brief Getter, gets the active filesystem.
+ /// @return
+ static FilesystemManagerInterface* GetMounted();
+
+ public:
+ virtual NodePtr Create(_Input const char* path) = 0;
+ virtual NodePtr CreateAlias(_Input const char* path) = 0;
+ virtual NodePtr CreateDirectory(_Input const char* path) = 0;
+
+ public:
+ virtual bool Remove(_Input const char* path) = 0;
+
+ public:
+ virtual NodePtr Open(_Input const char* path, _Input const char* r) = 0;
+
+ public:
+ virtual Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT size) = 0;
+
+ virtual _Output VoidPtr Read(_Input NodePtr node,
+ _Input Int32 flags,
+ _Input SizeT sz) = 0;
+
+ virtual Void Write(_Input const Char* name,
+ _Input NodePtr node,
+ _Input VoidPtr data,
+ _Input Int32 flags,
+ _Input SizeT size) = 0;
+
+ virtual _Output VoidPtr Read(_Input const Char* name,
+ _Input NodePtr node,
+ _Input Int32 flags,
+ _Input SizeT sz) = 0;
+
+ public:
+ virtual bool Seek(_Input NodePtr node, _Input SizeT off) = 0;
+
+ public:
+ virtual SizeT Tell(_Input NodePtr node) = 0;
+ virtual bool Rewind(_Input NodePtr node) = 0;
+ };
+
+#ifdef __FSKIT_USE_NEWFS__
+ /**
+ * @brief Based of FilesystemManagerInterface, takes care of managing NewFS
+ * disks.
+ */
+ class NewFilesystemManager final : public FilesystemManagerInterface
+ {
+ public:
+ explicit NewFilesystemManager();
+ ~NewFilesystemManager() override;
+
+ public:
+ NEWOS_COPY_DEFAULT(NewFilesystemManager);
+
+ public:
+ NodePtr Create(const Char* path) override;
+ NodePtr CreateAlias(const Char* path) override;
+ NodePtr CreateDirectory(const Char* path) override;
+
+ public:
+ bool Remove(const Char* path) override;
+ NodePtr Open(const Char* path, const Char* r) override;
+ Void Write(NodePtr node, VoidPtr data, Int32 flags, SizeT sz) override;
+ VoidPtr Read(NodePtr node, Int32 flags, SizeT sz) override;
+ bool Seek(NodePtr node, SizeT off) override;
+ SizeT Tell(NodePtr node) override;
+ bool Rewind(NodePtr node) override;
+
+ Void Write(_Input const Char* name,
+ _Input NodePtr node,
+ _Input VoidPtr data,
+ _Input Int32 flags,
+ _Input SizeT size) override;
+
+ _Output VoidPtr Read(_Input const Char* name,
+ _Input NodePtr node,
+ _Input Int32 flags,
+ _Input SizeT sz) override;
+
+ public:
+ void SetResourceFork(const char* forkName);
+ void SetDataFork(const char* forkName);
+
+ /// @brief Get internal parser.
+ /// @return
+ NewFSParser* GetParser() noexcept;
+
+ private:
+ NewFSParser* fImpl{nullptr};
+ };
+
+#endif // ifdef __FSKIT_USE_NEWFS__
+
+ /**
+ * Usable FileStream
+ * @tparam Encoding file encoding (char, wchar_t...)
+ * @tparam FSClass Filesystem contract who takes care of it.
+ */
+ template <typename Encoding = char,
+ typename FSClass = FilesystemManagerInterface>
+ class FileStream final
+ {
+ public:
+ explicit FileStream(const Encoding* path, const Encoding* restrict_type);
+ ~FileStream();
+
+ public:
+ FileStream& operator=(const FileStream&);
+ FileStream(const FileStream&);
+
+ public:
+ ErrorOr<Int64> WriteAll(const VoidPtr data) noexcept
+ {
+ if (this->fFileRestrict != eRestrictReadWrite &&
+ this->fFileRestrict != eRestrictReadWriteBinary &&
+ this->fFileRestrict != eRestrictWrite &&
+ this->fFileRestrict != eRestrictWriteBinary)
+ return ErrorOr<Int64>(kErrorInvalidData);
+
+ if (data == nullptr)
+ return ErrorOr<Int64>(kErrorInvalidData);
+
+ auto man = FSClass::GetMounted();
+
+ if (man)
+ {
+ man->Write(fFile, data, cFileWriteAll);
+ return ErrorOr<Int64>(0);
+ }
+
+ return ErrorOr<Int64>(kErrorInvalidData);
+ }
+
+ VoidPtr ReadAll() noexcept
+ {
+ if (this->fFileRestrict != eRestrictReadWrite &&
+ this->fFileRestrict != eRestrictReadWriteBinary &&
+ this->fFileRestrict != eRestrictRead &&
+ this->fFileRestrict != eRestrictReadBinary)
+ return nullptr;
+
+ auto man = FSClass::GetMounted();
+
+ if (man)
+ {
+ VoidPtr ret = man->Read(fFile, cFileReadAll, 0);
+ return ret;
+ }
+
+ return nullptr;
+ }
+
+ ErrorOr<Int64> WriteAll(const char* fName, const VoidPtr data) noexcept
+ {
+ if (this->fFileRestrict != eRestrictReadWrite &&
+ this->fFileRestrict != eRestrictReadWriteBinary &&
+ this->fFileRestrict != eRestrictWrite &&
+ this->fFileRestrict != eRestrictWriteBinary)
+ return ErrorOr<Int64>(kErrorInvalidData);
+
+ if (data == nullptr)
+ return ErrorOr<Int64>(kErrorInvalidData);
+
+ auto man = FSClass::GetMounted();
+
+ if (man)
+ {
+ man->Write(fName, fFile, data, cFileWriteAll);
+ return ErrorOr<Int64>(0);
+ }
+
+ return ErrorOr<Int64>(kErrorInvalidData);
+ }
+
+ VoidPtr Read(const char* fName) noexcept
+ {
+ if (this->fFileRestrict != eRestrictReadWrite &&
+ this->fFileRestrict != eRestrictReadWriteBinary &&
+ this->fFileRestrict != eRestrictRead &&
+ this->fFileRestrict != eRestrictReadBinary)
+ return nullptr;
+
+ auto man = FSClass::GetMounted();
+
+ if (man)
+ {
+ VoidPtr ret = man->Read(fName, fFile, cFileReadAll, 0);
+ return ret;
+ }
+
+ return nullptr;
+ }
+
+ VoidPtr Read(SizeT offset, SizeT sz)
+ {
+ if (this->fFileRestrict != eRestrictReadWrite &&
+ this->fFileRestrict != eRestrictReadWriteBinary &&
+ this->fFileRestrict != eRestrictRead &&
+ this->fFileRestrict != eRestrictReadBinary)
+ return nullptr;
+
+ auto man = FSClass::GetMounted();
+
+ if (man)
+ {
+ man->Seek(fFile, offset);
+ auto ret = man->Read(fFile, cFileReadChunk, sz);
+
+ return ret;
+ }
+
+ return nullptr;
+ }
+
+ Void Write(SizeT offset, voidPtr data, SizeT sz)
+ {
+ if (this->fFileRestrict != eRestrictReadWrite &&
+ this->fFileRestrict != eRestrictReadWriteBinary &&
+ this->fFileRestrict != eRestrictWrite &&
+ this->fFileRestrict != eRestrictWriteBinary)
+ return;
+
+ auto man = FSClass::GetMounted();
+
+ if (man)
+ {
+ man->Seek(fFile, offset);
+ man->Write(fFile, data, sz, cFileReadChunk);
+ }
+ }
+
+ public:
+ /// @brief Leak node pointer.
+ /// @return The node pointer.
+ NodePtr Leak()
+ {
+ return fFile;
+ }
+
+ /// @brief Leak MIME.
+ /// @return The MIME.
+ Char* MIME() noexcept
+ {
+ return const_cast<char*>(fMime);
+ }
+
+ enum
+ {
+ eRestrictRead,
+ eRestrictReadBinary,
+ eRestrictWrite,
+ eRestrictWriteBinary,
+ eRestrictReadWrite,
+ eRestrictReadWriteBinary,
+ };
+
+ private:
+ NodePtr fFile{nullptr};
+ Int32 fFileRestrict{};
+ const Char* fMime{cFileMimeGeneric};
+ };
+
+ using FileStreamUTF8 = FileStream<Char>;
+ using FileStreamUTF16 = FileStream<WideChar>;
+
+ typedef UInt64 CursorType;
+
+ /// @brief constructor
+ template <typename Encoding, typename Class>
+ FileStream<Encoding, Class>::FileStream(const Encoding* path,
+ const Encoding* restrict_type)
+ : fFile(Class::GetMounted()->Open(path, restrict_type))
+ {
+ static const auto cLength = 255;
+
+ struct StringMap final
+ {
+ Char fRestrict[cLength];
+ Int32 fMappedTo;
+ };
+
+ const SizeT cRestrictCount = cRestrictMax;
+ const StringMap cRestrictList[] = {
+ {
+ .fRestrict = cRestrictR,
+ .fMappedTo = eRestrictRead,
+ },
+ {
+ .fRestrict = cRestrictRB,
+ .fMappedTo = eRestrictReadBinary,
+ },
+ {
+ .fRestrict = cRestrictRWB,
+ .fMappedTo = eRestrictReadWriteBinary,
+ },
+ {
+ .fRestrict = cRestrictW,
+ .fMappedTo = eRestrictWrite,
+ },
+ {
+ .fRestrict = cRestrictWB,
+ .fMappedTo = eRestrictReadWrite,
+ }};
+
+ for (SizeT index = 0; index < cRestrictCount; ++index)
+ {
+ if (rt_string_cmp(restrict_type, cRestrictList[index].fRestrict,
+ rt_string_len(cRestrictList[index].fRestrict)) == 0)
+ {
+ fFileRestrict = cRestrictList[index].fMappedTo;
+ break;
+ }
+ }
+
+ kcout << "newoskrnl: new file: " << path << ".\r";
+ }
+
+ /// @brief destructor
+ template <typename Encoding, typename Class>
+ FileStream<Encoding, Class>::~FileStream()
+ {
+ delete fFile;
+ }
+} // namespace Kernel