summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/fud_c_file.hpp26
-rw-r--r--source/fud_c_file.cpp34
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 {