citra/src/core/file_sys/archive_backend.h
Rokkubro b5ff2440f6 Squash commits during rebase again:
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)
2023-11-02 21:09:42 +11:00

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