diff options
-rw-r--r-- | include/fud_c_file.hpp | 26 | ||||
-rw-r--r-- | source/fud_c_file.cpp | 34 |
2 files changed, 41 insertions, 19 deletions
diff --git a/include/fud_c_file.hpp b/include/fud_c_file.hpp index b48e8a0..f563a35 100644 --- a/include/fud_c_file.hpp +++ b/include/fud_c_file.hpp @@ -80,6 +80,7 @@ constexpr const char* CTextFileModeFromFlags(CFileMode mode) enum class FileStatus { Success, + PartialSuccess, InvalidName, InvalidArgument, InvalidState, @@ -91,6 +92,8 @@ static inline const char* FileStatusToString(FileStatus status) { switch (status) { case FileStatus::Success: return "Success"; + case FileStatus::PartialSuccess: + return "PartialSuccess"; case FileStatus::InvalidName: return "InvalidName"; case FileStatus::InvalidArgument: @@ -106,6 +109,11 @@ static inline const char* FileStatusToString(FileStatus status) { } } +struct [[nodiscard]] ReadResult { + size_t bytesRead{0}; + FileStatus status{FileStatus::Success}; +}; + class CBinaryFile { public: CBinaryFile(const String& filename, CFileMode mode); @@ -122,15 +130,21 @@ class CBinaryFile { [[nodiscard]] Result<size_t, FileStatus> size() const; - template <typename T> - [[nodiscard]] FileStatus read(T& destination, size_t length); + [[nodiscard]] ReadResult read(void* destination, size_t destinationSize, size_t length); - template <typename T> - [[nodiscard]] FileStatus read(T& destination, size_t length, size_t offset); + [[nodiscard]] ReadResult read(void* destination, size_t destinationSize, size_t length, size_t offset); - [[nodiscard]] FileStatus read(void* destination, size_t destinationSize, size_t length); + template <typename T> + [[nodiscard]] ReadResult read(T& destination, size_t length) + { + return read(destination, length, 0); + } - [[nodiscard]] FileStatus read(void* destination, size_t destinationSize, size_t length, size_t offset); + template <typename T> + [[nodiscard]] ReadResult read(T& destination, size_t length, size_t offset) + { + return read(&destination, sizeof(destination), length, offset); + } private: FileStatus reset() const; diff --git a/source/fud_c_file.cpp b/source/fud_c_file.cpp index 3d15431..a85fd00 100644 --- a/source/fud_c_file.cpp +++ b/source/fud_c_file.cpp @@ -97,48 +97,56 @@ Result<size_t, FileStatus> CBinaryFile::size() const return RetType::okay(fileSize); } -FileStatus CBinaryFile::read(void* destination, size_t destinationSize, size_t length) +ReadResult CBinaryFile::read(void* destination, size_t destinationSize, size_t length) { return read(destination, destinationSize, length, 0); } -FileStatus CBinaryFile::read(void* destination, size_t destinationSize, size_t length, size_t offset) +ReadResult CBinaryFile::read(void* destination, size_t destinationSize, size_t length, size_t offset) { + ReadResult result{}; if (length == 0) { - return FileStatus::Success; + return result; } if (destination == nullptr) { - return FileStatus::NullPointer; + result.status = FileStatus::NullPointer; + return result; } if (offset > LONG_MAX || SIZE_MAX - offset < length || destinationSize < length) { - return FileStatus::InvalidArgument; + result.status = FileStatus::InvalidArgument; + return result; } auto fileSizeResult = size(); if (fileSizeResult.isError()) { - return fileSizeResult.getError(); + result.status = fileSizeResult.getError(); + return result; } auto fileSize = fileSizeResult.getOkay(); if (offset + length > fileSize) { - return FileStatus::InvalidArgument; + result.status = FileStatus::InvalidArgument; + return result; } auto seekResult = fseek(m_file, static_cast<long>(offset), SEEK_SET); if (seekResult != 0) { - return FileStatus::Error; + result.status = FileStatus::Error; + return result; } auto* destPtr = static_cast<char*>(destination); - auto readResult = fread(destPtr, length, 1, m_file); - if (readResult != 1) { - static_cast<void>(reset()); - return FileStatus::Error; + result.bytesRead = fread(destPtr, 1, length, m_file); + static_cast<void>(reset()); + if (result.bytesRead != length) { + result.status = FileStatus::PartialSuccess; + } else { + result.status = FileStatus::Success; } - return FileStatus::Success; + return result; } FileStatus CBinaryFile::reset() const { |