diff options
Diffstat (limited to 'source/fud_c_file.cpp')
-rw-r--r-- | source/fud_c_file.cpp | 65 |
1 files changed, 62 insertions, 3 deletions
diff --git a/source/fud_c_file.cpp b/source/fud_c_file.cpp index a85fd00..cad4c9d 100644 --- a/source/fud_c_file.cpp +++ b/source/fud_c_file.cpp @@ -29,7 +29,7 @@ CBinaryFile::CBinaryFile(const String& filename, CFileMode mode) CBinaryFile::CBinaryFile(const String& filename, CFileMode mode, const String& extraFlags) : m_filename{filename}, m_extraFlags{extraFlags}, - m_mode{String(CBinaryFileModeFromFlags(mode)).append(extraFlags)}, + m_mode{String(CBinaryFileModeFromFlags(mode)).catenate(extraFlags)}, m_modeFlags{mode} { } @@ -137,8 +137,8 @@ ReadResult CBinaryFile::read(void* destination, size_t destinationSize, size_t l return result; } - auto* destPtr = static_cast<char*>(destination); - result.bytesRead = fread(destPtr, 1, length, m_file); + auto* destBytes = static_cast<char*>(destination); + result.bytesRead = fread(destBytes, 1, length, m_file); static_cast<void>(reset()); if (result.bytesRead != length) { result.status = FileStatus::PartialSuccess; @@ -149,6 +149,65 @@ ReadResult CBinaryFile::read(void* destination, size_t destinationSize, size_t l return result; } +WriteResult CBinaryFile::write(const void* source, size_t sourceSize, size_t length) +{ + auto offsetResult = size(); + if (offsetResult.isError()) { + return WriteResult{0, offsetResult.getError()}; + } + + return write(source, sourceSize, length, offsetResult.getOkay()); +} + +WriteResult CBinaryFile::write(const void* source, size_t sourceSize, size_t length, size_t offset) +{ + WriteResult result{}; + if (length == 0) { + return result; + } + + if (source == nullptr) { + result.status = FileStatus::NullPointer; + return result; + } + + if (offset > LONG_MAX || SIZE_MAX - offset < length || sourceSize < length) { + result.status = FileStatus::InvalidArgument; + return result; + } + + auto fileSizeResult = size(); + if (fileSizeResult.isError()) { + result.status = fileSizeResult.getError(); + return result; + } + + // TODO: proper way of handling this + auto fileSize = fileSizeResult.getOkay(); + int seekResult; + if (offset > fileSize) { + seekResult = fseek(m_file, 0, SEEK_END); + } else { + seekResult = fseek(m_file, static_cast<long>(offset), SEEK_SET); + } + + if (seekResult != 0) { + result.status = FileStatus::Error; + return result; + } + + auto* sourceBytes = static_cast<const char*>(source); + result.bytesWritten = fwrite(sourceBytes, 1, length, m_file); + static_cast<void>(reset()); + if (result.bytesWritten != length) { + result.status = FileStatus::PartialSuccess; + } else { + result.status = FileStatus::Success; + } + + return result; +} + FileStatus CBinaryFile::reset() const { if (!isOpen()) { return FileStatus::InvalidState; |