// Copyright 2018 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once #include #include #include #include #include "core/file_sys/vfs.h" #include "core/file_sys/vfs_static.h" namespace FileSys { class ConcatenatedVfsFile; // Wrapper function to allow for more efficient handling of files.size() == 0, 1 cases. VirtualFile ConcatenateFiles(std::vector files, std::string name = ""); // Convenience function that turns a map of offsets to files into a concatenated file, filling gaps // with template parameter. template VirtualFile ConcatenateFiles(std::map files, std::string name = "") { if (files.empty()) return nullptr; if (files.size() == 1) return files.begin()->second; for (auto iter = files.begin(); iter != --files.end();) { const auto old = iter++; if (old->first + old->second->GetSize() != iter->first) { files.emplace(old->first + old->second->GetSize(), std::make_shared>(iter->first - old->first - old->second->GetSize())); } } if (files.begin()->first != 0) files.emplace(0, std::make_shared>(files.begin()->first)); return std::shared_ptr(new ConcatenatedVfsFile(std::move(files), std::move(name))); } // Class that wraps multiple vfs files and concatenates them, making reads seamless. Currently // read-only. class ConcatenatedVfsFile : public VfsFile { friend VirtualFile ConcatenateFiles(std::vector files, std::string name); template friend VirtualFile ConcatenateFiles(std::map files, std::string name); ConcatenatedVfsFile(std::vector files, std::string name); ConcatenatedVfsFile(std::map files, std::string name); public: ~ConcatenatedVfsFile() override; std::string GetName() const override; std::size_t GetSize() const override; bool Resize(std::size_t new_size) override; std::shared_ptr GetContainingDirectory() const override; bool IsWritable() const override; bool IsReadable() const override; std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override; std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override; bool Rename(std::string_view name) override; private: // Maps starting offset to file -- more efficient. std::map files; std::string name; }; } // namespace FileSys