mirror of
https://github.com/citra-emu/citra.git
synced 2025-05-10 08:51:07 +00:00

Final things from review comments Clang format Shorten property code (similar to #6883) and move to utils Move all additional helper functions into a 'utils' file. Simplify some things as requested in review Minor code changes from review before rebase fix misusing std span Fix leftovers from rebase, and null-terminator problem with download string-view Change downloadbossdatafromurl to take in string_views, make getting the list of files more dynamic Fix error in linux builds and cleanup Squash commits during rebase: Some changes as per review and cleanup More changes as per review Changes as per review Futures cannot be copied, remove stubbed warning on implemented calls, remove unneeded task_status simulation, simplify getting task_status and duration Implement downloading tasks in background Very final changes from review; and use common for converting strings FInal changes for review Attempt to fix codecvt error Use references when any_casting Update boost submodule to use master again, refactor how properties work, other minor changes per review Fix operator overload error on linux/mingw Make some changes as requested by review; change boost submodule url temporarily to use boost.url Fix for android build Fixes android builds when web services are enabled, like in #6555 Avoid crashes when urls are invalid clang-format Return error status properly on task fail Fix implementation of gettaskstate, gettaskstatus and gettaskservicestatus Fix mingw build error Add support for reading tasks from boss save data databases. clang-format Implement storing task properties Fix missing includes and add references in loops Change task_id_list to map, initial implementation of task properties, minor refactor Remove the dependency on the newer behavior of std erase to fix android building Fix compilation on android and other platforms when web services are not enabled Fix clang-format errors Add support for downloading and decrypting spotpass data directly from nintendo servers Fix windows implicit conversion error again Fix comment Fix filter in NsDataIdList; Finish GetNsDataHeaderInfo; Implement basic support for registering tasks and checking if they exist TODO actually read and write from boss savedata dbs Add boss extdata to archive.h so the lle boss module can function properly Implement ReadNsData and partially implement GetNsDataHeaderInfo and GetNsDataLastUpdate; MK7 now reads spotpass data and successfully boots! Made requested changes; added filtering; removed readnsdata implementation Add partial implementations of GetNsDataIdList(1/2/3) and ReadNsData Add zeroed array of nsdataid entries, run clang-format Check the spotpass extdata directory to determine number of ns output entries Check for PLvPWAA Only set the number of output entries in GetNsDataIdList1 to 1 if PLvPWAA is detected. Fix plvpwaa dlc error Return 1 for the number of output entries in the GetNsDataIdList1 stub. This fixes the extra content for Professor Layton vs Phoenix Wright Ace Attorney as the game expects the boss extdata to not be empty. Might break other games if they attempt to do anything with the ns data. (although the readnsdata and deletensdata methods are both still stubbed)
251 lines
7.9 KiB
C++
251 lines
7.9 KiB
C++
// Copyright 2014 Citra Emulator Project
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
#include <boost/serialization/string.hpp>
|
|
#include <boost/serialization/vector.hpp>
|
|
#include "common/bit_field.h"
|
|
#include "common/common_types.h"
|
|
#include "common/swap.h"
|
|
#include "core/file_sys/delay_generator.h"
|
|
#include "core/hle/result.h"
|
|
|
|
namespace FileSys {
|
|
|
|
class FileBackend;
|
|
class DirectoryBackend;
|
|
|
|
// Path string type
|
|
enum class LowPathType : u32 {
|
|
Invalid = 0,
|
|
Empty = 1,
|
|
Binary = 2,
|
|
Char = 3,
|
|
Wchar = 4,
|
|
};
|
|
|
|
union Mode {
|
|
u32 hex = 0;
|
|
BitField<0, 1, u32> read_flag;
|
|
BitField<1, 1, u32> write_flag;
|
|
BitField<2, 1, u32> create_flag;
|
|
};
|
|
|
|
class Path {
|
|
public:
|
|
Path() : type(LowPathType::Invalid) {}
|
|
Path(const char* path) : type(LowPathType::Char), string(path) {}
|
|
Path(std::string path) : type(LowPathType::Char), string(std::move(path)) {}
|
|
Path(std::vector<u8> binary_data) : type(LowPathType::Binary), binary(std::move(binary_data)) {}
|
|
template <std::size_t size>
|
|
Path(const std::array<u8, size>& binary_data)
|
|
: type(LowPathType::Binary), binary(binary_data.begin(), binary_data.end()) {}
|
|
Path(LowPathType type, std::vector<u8> data);
|
|
|
|
LowPathType GetType() const {
|
|
return type;
|
|
}
|
|
|
|
/**
|
|
* Gets the string representation of the path for debugging
|
|
* @return String representation of the path for debugging
|
|
*/
|
|
std::string DebugStr() const;
|
|
|
|
std::string AsString() const;
|
|
std::u16string AsU16Str() const;
|
|
std::vector<u8> AsBinary() const;
|
|
|
|
private:
|
|
LowPathType type;
|
|
std::vector<u8> binary;
|
|
std::string string;
|
|
std::u16string u16str;
|
|
|
|
template <class Archive>
|
|
void serialize(Archive& ar, const unsigned int) {
|
|
ar& type;
|
|
switch (type) {
|
|
case LowPathType::Binary:
|
|
ar& binary;
|
|
break;
|
|
case LowPathType::Char:
|
|
ar& string;
|
|
break;
|
|
case LowPathType::Wchar: {
|
|
std::vector<char16_t> data;
|
|
if (Archive::is_saving::value) {
|
|
std::copy(u16str.begin(), u16str.end(), std::back_inserter(data));
|
|
}
|
|
ar& data;
|
|
if (Archive::is_loading::value) {
|
|
u16str = std::u16string(data.data(), data.size());
|
|
}
|
|
} break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
friend class boost::serialization::access;
|
|
};
|
|
|
|
/// Parameters of the archive, as specified in the Create or Format call.
|
|
struct ArchiveFormatInfo {
|
|
u32_le total_size; ///< The pre-defined size of the archive.
|
|
u32_le number_directories; ///< The pre-defined number of directories in the archive.
|
|
u32_le number_files; ///< The pre-defined number of files in the archive.
|
|
u8 duplicate_data; ///< Whether the archive should duplicate the data.
|
|
};
|
|
static_assert(std::is_trivial_v<ArchiveFormatInfo>, "ArchiveFormatInfo is not POD");
|
|
|
|
class ArchiveBackend : NonCopyable {
|
|
public:
|
|
virtual ~ArchiveBackend() {}
|
|
|
|
/**
|
|
* Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.)
|
|
*/
|
|
virtual std::string GetName() const = 0;
|
|
|
|
/**
|
|
* 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 error code
|
|
*/
|
|
virtual ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path,
|
|
const Mode& mode) const = 0;
|
|
|
|
/**
|
|
* Delete a file specified by its path
|
|
* @param path Path relative to the archive
|
|
* @return Result of the operation
|
|
*/
|
|
virtual ResultCode DeleteFile(const Path& path) const = 0;
|
|
|
|
/**
|
|
* Rename a File specified by its path
|
|
* @param src_path Source path relative to the archive
|
|
* @param dest_path Destination path relative to the archive
|
|
* @return Result of the operation
|
|
*/
|
|
virtual ResultCode 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 Result of the operation
|
|
*/
|
|
virtual ResultCode DeleteDirectory(const Path& path) const = 0;
|
|
|
|
/**
|
|
* Delete a directory specified by its path and anything under it
|
|
* @param path Path relative to the archive
|
|
* @return Result of the operation
|
|
*/
|
|
virtual ResultCode DeleteDirectoryRecursively(const Path& path) const = 0;
|
|
|
|
/**
|
|
* Create a file specified by its path
|
|
* @param path Path relative to the Archive
|
|
* @param size The size of the new file, filled with zeroes
|
|
* @return Result of the operation
|
|
*/
|
|
virtual ResultCode CreateFile(const Path& path, u64 size) const = 0;
|
|
|
|
/**
|
|
* Create a directory specified by its path
|
|
* @param path Path relative to the archive
|
|
* @return Result of the operation
|
|
*/
|
|
virtual ResultCode CreateDirectory(const Path& path) const = 0;
|
|
|
|
/**
|
|
* Rename a Directory specified by its path
|
|
* @param src_path Source path relative to the archive
|
|
* @param dest_path Destination path relative to the archive
|
|
* @return Result of the operation
|
|
*/
|
|
virtual ResultCode RenameDirectory(const Path& src_path, const Path& dest_path) const = 0;
|
|
|
|
/**
|
|
* Open a directory specified by its path
|
|
* @param path Path relative to the archive
|
|
* @return Opened directory, or error code
|
|
*/
|
|
virtual ResultVal<std::unique_ptr<DirectoryBackend>> OpenDirectory(const Path& path) const = 0;
|
|
|
|
/**
|
|
* Get the free space
|
|
* @return The number of free bytes in the archive
|
|
*/
|
|
virtual u64 GetFreeBytes() const = 0;
|
|
|
|
u64 GetOpenDelayNs() {
|
|
if (delay_generator != nullptr) {
|
|
return delay_generator->GetOpenDelayNs();
|
|
}
|
|
LOG_ERROR(Service_FS, "Delay generator was not initalized. Using default");
|
|
delay_generator = std::make_unique<DefaultDelayGenerator>();
|
|
return delay_generator->GetOpenDelayNs();
|
|
}
|
|
|
|
protected:
|
|
std::unique_ptr<DelayGenerator> delay_generator;
|
|
|
|
private:
|
|
template <class Archive>
|
|
void serialize(Archive& ar, const unsigned int) {
|
|
ar& delay_generator;
|
|
}
|
|
friend class boost::serialization::access;
|
|
};
|
|
|
|
class ArchiveFactory : NonCopyable {
|
|
public:
|
|
virtual ~ArchiveFactory() {}
|
|
|
|
/**
|
|
* Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.)
|
|
*/
|
|
virtual std::string GetName() const = 0;
|
|
|
|
/**
|
|
* Tries to open the archive of this type with the specified path
|
|
* @param path Path to the archive
|
|
* @param program_id the program ID of the client that requests the operation
|
|
* @return An ArchiveBackend corresponding operating specified archive path.
|
|
*/
|
|
virtual ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path, u64 program_id) = 0;
|
|
|
|
/**
|
|
* Deletes the archive contents and then re-creates the base folder
|
|
* @param path Path to the archive
|
|
* @param format_info Format information for the new archive
|
|
* @param program_id the program ID of the client that requests the operation
|
|
* @return ResultCode of the operation, 0 on success
|
|
*/
|
|
virtual ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info,
|
|
u64 program_id) = 0;
|
|
|
|
/**
|
|
* Retrieves the format info about the archive with the specified path
|
|
* @param path Path to the archive
|
|
* @param program_id the program ID of the client that requests the operation
|
|
* @return Format information about the archive or error code
|
|
*/
|
|
virtual ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path, u64 program_id) const = 0;
|
|
|
|
template <class Archive>
|
|
void serialize(Archive& ar, const unsigned int) {}
|
|
friend class boost::serialization::access;
|
|
};
|
|
|
|
} // namespace FileSys
|