mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	
						commit
						13699f05e7
					
				
					 9 changed files with 99 additions and 171 deletions
				
			
		|  | @ -40,40 +40,37 @@ union Mode { | |||
| class Path { | ||||
| public: | ||||
| 
 | ||||
|     Path(): | ||||
|         type(Invalid) | ||||
|     { | ||||
|     Path() : type(Invalid) { | ||||
|     } | ||||
| 
 | ||||
|     Path(const char* path): | ||||
|         type(Char), string(path) | ||||
|     { | ||||
|     Path(const char* path) : type(Char), string(path) { | ||||
|     } | ||||
| 
 | ||||
|     Path(LowPathType type, u32 size, u32 pointer): | ||||
|         type(type) | ||||
|     { | ||||
|     Path(LowPathType type, u32 size, u32 pointer) : type(type) { | ||||
|         switch (type) { | ||||
|             case Binary: | ||||
|             { | ||||
|                 u8* data = Memory::GetPointer(pointer); | ||||
|                 binary = std::vector<u8>(data, data + size); | ||||
|                 break; | ||||
|             } | ||||
|             case Char: | ||||
|             { | ||||
|                 const char* data = reinterpret_cast<const char*>(Memory::GetPointer(pointer)); | ||||
|                 string = std::string(data, size - 1); // Data is always null-terminated.
 | ||||
|                 break; | ||||
|             } | ||||
|             case Wchar: | ||||
|             { | ||||
|                 const char16_t* data = reinterpret_cast<const char16_t*>(Memory::GetPointer(pointer)); | ||||
|                 u16str = std::u16string(data, size/2 - 1); // Data is always null-terminated.
 | ||||
|                 break; | ||||
|             } | ||||
|             default: | ||||
|                 break; | ||||
|         case Binary: | ||||
|         { | ||||
|             u8* data = Memory::GetPointer(pointer); | ||||
|             binary = std::vector<u8>(data, data + size); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         case Char: | ||||
|         { | ||||
|             const char* data = reinterpret_cast<const char*>(Memory::GetPointer(pointer)); | ||||
|             string = std::string(data, size - 1); // Data is always null-terminated.
 | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         case Wchar: | ||||
|         { | ||||
|             const char16_t* data = reinterpret_cast<const char16_t*>(Memory::GetPointer(pointer)); | ||||
|             u16str = std::u16string(data, size/2 - 1); // Data is always null-terminated.
 | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -104,66 +101,64 @@ public: | |||
|             return "[Char: " + AsString() + ']'; | ||||
|         case Wchar: | ||||
|             return "[Wchar: " + AsString() + ']'; | ||||
|         default: | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     const std::string AsString() const { | ||||
|         switch (GetType()) { | ||||
|         case Char: | ||||
|             return string; | ||||
|         case Wchar: | ||||
|             return Common::UTF16ToUTF8(u16str); | ||||
|         case Empty: | ||||
|             return {}; | ||||
|         case Invalid: | ||||
|         case Binary: | ||||
|             // TODO(yuriks): Add assert
 | ||||
|             LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); | ||||
|             return {}; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     const std::string AsString() const { | ||||
|         switch (GetType()) { | ||||
|             case Char: | ||||
|                 return string; | ||||
|             case Wchar: | ||||
|                 return Common::UTF16ToUTF8(u16str); | ||||
|             case Empty: | ||||
|                 return {}; | ||||
|             default: | ||||
|                 // TODO(yuriks): Add assert
 | ||||
|                 LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); | ||||
|                 return {}; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     const std::u16string AsU16Str() const { | ||||
|         switch (GetType()) { | ||||
|             case Char: | ||||
|                 return Common::UTF8ToUTF16(string); | ||||
|             case Wchar: | ||||
|                 return u16str; | ||||
|             case Empty: | ||||
|                 return {}; | ||||
|             default: | ||||
|                 // TODO(yuriks): Add assert
 | ||||
|                 LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!"); | ||||
|                 return {}; | ||||
|         case Char: | ||||
|             return Common::UTF8ToUTF16(string); | ||||
|         case Wchar: | ||||
|             return u16str; | ||||
|         case Empty: | ||||
|             return {}; | ||||
|         case Invalid: | ||||
|         case Binary: | ||||
|             // TODO(yuriks): Add assert
 | ||||
|             LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!"); | ||||
|             return {}; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     const std::vector<u8> AsBinary() const { | ||||
|         switch (GetType()) { | ||||
|             case Binary: | ||||
|                 return binary; | ||||
|             case Char: | ||||
|                 return std::vector<u8>(string.begin(), string.end()); | ||||
|             case Wchar: | ||||
|             { | ||||
|                 // use two u8 for each character of u16str
 | ||||
|                 std::vector<u8> to_return(u16str.size() * 2); | ||||
|                 for (size_t i = 0; i < u16str.size(); ++i) { | ||||
|                     u16 tmp_char = u16str.at(i); | ||||
|                     to_return[i*2] = (tmp_char & 0xFF00) >> 8; | ||||
|                     to_return[i*2 + 1] = (tmp_char & 0x00FF); | ||||
|                 } | ||||
|                 return to_return; | ||||
|         case Binary: | ||||
|             return binary; | ||||
|         case Char: | ||||
|             return std::vector<u8>(string.begin(), string.end()); | ||||
|         case Wchar: | ||||
|         { | ||||
|             // use two u8 for each character of u16str
 | ||||
|             std::vector<u8> to_return(u16str.size() * 2); | ||||
|             for (size_t i = 0; i < u16str.size(); ++i) { | ||||
|                 u16 tmp_char = u16str.at(i); | ||||
|                 to_return[i*2] = (tmp_char & 0xFF00) >> 8; | ||||
|                 to_return[i*2 + 1] = (tmp_char & 0x00FF); | ||||
|             } | ||||
|             case Empty: | ||||
|                 return {}; | ||||
|             default: | ||||
|                 // TODO(yuriks): Add assert
 | ||||
|                 LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); | ||||
|                 return {}; | ||||
|             return to_return; | ||||
|         } | ||||
|         case Empty: | ||||
|             return {}; | ||||
|         case Invalid: | ||||
|             // TODO(yuriks): Add assert
 | ||||
|             LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); | ||||
|             return {}; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -176,7 +171,8 @@ private: | |||
| 
 | ||||
| class ArchiveBackend : NonCopyable { | ||||
| public: | ||||
|     virtual ~ArchiveBackend() { } | ||||
|     virtual ~ArchiveBackend() { | ||||
|     } | ||||
| 
 | ||||
|     /**
 | ||||
|      * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) | ||||
|  | @ -196,7 +192,7 @@ public: | |||
|      * @param path Path relative to the archive | ||||
|      * @return Whether the file could be deleted | ||||
|      */ | ||||
|     virtual bool DeleteFile(const FileSys::Path& path) const = 0; | ||||
|     virtual bool DeleteFile(const Path& path) const = 0; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Rename a File specified by its path | ||||
|  | @ -204,14 +200,14 @@ public: | |||
|      * @param dest_path Destination path relative to the archive | ||||
|      * @return Whether rename succeeded | ||||
|      */ | ||||
|     virtual bool RenameFile(const FileSys::Path& src_path, const FileSys::Path& dest_path) const = 0; | ||||
|     virtual bool RenameFile(const Path& src_path, const Path& dest_path) const = 0; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Delete a directory specified by its path | ||||
|      * @param path Path relative to the archive | ||||
|      * @return Whether the directory could be deleted | ||||
|      */ | ||||
|     virtual bool DeleteDirectory(const FileSys::Path& path) const = 0; | ||||
|     virtual bool DeleteDirectory(const Path& path) const = 0; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Create a file specified by its path | ||||
|  | @ -234,7 +230,7 @@ public: | |||
|      * @param dest_path Destination path relative to the archive | ||||
|      * @return Whether rename succeeded | ||||
|      */ | ||||
|     virtual bool RenameDirectory(const FileSys::Path& src_path, const FileSys::Path& dest_path) const = 0; | ||||
|     virtual bool RenameDirectory(const Path& src_path, const Path& dest_path) const = 0; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Open a directory specified by its path | ||||
|  |  | |||
|  | @ -23,37 +23,21 @@ Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Open a file specified by its path, using the specified mode | ||||
|  * @param path Path relative to the archive | ||||
|  * @param mode Mode to open the file with | ||||
|  * @return Opened file, or nullptr | ||||
|  */ | ||||
| std::unique_ptr<FileBackend> Archive_RomFS::OpenFile(const Path& path, const Mode mode) const { | ||||
|     return Common::make_unique<File_RomFS>(this); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Delete a file specified by its path | ||||
|  * @param path Path relative to the archive | ||||
|  * @return Whether the file could be deleted | ||||
|  */ | ||||
| bool Archive_RomFS::DeleteFile(const FileSys::Path& path) const { | ||||
| bool Archive_RomFS::DeleteFile(const Path& path) const { | ||||
|     LOG_WARNING(Service_FS, "Attempted to delete a file from ROMFS."); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| bool Archive_RomFS::RenameFile(const FileSys::Path& src_path, const FileSys::Path& dest_path) const { | ||||
| bool Archive_RomFS::RenameFile(const Path& src_path, const Path& dest_path) const { | ||||
|     LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS."); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Delete a directory specified by its path | ||||
|  * @param path Path relative to the archive | ||||
|  * @return Whether the directory could be deleted | ||||
|  */ | ||||
| bool Archive_RomFS::DeleteDirectory(const FileSys::Path& path) const { | ||||
| bool Archive_RomFS::DeleteDirectory(const Path& path) const { | ||||
|     LOG_WARNING(Service_FS, "Attempted to delete a directory from ROMFS."); | ||||
|     return false; | ||||
| } | ||||
|  | @ -64,26 +48,16 @@ ResultCode Archive_RomFS::CreateFile(const Path& path, u32 size) const { | |||
|     return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Create a directory specified by its path | ||||
|  * @param path Path relative to the archive | ||||
|  * @return Whether the directory could be created | ||||
|  */ | ||||
| bool Archive_RomFS::CreateDirectory(const Path& path) const { | ||||
|     LOG_WARNING(Service_FS, "Attempted to create a directory in ROMFS."); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| bool Archive_RomFS::RenameDirectory(const FileSys::Path& src_path, const FileSys::Path& dest_path) const { | ||||
| bool Archive_RomFS::RenameDirectory(const Path& src_path, const Path& dest_path) const { | ||||
|     LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS."); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Open a directory specified by its path | ||||
|  * @param path Path relative to the archive | ||||
|  * @return Opened directory, or nullptr | ||||
|  */ | ||||
| std::unique_ptr<DirectoryBackend> Archive_RomFS::OpenDirectory(const Path& path) const { | ||||
|     return Common::make_unique<Directory_RomFS>(); | ||||
| } | ||||
|  |  | |||
|  | @ -36,7 +36,7 @@ public: | |||
|      * @param path Path relative to the archive | ||||
|      * @return Whether the file could be deleted | ||||
|      */ | ||||
|     bool DeleteFile(const FileSys::Path& path) const override; | ||||
|     bool DeleteFile(const Path& path) const override; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Rename a File specified by its path | ||||
|  | @ -44,14 +44,14 @@ public: | |||
|      * @param dest_path Destination path relative to the archive | ||||
|      * @return Whether rename succeeded | ||||
|      */ | ||||
|     bool RenameFile(const FileSys::Path& src_path, const FileSys::Path& dest_path) const override; | ||||
|     bool RenameFile(const Path& src_path, const Path& dest_path) const override; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Delete a directory specified by its path | ||||
|      * @param path Path relative to the archive | ||||
|      * @return Whether the directory could be deleted | ||||
|      */ | ||||
|     bool DeleteDirectory(const FileSys::Path& path) const override; | ||||
|     bool DeleteDirectory(const Path& path) const override; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Create a file specified by its path | ||||
|  | @ -74,7 +74,7 @@ public: | |||
|      * @param dest_path Destination path relative to the archive | ||||
|      * @return Whether rename succeeded | ||||
|      */ | ||||
|     bool RenameDirectory(const FileSys::Path& src_path, const FileSys::Path& dest_path) const override; | ||||
|     bool RenameDirectory(const Path& src_path, const Path& dest_path) const override; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Open a directory specified by its path | ||||
|  |  | |||
|  | @ -16,7 +16,7 @@ | |||
| 
 | ||||
| namespace FileSys { | ||||
| 
 | ||||
| Archive_SaveData::Archive_SaveData(const std::string& mount_point, u64 program_id)  | ||||
| Archive_SaveData::Archive_SaveData(const std::string& mount_point, u64 program_id) | ||||
|         : DiskArchive(mount_point + Common::StringFromFormat("%016X", program_id) + DIR_SEP) { | ||||
|     LOG_INFO(Service_FS, "Directory %s set as SaveData.", this->mount_point.c_str()); | ||||
| } | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ | |||
| namespace FileSys { | ||||
| 
 | ||||
| /// File system interface to the SystemSaveData archive
 | ||||
| /// TODO(Subv): This archive should point to a location in the NAND, 
 | ||||
| /// TODO(Subv): This archive should point to a location in the NAND,
 | ||||
| /// specifically nand:/data/<ID0>/sysdata/<SaveID-Low>/<SaveID-High>
 | ||||
| class Archive_SystemSaveData final : public DiskArchive { | ||||
| public: | ||||
|  |  | |||
|  | @ -21,20 +21,10 @@ bool Directory_RomFS::Open() { | |||
|     return false; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * List files contained in the directory | ||||
|  * @param count Number of entries to return at once in entries | ||||
|  * @param entries Buffer to read data into | ||||
|  * @return Number of entries listed | ||||
|  */ | ||||
| u32 Directory_RomFS::Read(const u32 count, Entry* entries) { | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Close the directory | ||||
|  * @return true if the directory closed correctly | ||||
|  */ | ||||
| bool Directory_RomFS::Close() const { | ||||
|     return false; | ||||
| } | ||||
|  |  | |||
|  | @ -23,15 +23,15 @@ std::unique_ptr<FileBackend> DiskArchive::OpenFile(const Path& path, const Mode | |||
|     return std::unique_ptr<FileBackend>(file); | ||||
| } | ||||
| 
 | ||||
| bool DiskArchive::DeleteFile(const FileSys::Path& path) const { | ||||
| bool DiskArchive::DeleteFile(const Path& path) const { | ||||
|     return FileUtil::Delete(GetMountPoint() + path.AsString()); | ||||
| } | ||||
| 
 | ||||
| bool DiskArchive::RenameFile(const FileSys::Path& src_path, const FileSys::Path& dest_path) const { | ||||
| bool DiskArchive::RenameFile(const Path& src_path, const Path& dest_path) const { | ||||
|     return FileUtil::Rename(GetMountPoint() + src_path.AsString(), GetMountPoint() + dest_path.AsString()); | ||||
| } | ||||
| 
 | ||||
| bool DiskArchive::DeleteDirectory(const FileSys::Path& path) const { | ||||
| bool DiskArchive::DeleteDirectory(const Path& path) const { | ||||
|     return FileUtil::DeleteDir(GetMountPoint() + path.AsString()); | ||||
| } | ||||
| 
 | ||||
|  | @ -60,7 +60,7 @@ bool DiskArchive::CreateDirectory(const Path& path) const { | |||
|     return FileUtil::CreateDir(GetMountPoint() + path.AsString()); | ||||
| } | ||||
| 
 | ||||
| bool DiskArchive::RenameDirectory(const FileSys::Path& src_path, const FileSys::Path& dest_path) const { | ||||
| bool DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { | ||||
|     return FileUtil::Rename(GetMountPoint() + src_path.AsString(), GetMountPoint() + dest_path.AsString()); | ||||
| } | ||||
| 
 | ||||
|  | @ -85,7 +85,7 @@ DiskFile::DiskFile(const DiskArchive* archive, const Path& path, const Mode mode | |||
| 
 | ||||
| bool DiskFile::Open() { | ||||
|     if (!mode.create_flag && !FileUtil::Exists(path)) { | ||||
|         LOG_ERROR(Service_FS, "Non-existing file %s can’t be open without mode create.", path.c_str()); | ||||
|         LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.", path.c_str()); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,8 +16,8 @@ | |||
| namespace FileSys { | ||||
| 
 | ||||
| /**
 | ||||
|  * Helper which implements a backend accessing the host machine's filesystem.  | ||||
|  * This should be subclassed by concrete archive types, which will provide the  | ||||
|  * Helper which implements a backend accessing the host machine's filesystem. | ||||
|  * This should be subclassed by concrete archive types, which will provide the | ||||
|  * base directory on the host filesystem and override any required functionality. | ||||
|  */ | ||||
| class DiskArchive : public ArchiveBackend { | ||||
|  | @ -26,12 +26,12 @@ public: | |||
| 
 | ||||
|     virtual std::string GetName() const = 0; | ||||
|     std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override; | ||||
|     bool DeleteFile(const FileSys::Path& path) const override; | ||||
|     bool RenameFile(const FileSys::Path& src_path, const FileSys::Path& dest_path) const override; | ||||
|     bool DeleteDirectory(const FileSys::Path& path) const override; | ||||
|     bool DeleteFile(const Path& path) const override; | ||||
|     bool RenameFile(const Path& src_path, const Path& dest_path) const override; | ||||
|     bool DeleteDirectory(const Path& path) const override; | ||||
|     ResultCode CreateFile(const Path& path, u32 size) const override; | ||||
|     bool CreateDirectory(const Path& path) const override; | ||||
|     bool RenameDirectory(const FileSys::Path& src_path, const FileSys::Path& dest_path) const override; | ||||
|     bool RenameDirectory(const Path& src_path, const Path& dest_path) const override; | ||||
|     std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override; | ||||
| 
 | ||||
|     /**
 | ||||
|  | @ -50,7 +50,7 @@ class DiskFile : public FileBackend { | |||
| public: | ||||
|     DiskFile(); | ||||
|     DiskFile(const DiskArchive* archive, const Path& path, const Mode mode); | ||||
|      | ||||
| 
 | ||||
|     ~DiskFile() override { | ||||
|         Close(); | ||||
|     } | ||||
|  | @ -61,7 +61,7 @@ public: | |||
|     size_t GetSize() const override; | ||||
|     bool SetSize(const u64 size) const override; | ||||
|     bool Close() const override; | ||||
|      | ||||
| 
 | ||||
|     void Flush() const override { | ||||
|         file->Flush(); | ||||
|     } | ||||
|  |  | |||
|  | @ -12,62 +12,30 @@ | |||
| 
 | ||||
| namespace FileSys { | ||||
| 
 | ||||
| /**
 | ||||
|  * Open the file | ||||
|  * @return true if the file opened correctly | ||||
|  */ | ||||
| bool File_RomFS::Open() { | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Read data from the file | ||||
|  * @param offset Offset in bytes to start reading data from | ||||
|  * @param length Length in bytes of data to read from file | ||||
|  * @param buffer Buffer to read data into | ||||
|  * @return Number of bytes read | ||||
|  */ | ||||
| size_t File_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const { | ||||
|     LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length); | ||||
|     memcpy(buffer, &archive->raw_data[(u32)offset], length); | ||||
|     return length; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Write data to the file | ||||
|  * @param offset Offset in bytes to start writing data to | ||||
|  * @param length Length in bytes of data to write to file | ||||
|  * @param flush The flush parameters (0 == do not flush) | ||||
|  * @param buffer Buffer to read data from | ||||
|  * @return Number of bytes written | ||||
|  */ | ||||
| size_t File_RomFS::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const { | ||||
|     LOG_WARNING(Service_FS, "Attempted to write to ROMFS."); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Get the size of the file in bytes | ||||
|  * @return Size of the file in bytes | ||||
|  */ | ||||
| size_t File_RomFS::GetSize() const { | ||||
|     return sizeof(u8) * archive->raw_data.size(); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Set the size of the file in bytes | ||||
|  * @param size New size of the file | ||||
|  * @return true if successful | ||||
|  */ | ||||
| bool File_RomFS::SetSize(const u64 size) const { | ||||
|     LOG_WARNING(Service_FS, "Attempted to set the size of ROMFS"); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Close the file | ||||
|  * @return true if the file closed correctly | ||||
|  */ | ||||
| bool File_RomFS::Close() const { | ||||
|     return false; | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue