mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-22 05:03:56 +00:00
Cleanup snapshot generation
This commit is contained in:
@@ -5,12 +5,13 @@
|
||||
|
||||
namespace utils
|
||||
{
|
||||
template <typename T, typename S = const uint8_t>
|
||||
requires(std::is_trivially_copyable_v<T> && std::is_same_v<uint8_t, std::remove_cv_t<S>>)
|
||||
template <typename Type, typename SpanElement = const std::byte>
|
||||
requires(std::is_trivially_copyable_v<Type> && (std::is_same_v<uint8_t, std::remove_cv_t<SpanElement>> ||
|
||||
std::is_same_v<std::byte, std::remove_cv_t<SpanElement>>))
|
||||
class safe_object_accessor
|
||||
{
|
||||
public:
|
||||
safe_object_accessor(const std::span<S> buffer, const size_t offset)
|
||||
safe_object_accessor(const std::span<SpanElement> buffer, const size_t offset)
|
||||
: buffer_(buffer),
|
||||
offset_(offset)
|
||||
{
|
||||
@@ -21,25 +22,25 @@ namespace utils
|
||||
* are respected
|
||||
****************************************************************************/
|
||||
|
||||
T get(const size_t element_index = 0) const
|
||||
Type get(const size_t element_index = 0) const
|
||||
{
|
||||
T value{};
|
||||
Type value{};
|
||||
memcpy(&value, get_valid_pointer(element_index), size);
|
||||
return value;
|
||||
}
|
||||
|
||||
void set(const T value, const size_t element_index = 0) const
|
||||
void set(const Type value, const size_t element_index = 0) const
|
||||
{
|
||||
memcpy(get_valid_pointer(element_index), &value, size);
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr auto size = sizeof(T);
|
||||
static constexpr auto size = sizeof(Type);
|
||||
|
||||
std::span<S> buffer_{};
|
||||
std::span<SpanElement> buffer_{};
|
||||
size_t offset_{};
|
||||
|
||||
S* get_valid_pointer(const size_t element_index) const
|
||||
SpanElement* get_valid_pointer(const size_t element_index) const
|
||||
{
|
||||
const auto start_offset = offset_ + (size * element_index);
|
||||
const auto end_offset = start_offset + size;
|
||||
@@ -52,29 +53,31 @@ namespace utils
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
requires(std::is_same_v<uint8_t, std::remove_cv_t<T>>)
|
||||
template <typename SpanElement>
|
||||
requires(std::is_same_v<uint8_t, std::remove_cv_t<SpanElement>> ||
|
||||
std::is_same_v<std::byte, std::remove_cv_t<SpanElement>>)
|
||||
class safe_buffer_accessor
|
||||
{
|
||||
public:
|
||||
safe_buffer_accessor(const std::span<T> buffer)
|
||||
safe_buffer_accessor(const std::span<SpanElement> buffer)
|
||||
: buffer_(buffer)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
safe_buffer_accessor(const safe_buffer_accessor<S>& obj)
|
||||
template <typename OtherSpanElement>
|
||||
requires(std::is_same_v<std::remove_cv_t<SpanElement>, std::remove_cv_t<OtherSpanElement>>)
|
||||
safe_buffer_accessor(const safe_buffer_accessor<OtherSpanElement>& obj)
|
||||
: buffer_(obj.get_buffer())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
safe_object_accessor<S, T> as(const size_t offset) const
|
||||
template <typename Type>
|
||||
safe_object_accessor<Type, SpanElement> as(const size_t offset) const
|
||||
{
|
||||
return {this->buffer_, offset};
|
||||
}
|
||||
|
||||
T* get_pointer_for_range(const size_t offset, const size_t size) const
|
||||
SpanElement* get_pointer_for_range(const size_t offset, const size_t size) const
|
||||
{
|
||||
this->validate(offset, size);
|
||||
return this->buffer_.data() + offset;
|
||||
@@ -89,11 +92,11 @@ namespace utils
|
||||
}
|
||||
}
|
||||
|
||||
template <typename S = char>
|
||||
std::basic_string<S> as_string(const size_t offset) const
|
||||
template <typename Char = char>
|
||||
std::basic_string<Char> as_string(const size_t offset) const
|
||||
{
|
||||
safe_object_accessor<S> string_accessor{this->buffer_, offset};
|
||||
std::basic_string<S> result{};
|
||||
safe_object_accessor<Char> string_accessor{this->buffer_, offset};
|
||||
std::basic_string<Char> result{};
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -107,12 +110,12 @@ namespace utils
|
||||
}
|
||||
}
|
||||
|
||||
std::span<T> get_buffer() const
|
||||
std::span<SpanElement> get_buffer() const
|
||||
{
|
||||
return this->buffer_;
|
||||
}
|
||||
|
||||
private:
|
||||
const std::span<T> buffer_{};
|
||||
const std::span<SpanElement> buffer_{};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <zlib.h>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace utils::compression
|
||||
@@ -48,16 +49,16 @@ namespace utils::compression
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t> decompress(const std::span<const std::uint8_t> data)
|
||||
std::vector<std::byte> decompress(const std::span<const std::byte> data)
|
||||
{
|
||||
std::vector<std::uint8_t> buffer{};
|
||||
std::vector<std::byte> buffer{};
|
||||
zlib_stream stream_container{};
|
||||
if (!stream_container.is_valid())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
static thread_local std::array<uint8_t, ZCHUNK_SIZE> dest{};
|
||||
static thread_local std::array<std::byte, ZCHUNK_SIZE> dest{};
|
||||
auto& stream = stream_container.get();
|
||||
|
||||
stream.avail_in = static_cast<uInt>(data.size());
|
||||
@@ -66,7 +67,7 @@ namespace utils::compression
|
||||
do
|
||||
{
|
||||
stream.avail_out = static_cast<uInt>(dest.size());
|
||||
stream.next_out = dest.data();
|
||||
stream.next_out = reinterpret_cast<uint8_t*>(dest.data());
|
||||
|
||||
const auto ret = inflate(&stream, Z_FINISH);
|
||||
if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_STREAM_END)
|
||||
@@ -80,14 +81,9 @@ namespace utils::compression
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t> decompress(const std::span<const std::byte>& data)
|
||||
std::vector<std::byte> compress(const std::span<const std::byte> data)
|
||||
{
|
||||
return decompress(std::span(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t> compress(const std::span<const std::uint8_t> data)
|
||||
{
|
||||
std::vector<std::uint8_t> result{};
|
||||
std::vector<std::byte> result{};
|
||||
auto length = compressBound(static_cast<uLong>(data.size()));
|
||||
result.resize(length);
|
||||
|
||||
@@ -100,10 +96,5 @@ namespace utils::compression
|
||||
result.resize(length);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::uint8_t> compress(const std::span<const std::byte> data)
|
||||
{
|
||||
return compress(std::span(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,13 @@
|
||||
|
||||
#include <span>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
namespace utils::compression
|
||||
{
|
||||
namespace zlib
|
||||
{
|
||||
constexpr unsigned int ZCHUNK_SIZE = 16384u;
|
||||
std::vector<std::uint8_t> compress(std::span<const std::uint8_t> data);
|
||||
std::vector<std::uint8_t> compress(std::span<const std::byte> data);
|
||||
std::vector<std::uint8_t> decompress(std::span<const std::uint8_t> data);
|
||||
std::vector<std::uint8_t> decompress(std::span<const std::byte> data);
|
||||
std::vector<std::byte> compress(std::span<const std::byte> data);
|
||||
std::vector<std::byte> decompress(std::span<const std::byte> data);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace utils::io
|
||||
return std::ifstream(file).good();
|
||||
}
|
||||
|
||||
bool write_file(const std::filesystem::path& file, const std::span<const uint8_t> data, const bool append)
|
||||
bool write_file(const std::filesystem::path& file, const std::span<const std::byte> data, const bool append)
|
||||
{
|
||||
if (file.has_parent_path())
|
||||
{
|
||||
@@ -41,34 +41,42 @@ namespace utils::io
|
||||
return false;
|
||||
}
|
||||
|
||||
bool write_file(const std::filesystem::path& file, const std::span<const std::byte> data, const bool append)
|
||||
std::vector<std::byte> read_file(const std::filesystem::path& file)
|
||||
{
|
||||
return write_file(file, std::span(reinterpret_cast<const uint8_t*>(data.data()), data.size()), append);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> read_file(const std::filesystem::path& file)
|
||||
{
|
||||
std::vector<uint8_t> data;
|
||||
std::vector<std::byte> data{};
|
||||
read_file(file, &data);
|
||||
return data;
|
||||
}
|
||||
|
||||
bool read_file(const std::filesystem::path& file, std::vector<uint8_t>* data)
|
||||
bool read_file(const std::filesystem::path& file, std::vector<std::byte>* data)
|
||||
{
|
||||
if (!data)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
data->clear();
|
||||
*data = {};
|
||||
|
||||
std::ifstream stream(file, std::ios::binary);
|
||||
if (!stream)
|
||||
std::ifstream file_stream(file, std::ios::binary);
|
||||
if (!file_stream)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*data = std::vector<uint8_t>{(std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>()};
|
||||
std::vector<char> temp_buffer(0x1000);
|
||||
|
||||
while (file_stream)
|
||||
{
|
||||
file_stream.read(temp_buffer.data(), static_cast<std::streamsize>(temp_buffer.size()));
|
||||
const auto bytes_read = file_stream.gcount();
|
||||
|
||||
if (bytes_read > 0)
|
||||
{
|
||||
const auto* buffer = reinterpret_cast<const std::byte*>(temp_buffer.data());
|
||||
data->insert(data->end(), buffer, buffer + bytes_read);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,9 @@ namespace utils::io
|
||||
bool remove_file(const std::filesystem::path& file);
|
||||
bool move_file(const std::filesystem::path& src, const std::filesystem::path& target);
|
||||
bool file_exists(const std::filesystem::path& file);
|
||||
bool write_file(const std::filesystem::path& file, std::span<const uint8_t> data, bool append = false);
|
||||
bool write_file(const std::filesystem::path& file, std::span<const std::byte> data, bool append = false);
|
||||
bool read_file(const std::filesystem::path& file, std::vector<uint8_t>* data);
|
||||
std::vector<uint8_t> read_file(const std::filesystem::path& file);
|
||||
bool read_file(const std::filesystem::path& file, std::vector<std::byte>* data);
|
||||
std::vector<std::byte> read_file(const std::filesystem::path& file);
|
||||
size_t file_size(const std::filesystem::path& file);
|
||||
bool create_directory(const std::filesystem::path& directory);
|
||||
bool directory_exists(const std::filesystem::path& directory);
|
||||
|
||||
Reference in New Issue
Block a user