From ca971ff31f49456e01d5e7f9747327f2ce18133a Mon Sep 17 00:00:00 2001 From: Hamish Milne Date: Fri, 10 Jan 2020 23:47:39 +0000 Subject: [PATCH] Serialize file/directory services --- TODO | 4 ++-- src/core/file_sys/archive_backend.h | 30 ++++++++++++++++++++++++++- src/core/file_sys/directory_backend.h | 5 +++++ src/core/hle/service/fs/directory.cpp | 12 +++++++++++ src/core/hle/service/fs/directory.h | 9 ++++++++ src/core/hle/service/fs/file.cpp | 13 ++++++++++++ src/core/hle/service/fs/file.h | 11 ++++++++++ 7 files changed, 81 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index a8efb78eb..a76890185 100644 --- a/TODO +++ b/TODO @@ -4,14 +4,14 @@ ☐ Custom texture cache ☐ Review constructor/initialization code ☐ Review core timing events -☐ Review base class serialization everywhere +✔ Review base class serialization everywhere @done(20-01-10 23:47) Make sure that all base/derived relationships are registered ☐ Serialize codeset with an apploader reference instead ☐ Additional stuff to serialize ☐ Self-NCCH archive ☐ File backends ☐ Directory backends - ☐ File/directory 'services' + ✔ File/directory 'services' @done(20-01-10 23:46) ✔ CPU @done(19-08-13 15:41) ✔ Memory @done(19-08-13 15:41) ✔ Page tables @done(20-01-05 16:33) diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 756613a30..6468c0630 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "common/bit_field.h" #include "common/common_types.h" #include "common/swap.h" @@ -63,7 +65,33 @@ private: LowPathType type; std::vector binary; std::string string; - std::u16string u16str; + std::u16string u16str{}; + + template + 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: + static_assert(sizeof(wchar_t) == sizeof(char16_t)); + { + std::wstring wstring(reinterpret_cast(u16str.data())); + ar& wstring; + if (!Archive::is_saving::value) { + u16str = std::u16string(reinterpret_cast(wstring.data())); + } + } + break; + default: + break; + } + } + friend class boost::serialization::access; }; /// Parameters of the archive, as specified in the Create or Format call. diff --git a/src/core/file_sys/directory_backend.h b/src/core/file_sys/directory_backend.h index e9f124b02..4c9dbb4df 100644 --- a/src/core/file_sys/directory_backend.h +++ b/src/core/file_sys/directory_backend.h @@ -53,6 +53,11 @@ public: * @return true if the directory closed correctly */ virtual bool Close() const = 0; + +private: + template + void serialize(Archive& ar, const unsigned int) {} + friend class boost::serialization::access; }; } // namespace FileSys diff --git a/src/core/hle/service/fs/directory.cpp b/src/core/hle/service/fs/directory.cpp index a72a9307a..16b12905c 100644 --- a/src/core/hle/service/fs/directory.cpp +++ b/src/core/hle/service/fs/directory.cpp @@ -2,13 +2,25 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/logging/log.h" #include "core/file_sys/directory_backend.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/fs/directory.h" +SERIALIZE_EXPORT_IMPL(Service::FS::Directory) + namespace Service::FS { +template +void Directory::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& path; + ar& backend; +} + +Directory::Directory() : ServiceFramework("", 1) {} + Directory::Directory(std::unique_ptr&& backend, const FileSys::Path& path) : ServiceFramework("", 1), path(path), backend(std::move(backend)) { diff --git a/src/core/hle/service/fs/directory.h b/src/core/hle/service/fs/directory.h index 890b26648..77956b166 100644 --- a/src/core/hle/service/fs/directory.h +++ b/src/core/hle/service/fs/directory.h @@ -25,6 +25,15 @@ public: protected: void Read(Kernel::HLERequestContext& ctx); void Close(Kernel::HLERequestContext& ctx); + +private: + Directory(); + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::FS + +BOOST_CLASS_EXPORT_KEY(Service::FS::Directory) diff --git a/src/core/hle/service/fs/file.cpp b/src/core/hle/service/fs/file.cpp index c8727314b..b878197d7 100644 --- a/src/core/hle/service/fs/file.cpp +++ b/src/core/hle/service/fs/file.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/archives.h" #include "common/logging/log.h" #include "core/core.h" #include "core/file_sys/errors.h" @@ -13,8 +14,20 @@ #include "core/hle/kernel/server_session.h" #include "core/hle/service/fs/file.h" +SERIALIZE_EXPORT_IMPL(Service::FS::File) +SERIALIZE_EXPORT_IMPL(Service::FS::FileSessionSlot) + namespace Service::FS { +template +void File::serialize(Archive& ar, const unsigned int) { + ar& boost::serialization::base_object(*this); + ar& path; + ar& backend; +} + +File::File() : ServiceFramework("", 1), kernel(Core::Global()) {} + File::File(Kernel::KernelSystem& kernel, std::unique_ptr&& backend, const FileSys::Path& path) : ServiceFramework("", 1), path(path), backend(std::move(backend)), kernel(kernel) { diff --git a/src/core/hle/service/fs/file.h b/src/core/hle/service/fs/file.h index 18317212e..98d448755 100644 --- a/src/core/hle/service/fs/file.h +++ b/src/core/hle/service/fs/file.h @@ -6,6 +6,7 @@ #include #include "core/file_sys/archive_backend.h" +#include "core/global.h" #include "core/hle/service/service.h" namespace Core { @@ -30,6 +31,7 @@ private: ar& size; ar& subfile; } + friend class boost::serialization::access; }; // TODO: File is not a real service, but it can still utilize ServiceFramework::RegisterHandlers. @@ -71,6 +73,15 @@ private: void OpenSubFile(Kernel::HLERequestContext& ctx); Kernel::KernelSystem& kernel; + + File(); + + template + void serialize(Archive& ar, const unsigned int); + friend class boost::serialization::access; }; } // namespace Service::FS + +BOOST_CLASS_EXPORT_KEY(Service::FS::FileSessionSlot) +BOOST_CLASS_EXPORT_KEY(Service::FS::File)