#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2021 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_STORAGE_FILESYSTEM_LINUX_WINDOWSFILE_H #define NUCLEX_STORAGE_FILESYSTEM_LINUX_WINDOWSFILE_H #include "Nuclex/Storage/Config.h" #if defined(NUCLEX_STORAGE_WIN32) #include "Nuclex/Storage/FileSystem/File.h" #include "../../Helpers/WindowsApi.h" #include // for std::shared_ptr #include // for std::atomic #include // for std::shared_timed_mutex namespace Nuclex { namespace Storage { namespace FileSystem { // ------------------------------------------------------------------------------------------- // class FileManagerBackend; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Storage::FileSystem namespace Nuclex { namespace Storage { namespace FileSystem { namespace Windows { // ------------------------------------------------------------------------------------------- // /// Accesses a real file on a mounted Linux file system class WindowsFile : public File { // use std::enable_shared_from_this? /// Initializes a new Windows file /// Backend in which the open file will be tracked /// Absolute path to the file /// Whether the file should be created right away /// /// The path is expected to be an absolute path without Microsoft's '\\?\' prefix /// so that its absolute path can be reported back to the user. If the file /// does not exist and is false, an exception is thrown. /// If is true, the file will be created right away to /// ensure it is reserved in the actual file system. /// public: WindowsFile( std::shared_ptr backend, const std::string &absolutePath, bool create = false ); /// Frees all resources owned by the instance public: virtual ~WindowsFile() override; /// Determines the size of the file /// The size of the file in bytes public: std::uint64_t GetSize() const override; /// Returns the name of the file /// The file's name public: const std::string &GetName() const override; /// Changes the name of the file /// New name the file will be known under public: void Rename(const std::string &name) override; #if 0 /// Returns the path the file is stored at in the native format /// The file's absolute path in the native OS format public: virtual const std::string &GetNativePath() const = 0; #endif /// Retrieves the time at which the file has been last modified /// The since since the last modification of the file took place public: std::time_t GetLastModificationTime() const override; /// Reads raw data from the file /// Absolute file position data will be read from /// Buffer into which data will be read /// Number of bytes that will be read public: void ReadAt( std::uint64_t location, void *buffer, std::size_t count ) const override; /// Writes raw data into the file /// Absolute file position data will be written to /// Buffer from which data will be taken /// Number of bytes that will be written public: void WriteAt( std::uint64_t location, const void *buffer, std::size_t count ) override; /// Ensures changes to the file have been written to disk public: void Flush() override; /// Opens the file descriptor with shared read access /// /// This is called by the ReadAt() method if it detects that the file descriptor /// is not valid (i.e. file not opened yet). It's moved into a separate method in /// order to keep the hot code path inside ReadAt() short. /// private: void openFileForReading() const; /// Opens the file descriptor with shared read access /// /// This is called by the WriteAt() method if it detects that the file descriptor /// is not valid (i.e. file not opened yet). It's moved into a separate method in /// order to keep the hot code path inside WriteAt() short. /// private: void openFileForWriting() const; /// Backend that's keeping track of opened files private: std::shared_ptr backend; /// Absolute path of the file in the file system private: std::string absolutePath; /// Name of the file private: std::string name; /// Reader/Writer lock mutex used for access + handle change /// /// Shared lock is used for accessing the file descriptor (including writes). /// Exclusive lock is used to change (close, open, re-open) the file descriptor. /// private: mutable std::shared_timed_mutex readerWriterLock; /// Handle of the opened file or INVALID_HANDLE if not opened yet private: mutable std::atomic fileHandle; /// Whether the file has been opened for writing private: mutable std::atomic isOpenedWritable; /// Current position of the file cursor private: mutable std::atomic fileCursor; }; // ------------------------------------------------------------------------------------------- // }}}} // namespace Nuclex::Storage::FileSystem::Windows #endif // defined(NUCLEX_STORAGE_WIN32) #endif // NUCLEX_STORAGE_FILESYSTEM_LINUX_WINDOWSFILE_H