mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 13:31:27 +12:00
139 lines
4.5 KiB
C++
139 lines
4.5 KiB
C++
#pragma once
|
|
|
|
#include "util/serialization.hpp"
|
|
|
|
#include "Utilities/Thread.h"
|
|
|
|
namespace fs
|
|
{
|
|
class file;
|
|
}
|
|
|
|
// Uncompressed file serialization handler
|
|
struct uncompressed_serialization_file_handler : utils::serialization_file_handler
|
|
{
|
|
const std::unique_ptr<fs::file> m_file_storage;
|
|
const std::add_pointer_t<const fs::file> m_file;
|
|
|
|
explicit uncompressed_serialization_file_handler(fs::file&& file) noexcept
|
|
: utils::serialization_file_handler()
|
|
, m_file_storage(std::make_unique<fs::file>(std::move(file)))
|
|
, m_file(m_file_storage.get())
|
|
{
|
|
}
|
|
|
|
explicit uncompressed_serialization_file_handler(const fs::file& file) noexcept
|
|
: utils::serialization_file_handler()
|
|
, m_file_storage(nullptr)
|
|
, m_file(std::addressof(file))
|
|
{
|
|
}
|
|
|
|
uncompressed_serialization_file_handler(const uncompressed_serialization_file_handler&) = delete;
|
|
uncompressed_serialization_file_handler& operator=(const uncompressed_serialization_file_handler&) = delete;
|
|
|
|
// Handle file read and write requests
|
|
bool handle_file_op(utils::serial& ar, usz pos, usz size, const void* data) override;
|
|
|
|
// Get available memory or file size
|
|
// Preferably memory size if is already greater/equal to recommended to avoid additional file ops
|
|
usz get_size(const utils::serial& ar, usz recommended) const override;
|
|
|
|
void finalize(utils::serial& ar) override;
|
|
};
|
|
|
|
template <typename File> requires (std::is_same_v<std::remove_cvref_t<File>, fs::file>)
|
|
inline std::unique_ptr<uncompressed_serialization_file_handler> make_uncompressed_serialization_file_handler(File&& file)
|
|
{
|
|
ensure(file);
|
|
return std::make_unique<uncompressed_serialization_file_handler>(std::forward<File>(file));
|
|
}
|
|
|
|
struct compressed_stream_data;
|
|
|
|
// Compressed file serialization handler
|
|
struct compressed_serialization_file_handler : utils::serialization_file_handler
|
|
{
|
|
explicit compressed_serialization_file_handler(fs::file&& file) noexcept
|
|
: utils::serialization_file_handler()
|
|
, m_file_storage(std::make_unique<fs::file>(std::move(file)))
|
|
, m_file(m_file_storage.get())
|
|
{
|
|
}
|
|
|
|
explicit compressed_serialization_file_handler(const fs::file& file) noexcept
|
|
: utils::serialization_file_handler()
|
|
, m_file_storage(nullptr)
|
|
, m_file(std::addressof(file))
|
|
{
|
|
}
|
|
|
|
compressed_serialization_file_handler(const compressed_serialization_file_handler&) = delete;
|
|
compressed_serialization_file_handler& operator=(const compressed_serialization_file_handler&) = delete;
|
|
|
|
// Handle file read and write requests
|
|
bool handle_file_op(utils::serial& ar, usz pos, usz size, const void* data) override;
|
|
|
|
// Get available memory or file size
|
|
// Preferably memory size if is already greater/equal to recommended to avoid additional file ops
|
|
usz get_size(const utils::serial& ar, usz recommended) const override;
|
|
void skip_until(utils::serial& ar) override;
|
|
|
|
bool is_valid() const override
|
|
{
|
|
return !m_errored;
|
|
}
|
|
|
|
void finalize(utils::serial& ar) override;
|
|
|
|
private:
|
|
const std::unique_ptr<fs::file> m_file_storage;
|
|
const std::add_pointer_t<const fs::file> m_file;
|
|
std::vector<u8> m_stream_data;
|
|
usz m_stream_data_index = 0;
|
|
usz m_file_read_index = 0;
|
|
atomic_t<usz> m_pending_bytes = 0;
|
|
atomic_t<bool> m_pending_signal = false;
|
|
bool m_write_inited = false;
|
|
bool m_read_inited = false;
|
|
bool m_errored = false;
|
|
std::shared_ptr<compressed_stream_data> m_stream;
|
|
std::unique_ptr<named_thread<std::function<void()>>> m_stream_data_prepare_thread;
|
|
std::unique_ptr<named_thread<std::function<void()>>> m_file_writer_thread;
|
|
|
|
usz read_at(utils::serial& ar, usz read_pos, void* data, usz size);
|
|
void initialize(utils::serial& ar);
|
|
void stream_data_prepare_thread_op();
|
|
void file_writer_thread_op();
|
|
void blocked_compressed_write(const std::vector<u8>& data);
|
|
};
|
|
|
|
template <typename File> requires (std::is_same_v<std::remove_cvref_t<File>, fs::file>)
|
|
inline std::unique_ptr<compressed_serialization_file_handler> make_compressed_serialization_file_handler(File&& file)
|
|
{
|
|
ensure(file);
|
|
return std::make_unique<compressed_serialization_file_handler>(std::forward<File>(file));
|
|
}
|
|
|
|
// Null file serialization handler
|
|
struct null_serialization_file_handler : utils::serialization_file_handler
|
|
{
|
|
explicit null_serialization_file_handler() noexcept
|
|
{
|
|
}
|
|
|
|
// Handle file read and write requests
|
|
bool handle_file_op(utils::serial& ar, usz pos, usz size, const void* data) override;
|
|
|
|
void finalize(utils::serial& ar) override;
|
|
|
|
bool is_null() const override
|
|
{
|
|
return true;
|
|
}
|
|
};
|
|
|
|
inline std::unique_ptr<null_serialization_file_handler> make_null_serialization_file_handler()
|
|
{
|
|
return std::make_unique<null_serialization_file_handler>();
|
|
}
|