132 lines
2.9 KiB
C++
132 lines
2.9 KiB
C++
/*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <cstdio>
|
|
#include <filesystem>
|
|
|
|
namespace OpenVulkano
|
|
{
|
|
class CFile
|
|
{
|
|
static constexpr std::array<char[4], 12> MODE_STRINGS = { "r", "rb", "w", "wb", "a", "ab", "r+", "rb+", "w+", "wb+", "a+", "ab+" };
|
|
static constexpr std::array<wchar_t[4], 12> MODE_STRINGS_W = { L"r", L"rb", L"w", L"wb", L"a", L"ab", L"r+", L"rb+", L"w+", L"wb+", L"a+", L"ab+" };
|
|
|
|
public:
|
|
enum Mode
|
|
{
|
|
READ = 0,
|
|
READ_BINARY,
|
|
WRITE,
|
|
WRITE_BINARY,
|
|
APPEND,
|
|
APPEND_BINARY,
|
|
READ_WRITE, // Null if file does not exist
|
|
READ_WRITE_BINARY, // Null if file does not exist
|
|
WRITE_READ, // Creates file if not exists
|
|
WRITE_READ_BINARY, // Creates file if not exists
|
|
APPEND_READ,
|
|
APPEND_READ_BINARY,
|
|
};
|
|
|
|
FILE* f = nullptr;
|
|
|
|
CFile() = default;
|
|
|
|
CFile(const std::filesystem::path& path, const Mode mode) : CFile(path.c_str(), mode)
|
|
{}
|
|
|
|
template<typename T>
|
|
CFile(const T* path, Mode mode) requires std::is_same_v<T, char> || std::is_same_v<T, wchar_t> : f(FOpen(path, mode))
|
|
{}
|
|
|
|
CFile(const CFile&) = delete;
|
|
CFile& operator=(const CFile&) = delete;
|
|
|
|
CFile(CFile&& other) noexcept : f(other.f)
|
|
{
|
|
other.f = nullptr;
|
|
}
|
|
|
|
CFile& operator=(CFile&& other) noexcept
|
|
{
|
|
Close();
|
|
f = other.f;
|
|
other.f = nullptr;
|
|
return *this;
|
|
}
|
|
|
|
~CFile()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
void Close()
|
|
{
|
|
if (f)
|
|
{
|
|
fclose(f);
|
|
f = nullptr;
|
|
}
|
|
}
|
|
|
|
void Open(const std::filesystem::path& path, const Mode mode)
|
|
{
|
|
Close(); // Close current
|
|
f = FOpen(path.c_str(), mode);
|
|
}
|
|
|
|
template<typename T>
|
|
void Open(const T* path, const Mode mode) requires std::is_same_v<T, char> || std::is_same_v<T, wchar_t>
|
|
{
|
|
f = FOpen(path, mode);
|
|
}
|
|
|
|
size_t Read(void* data, const size_t elementSize, const size_t elementCount = 1) const
|
|
{
|
|
return fread(data, elementSize, elementCount, f);
|
|
}
|
|
|
|
size_t Write(const void* data, const size_t elementSize, const size_t elementCount = 1) const
|
|
{
|
|
return fwrite(data, elementSize, elementCount, f);
|
|
}
|
|
|
|
int Put(const char c) const
|
|
{
|
|
return fputc(c, f);
|
|
}
|
|
|
|
void Seek(const long position, const int mode = SEEK_SET) const
|
|
{
|
|
fseek(f, position, mode);
|
|
}
|
|
|
|
[[nodiscard]] long Tell() const
|
|
{
|
|
return ftell(f);
|
|
}
|
|
|
|
FILE* FilePtr() const { return f; }
|
|
|
|
[[nodiscard]] operator bool() const noexcept { return f != nullptr; }
|
|
|
|
[[nodiscard]] operator FILE*() const noexcept { return f; }
|
|
|
|
// Helper function, might be used outside off class
|
|
template<typename T>
|
|
[[nodiscard]] static FILE* FOpen(const T* path, const Mode mode) requires std::is_same_v<T, char> || std::is_same_v<T, wchar_t>
|
|
{
|
|
if constexpr (std::is_same_v<T, char>)
|
|
return fopen(path, MODE_STRINGS[mode]);
|
|
else
|
|
return _wfopen(path, MODE_STRINGS_W[mode]);
|
|
}
|
|
};
|
|
}
|