diff options
author | Zach Hilman <DarkLordZach@users.noreply.github.com> | 2018-07-06 16:51:32 +0200 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2018-07-06 16:51:32 +0200 |
commit | 77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2 (patch) | |
tree | 38ef6451732c5eecb0efdd198f3db4d33848453c /src/core/file_sys/vfs.h | |
parent | Merge pull request #629 from Subv/depth_test (diff) | |
download | yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar.gz yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar.bz2 yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar.lz yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar.xz yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.tar.zst yuzu-77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2.zip |
Diffstat (limited to 'src/core/file_sys/vfs.h')
-rw-r--r-- | src/core/file_sys/vfs.h | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h new file mode 100644 index 000000000..0e30991b4 --- /dev/null +++ b/src/core/file_sys/vfs.h @@ -0,0 +1,220 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <memory> +#include <string> +#include <type_traits> +#include <vector> +#include "boost/optional.hpp" +#include "common/common_types.h" +#include "common/file_util.h" + +namespace FileSys { +struct VfsFile; +struct VfsDirectory; + +// Convenience typedefs to use VfsDirectory and VfsFile +using VirtualDir = std::shared_ptr<FileSys::VfsDirectory>; +using VirtualFile = std::shared_ptr<FileSys::VfsFile>; + +// A class representing a file in an abstract filesystem. +struct VfsFile : NonCopyable { + virtual ~VfsFile(); + + // Retrieves the file name. + virtual std::string GetName() const = 0; + // Retrieves the extension of the file name. + virtual std::string GetExtension() const; + // Retrieves the size of the file. + virtual size_t GetSize() const = 0; + // Resizes the file to new_size. Returns whether or not the operation was successful. + virtual bool Resize(size_t new_size) = 0; + // Gets a pointer to the directory containing this file, returning nullptr if there is none. + virtual std::shared_ptr<VfsDirectory> GetContainingDirectory() const = 0; + + // Returns whether or not the file can be written to. + virtual bool IsWritable() const = 0; + // Returns whether or not the file can be read from. + virtual bool IsReadable() const = 0; + + // The primary method of reading from the file. Reads length bytes into data starting at offset + // into file. Returns number of bytes successfully read. + virtual size_t Read(u8* data, size_t length, size_t offset = 0) const = 0; + // The primary method of writing to the file. Writes length bytes from data starting at offset + // into file. Returns number of bytes successfully written. + virtual size_t Write(const u8* data, size_t length, size_t offset = 0) = 0; + + // Reads exactly one byte at the offset provided, returning boost::none on error. + virtual boost::optional<u8> ReadByte(size_t offset = 0) const; + // Reads size bytes starting at offset in file into a vector. + virtual std::vector<u8> ReadBytes(size_t size, size_t offset = 0) const; + // Reads all the bytes from the file into a vector. Equivalent to 'file->Read(file->GetSize(), + // 0)' + virtual std::vector<u8> ReadAllBytes() const; + + // Reads an array of type T, size number_elements starting at offset. + // Returns the number of bytes (sizeof(T)*number_elements) read successfully. + template <typename T> + size_t ReadArray(T* data, size_t number_elements, size_t offset = 0) const { + static_assert(std::is_trivially_copyable<T>::value, + "Data type must be trivially copyable."); + + return Read(reinterpret_cast<u8*>(data), number_elements * sizeof(T), offset); + } + + // Reads size bytes into the memory starting at data starting at offset into the file. + // Returns the number of bytes read successfully. + template <typename T> + size_t ReadBytes(T* data, size_t size, size_t offset = 0) const { + static_assert(std::is_trivially_copyable<T>::value, + "Data type must be trivially copyable."); + return Read(reinterpret_cast<u8*>(data), size, offset); + } + + // Reads one object of type T starting at offset in file. + // Returns the number of bytes read successfully (sizeof(T)). + template <typename T> + size_t ReadObject(T* data, size_t offset = 0) const { + static_assert(std::is_trivially_copyable<T>::value, + "Data type must be trivially copyable."); + return Read(reinterpret_cast<u8*>(data), sizeof(T), offset); + } + + // Writes exactly one byte to offset in file and retuns whether or not the byte was written + // successfully. + virtual bool WriteByte(u8 data, size_t offset = 0); + // Writes a vector of bytes to offset in file and returns the number of bytes successfully + // written. + virtual size_t WriteBytes(std::vector<u8> data, size_t offset = 0); + + // Writes an array of type T, size number_elements to offset in file. + // Returns the number of bytes (sizeof(T)*number_elements) written successfully. + template <typename T> + size_t WriteArray(T* data, size_t number_elements, size_t offset = 0) { + static_assert(std::is_trivially_copyable<T>::value, + "Data type must be trivially copyable."); + + return Write(data, number_elements * sizeof(T), offset); + } + + // Writes size bytes starting at memory location data to offset in file. + // Returns the number of bytes written successfully. + template <typename T> + size_t WriteBytes(T* data, size_t size, size_t offset = 0) { + static_assert(std::is_trivially_copyable<T>::value, + "Data type must be trivially copyable."); + return Write(reinterpret_cast<u8*>(data), size, offset); + } + + // Writes one object of type T to offset in file. + // Returns the number of bytes written successfully (sizeof(T)). + template <typename T> + size_t WriteObject(const T& data, size_t offset = 0) { + static_assert(std::is_trivially_copyable<T>::value, + "Data type must be trivially copyable."); + return Write(&data, sizeof(T), offset); + } + + // Renames the file to name. Returns whether or not the operation was successsful. + virtual bool Rename(const std::string& name) = 0; +}; + +// A class representing a directory in an abstract filesystem. +struct VfsDirectory : NonCopyable { + virtual ~VfsDirectory(); + + // Retrives the file located at path as if the current directory was root. Returns nullptr if + // not found. + virtual std::shared_ptr<VfsFile> GetFileRelative(const std::string& path) const; + // Calls GetFileRelative(path) on the root of the current directory. + virtual std::shared_ptr<VfsFile> GetFileAbsolute(const std::string& path) const; + + // Retrives the directory located at path as if the current directory was root. Returns nullptr + // if not found. + virtual std::shared_ptr<VfsDirectory> GetDirectoryRelative(const std::string& path) const; + // Calls GetDirectoryRelative(path) on the root of the current directory. + virtual std::shared_ptr<VfsDirectory> GetDirectoryAbsolute(const std::string& path) const; + + // Returns a vector containing all of the files in this directory. + virtual std::vector<std::shared_ptr<VfsFile>> GetFiles() const = 0; + // Returns the file with filename matching name. Returns nullptr if directory dosen't have a + // file with name. + virtual std::shared_ptr<VfsFile> GetFile(const std::string& name) const; + + // Returns a vector containing all of the subdirectories in this directory. + virtual std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const = 0; + // Returns the directory with name matching name. Returns nullptr if directory dosen't have a + // directory with name. + virtual std::shared_ptr<VfsDirectory> GetSubdirectory(const std::string& name) const; + + // Returns whether or not the directory can be written to. + virtual bool IsWritable() const = 0; + // Returns whether of not the directory can be read from. + virtual bool IsReadable() const = 0; + + // Returns whether or not the directory is the root of the current file tree. + virtual bool IsRoot() const; + + // Returns the name of the directory. + virtual std::string GetName() const = 0; + // Returns the total size of all files and subdirectories in this directory. + virtual size_t GetSize() const; + // Returns the parent directory of this directory. Returns nullptr if this directory is root or + // has no parent. + virtual std::shared_ptr<VfsDirectory> GetParentDirectory() const = 0; + + // Creates a new subdirectory with name name. Returns a pointer to the new directory or nullptr + // if the operation failed. + virtual std::shared_ptr<VfsDirectory> CreateSubdirectory(const std::string& name) = 0; + // Creates a new file with name name. Returns a pointer to the new file or nullptr if the + // operation failed. + virtual std::shared_ptr<VfsFile> CreateFile(const std::string& name) = 0; + + // Deletes the subdirectory with name and returns true on success. + virtual bool DeleteSubdirectory(const std::string& name) = 0; + // Deletes all subdirectories and files of subdirectory with name recirsively and then deletes + // the subdirectory. Returns true on success. + virtual bool DeleteSubdirectoryRecursive(const std::string& name); + // Returnes whether or not the file with name name was deleted successfully. + virtual bool DeleteFile(const std::string& name) = 0; + + // Returns whether or not this directory was renamed to name. + virtual bool Rename(const std::string& name) = 0; + + // Returns whether or not the file with name src was successfully copied to a new file with name + // dest. + virtual bool Copy(const std::string& src, const std::string& dest); + + // Interprets the file with name file instead as a directory of type directory. + // The directory must have a constructor that takes a single argument of type + // std::shared_ptr<VfsFile>. Allows to reinterpret container files (i.e NCA, zip, XCI, etc) as a + // subdirectory in one call. + template <typename Directory> + bool InterpretAsDirectory(const std::string& file) { + auto file_p = GetFile(file); + if (file_p == nullptr) + return false; + return ReplaceFileWithSubdirectory(file, std::make_shared<Directory>(file_p)); + } + +protected: + // Backend for InterpretAsDirectory. + // Removes all references to file and adds a reference to dir in the directory's implementation. + virtual bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) = 0; +}; + +// A convenience partial-implementation of VfsDirectory that stubs out methods that should only work +// if writable. This is to avoid redundant empty methods everywhere. +struct ReadOnlyVfsDirectory : public VfsDirectory { + bool IsWritable() const override; + bool IsReadable() const override; + std::shared_ptr<VfsDirectory> CreateSubdirectory(const std::string& name) override; + std::shared_ptr<VfsFile> CreateFile(const std::string& name) override; + bool DeleteSubdirectory(const std::string& name) override; + bool DeleteFile(const std::string& name) override; + bool Rename(const std::string& name) override; +}; +} // namespace FileSys |