mirror of https://github.com/libAthena/athena.git
FileWriterWin32: Handle large files within writeUBytes
Handles the case where a given size exceeds the maximum value that can be contained within a DWORD. Given a DWORD is 32-bit in size and an atUint64 is 64-bits in size, this avoids errors on valid sizes, even if they're extremely unlikely to ever occur.
This commit is contained in:
parent
462146b644
commit
3b1348a26a
|
@ -1,5 +1,10 @@
|
||||||
#include "athena/FileWriter.hpp"
|
#include "athena/FileWriter.hpp"
|
||||||
#include "win32_largefilewrapper.h"
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#undef min
|
||||||
|
#undef max
|
||||||
|
|
||||||
namespace athena::io {
|
namespace athena::io {
|
||||||
FileWriter::FileWriter(std::string_view filename, bool overwrite, bool globalErr)
|
FileWriter::FileWriter(std::string_view filename, bool overwrite, bool globalErr)
|
||||||
|
@ -96,19 +101,29 @@ atUint64 FileWriter::length() const { return utility::fileSize(m_filename); }
|
||||||
|
|
||||||
void FileWriter::writeUBytes(const atUint8* data, atUint64 len) {
|
void FileWriter::writeUBytes(const atUint8* data, atUint64 len) {
|
||||||
if (!isOpen()) {
|
if (!isOpen()) {
|
||||||
if (m_globalErr)
|
if (m_globalErr) {
|
||||||
atError(fmt("File not open for writing"));
|
atError(fmt("File not open for writing"));
|
||||||
|
}
|
||||||
setError();
|
setError();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD ret = 0;
|
atUint64 remaining = len;
|
||||||
WriteFile(m_fileHandle, data, len, &ret, nullptr);
|
do {
|
||||||
if (ret != len) {
|
const auto toWrite = static_cast<DWORD>(std::min(remaining, atUint64{std::numeric_limits<DWORD>::max()}));
|
||||||
if (m_globalErr)
|
DWORD written = 0;
|
||||||
atError(fmt("Unable to write to stream"));
|
|
||||||
setError();
|
if (WriteFile(m_fileHandle, data, toWrite, &written, nullptr) == FALSE) {
|
||||||
}
|
if (m_globalErr) {
|
||||||
|
atError(fmt("Unable to write to file"));
|
||||||
|
}
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining -= written;
|
||||||
|
data += written;
|
||||||
|
} while (remaining != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace athena::io
|
} // namespace athena::io
|
||||||
|
|
Loading…
Reference in New Issue