mirror of
https://github.com/pound-emu/pound.git
synced 2025-12-13 04:36:57 +00:00
Major project restructuring
Remove unecessary files and made the tree much more cleaner. Signed-off-by: Ronald Caesar <github43132@proton.me>
This commit is contained in:
parent
13b2e741b9
commit
05c4f7025f
62 changed files with 2698 additions and 2453 deletions
231
core/common/IoFile.h
Normal file
231
core/common/IoFile.h
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
// Copyright 2025 Xenon Emulator Project. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <span>
|
||||
|
||||
#include "Enum.h"
|
||||
#include "PathUtil.h"
|
||||
|
||||
namespace Base::FS
|
||||
{
|
||||
|
||||
enum class FileAccessMode
|
||||
{
|
||||
/**
|
||||
* If the file at path exists, it opens the file for reading.
|
||||
* If the file at path does not exist, it fails to open the file.
|
||||
*/
|
||||
Read = 1 << 0,
|
||||
/**
|
||||
* If the file at path exists, the existing contents of the file are erased.
|
||||
* The empty file is then opened for writing.
|
||||
* If the file at path does not exist, it creates and opens a new empty file for writing.
|
||||
*/
|
||||
Write = 1 << 1,
|
||||
/**
|
||||
* If the file at path exists, it opens the file for reading and writing.
|
||||
* If the file at path does not exist, it fails to open the file.
|
||||
*/
|
||||
ReadWrite = Read | Write,
|
||||
/**
|
||||
* If the file at path exists, it opens the file for appending.
|
||||
* If the file at path does not exist, it creates and opens a new empty file for appending.
|
||||
*/
|
||||
Append = 1 << 2,
|
||||
/**
|
||||
* If the file at path exists, it opens the file for both reading and appending.
|
||||
* If the file at path does not exist, it creates and opens a new empty file for both
|
||||
* reading and appending.
|
||||
*/
|
||||
ReadAppend = Read | Append
|
||||
};
|
||||
DECLARE_ENUM_FLAG_OPERATORS(FileAccessMode)
|
||||
|
||||
enum class FileMode
|
||||
{
|
||||
BinaryMode,
|
||||
TextMode
|
||||
};
|
||||
|
||||
enum class FileShareFlag
|
||||
{
|
||||
ShareNone, // Provides exclusive access to the file.
|
||||
ShareReadOnly, // Provides read only shared access to the file.
|
||||
ShareWriteOnly, // Provides write only shared access to the file.
|
||||
ShareReadWrite // Provides read and write shared access to the file.
|
||||
};
|
||||
|
||||
enum class SeekOrigin : u32
|
||||
{
|
||||
SetOrigin, // Seeks from the start of the file.
|
||||
CurrentPosition, // Seeks from the current file pointer position.
|
||||
End // Seeks from the end of the file.
|
||||
};
|
||||
|
||||
class IOFile final
|
||||
{
|
||||
public:
|
||||
IOFile();
|
||||
|
||||
explicit IOFile(const std::string& path, FileAccessMode mode, FileMode type = FileMode::BinaryMode,
|
||||
FileShareFlag flag = FileShareFlag::ShareReadOnly);
|
||||
|
||||
explicit IOFile(std::string_view path, FileAccessMode mode, FileMode type = FileMode::BinaryMode,
|
||||
FileShareFlag flag = FileShareFlag::ShareReadOnly);
|
||||
explicit IOFile(const fs::path& path, FileAccessMode mode, FileMode type = FileMode::BinaryMode,
|
||||
FileShareFlag flag = FileShareFlag::ShareReadOnly);
|
||||
|
||||
~IOFile();
|
||||
|
||||
IOFile(const IOFile&) = delete;
|
||||
IOFile& operator=(const IOFile&) = delete;
|
||||
|
||||
IOFile(IOFile&& other) noexcept;
|
||||
IOFile& operator=(IOFile&& other) noexcept;
|
||||
|
||||
fs::path GetPath() const { return filePath; }
|
||||
|
||||
FileAccessMode GetAccessMode() const { return fileAccessMode; }
|
||||
|
||||
FileMode GetType() const { return fileType; }
|
||||
|
||||
bool IsOpen() const { return file != nullptr; }
|
||||
|
||||
uptr GetFileMapping();
|
||||
|
||||
int Open(const fs::path& path, FileAccessMode mode, FileMode type = FileMode::BinaryMode,
|
||||
FileShareFlag flag = FileShareFlag::ShareReadOnly);
|
||||
void Close();
|
||||
|
||||
void Unlink();
|
||||
|
||||
bool Flush() const;
|
||||
bool Commit() const;
|
||||
|
||||
bool SetSize(u64 size) const;
|
||||
u64 GetSize() const;
|
||||
|
||||
bool Seek(s64 offset, SeekOrigin origin = SeekOrigin::SetOrigin) const;
|
||||
s64 Tell() const;
|
||||
|
||||
template <typename T>
|
||||
size_t Read(T& data) const
|
||||
{
|
||||
if constexpr (std::contiguous_iterator<typename T::iterator>)
|
||||
{
|
||||
using ContiguousType = typename T::value_type;
|
||||
static_assert(std::is_trivially_copyable_v<ContiguousType>, "Data type must be trivially copyable.");
|
||||
return ReadSpan<ContiguousType>(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ReadObject(data) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t Write(const T& data) const
|
||||
{
|
||||
if constexpr (std::contiguous_iterator<typename T::iterator>)
|
||||
{
|
||||
using ContiguousType = typename T::value_type;
|
||||
static_assert(std::is_trivially_copyable_v<ContiguousType>, "Data type must be trivially copyable.");
|
||||
return WriteSpan<ContiguousType>(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
||||
return WriteObject(data) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t ReadSpan(std::span<T> data) const
|
||||
{
|
||||
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
||||
|
||||
if (!IsOpen())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ReadRaw<T>(data.data(), data.size());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t ReadRaw(void* data, size_t size) const
|
||||
{
|
||||
return std::fread(data, sizeof(T), size, file);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t WriteSpan(std::span<const T> data) const
|
||||
{
|
||||
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
||||
|
||||
if (!IsOpen())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return std::fwrite(data.data(), sizeof(T), data.size(), file);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ReadObject(T& object) const
|
||||
{
|
||||
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
||||
static_assert(!std::is_pointer_v<T>, "T must not be a pointer to an object.");
|
||||
|
||||
if (!IsOpen())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return std::fread(&object, sizeof(T), 1, file) == 1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
size_t WriteRaw(const void* data, size_t size) const
|
||||
{
|
||||
return std::fwrite(data, sizeof(T), size, file);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool WriteObject(const T& object) const
|
||||
{
|
||||
static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable.");
|
||||
static_assert(!std::is_pointer_v<T>, "T must not be a pointer to an object.");
|
||||
|
||||
if (!IsOpen())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return std::fwrite(&object, sizeof(T), 1, file) == 1;
|
||||
}
|
||||
|
||||
std::string ReadString(size_t length) const;
|
||||
|
||||
size_t WriteString(std::span<const char> string) const { return WriteSpan(string); }
|
||||
|
||||
static size_t WriteBytes(const fs::path path, const auto& data)
|
||||
{
|
||||
IOFile out(path, FileAccessMode::Write);
|
||||
return out.Write(data);
|
||||
}
|
||||
|
||||
private:
|
||||
fs::path filePath{};
|
||||
FileAccessMode fileAccessMode{};
|
||||
FileMode fileType{};
|
||||
|
||||
std::FILE* file = nullptr;
|
||||
uptr fileMapping = 0;
|
||||
};
|
||||
|
||||
u64 GetDirectorySize(const fs::path& path);
|
||||
|
||||
} // namespace Base::FS
|
||||
Loading…
Add table
Add a link
Reference in a new issue