13 : m_file{file}, m_xor{
std::move(data_xor)}
16 auto pos{std::ftell(
m_file)};
23 if (!
m_file)
throw std::ios_base::failure(
"AutoFile::read: file handle is nullptr");
26 if (!
m_position.has_value())
throw std::ios_base::failure(
"AutoFile::read: position unknown");
36 throw std::ios_base::failure(
"AutoFile::seek: file handle is nullptr");
38 if (std::fseek(
m_file, offset, origin) != 0) {
39 throw std::ios_base::failure(
feof() ?
"AutoFile::seek: end of file" :
"AutoFile::seek: fseek failed");
41 if (origin == SEEK_SET) {
43 }
else if (origin == SEEK_CUR &&
m_position.has_value()) {
46 int64_t r{std::ftell(
m_file)};
48 throw std::ios_base::failure(
"AutoFile::seek: ftell failed");
56 if (!
m_position.has_value())
throw std::ios_base::failure(
"AutoFile::tell: position unknown");
63 throw std::ios_base::failure(
feof() ?
"AutoFile::read: end of file" :
"AutoFile::read: fread failed");
69 if (!
m_file)
throw std::ios_base::failure(
"AutoFile::ignore: file handle is nullptr");
70 unsigned char data[4096];
72 size_t nNow = std::min<size_t>(nSize,
sizeof(
data));
73 if (std::fread(
data, 1, nNow,
m_file) != nNow) {
74 throw std::ios_base::failure(
feof() ?
"AutoFile::ignore: end of file" :
"AutoFile::ignore: fread failed");
83 if (!
m_file)
throw std::ios_base::failure(
"AutoFile::write: file handle is nullptr");
86 throw std::ios_base::failure(
"AutoFile::write: write failed");
90 if (!
m_position.has_value())
throw std::ios_base::failure(
"AutoFile::write: position unknown");
91 std::array<std::byte, 4096> buf;
92 while (src.
size() > 0) {
93 auto buf_now{
Span{buf}.
first(std::min<size_t>(src.
size(), buf.size()))};
94 std::copy(src.
begin(), src.
begin() + buf_now.size(), buf_now.begin());
96 if (std::fwrite(buf_now.data(), 1, buf_now.size(),
m_file) != buf_now.size()) {
97 throw std::ios_base::failure{
"XorFile::write: failed"};
99 src = src.
subspan(buf_now.size());
void ignore(size_t nSize)
std::vector< std::byte > m_xor
void seek(int64_t offset, int origin)
Wrapper around fseek().
void read(Span< std::byte > dst)
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
bool Truncate(unsigned size)
Wrapper around TruncateFile().
std::size_t detail_fread(Span< std::byte > dst)
Implementation detail, only used internally.
std::optional< int64_t > m_position
AutoFile(std::FILE *file, std::vector< std::byte > data_xor={})
int64_t tell()
Find position within the file.
void write(Span< const std::byte > src)
bool Commit()
Wrapper around FileCommit().
size_t GetMemoryUsage() const noexcept
Compute total memory usage of this object (own memory + any dynamic memory).
A Span is an object that can refer to a contiguous sequence of objects.
constexpr std::size_t size() const noexcept
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
constexpr C * data() const noexcept
constexpr C * begin() const noexcept
bool TruncateFile(FILE *file, unsigned int length)
bool FileCommit(FILE *file)
Ensure file contents are fully committed to disk, using a platform-specific feature analogous to fsyn...
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
void Xor(Span< std::byte > write, Span< const std::byte > key, size_t key_offset=0)