summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/fud_c_file.cpp91
1 files changed, 89 insertions, 2 deletions
diff --git a/source/fud_c_file.cpp b/source/fud_c_file.cpp
index 24186bf..3d15431 100644
--- a/source/fud_c_file.cpp
+++ b/source/fud_c_file.cpp
@@ -38,10 +38,13 @@ CBinaryFile::~CBinaryFile() {
close();
}
-FileResult CBinaryFile::open()
+FileStatus CBinaryFile::open()
{
+ if (!m_filename.valid()) {
+ return FileStatus::InvalidName;
+ }
m_file = fopen(m_filename.c_str(), m_mode.c_str());
- return m_file != nullptr ? FileResult::Success : FileResult::Error;
+ return m_file != nullptr ? FileStatus::Success : FileStatus::Error;
}
void CBinaryFile::close()
@@ -62,4 +65,88 @@ FILE* CBinaryFile::file()
return m_file;
}
+bool CBinaryFile::isOpen() const
+{
+ return m_file != nullptr;
+}
+
+Result<size_t, FileStatus> CBinaryFile::size() const
+{
+ using RetType = Result<size_t, FileStatus>;
+ if (!isOpen()) {
+ return RetType::error(FileStatus::InvalidState);
+ }
+
+ auto seekStatus = fseek(m_file, 0, SEEK_END);
+ if (seekStatus != 0) {
+ return RetType::error(FileStatus::Error);
+ }
+
+ auto fileSizeResult = ftell(m_file);
+ if (fileSizeResult < 0) {
+ return RetType::error(FileStatus::Error);
+ }
+
+ auto fileSize = static_cast<size_t>(fileSizeResult);
+
+ auto resetStatus = reset();
+ if (resetStatus != FileStatus::Success) {
+ return RetType::error(resetStatus);
+ }
+
+ return RetType::okay(fileSize);
+}
+
+FileStatus 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)
+{
+ if (length == 0) {
+ return FileStatus::Success;
+ }
+
+ if (destination == nullptr) {
+ return FileStatus::NullPointer;
+ }
+
+ if (offset > LONG_MAX || SIZE_MAX - offset < length || destinationSize < length) {
+ return FileStatus::InvalidArgument;
+ }
+
+ auto fileSizeResult = size();
+ if (fileSizeResult.isError()) {
+ return fileSizeResult.getError();
+ }
+
+ auto fileSize = fileSizeResult.getOkay();
+ if (offset + length > fileSize) {
+ return FileStatus::InvalidArgument;
+ }
+
+ auto seekResult = fseek(m_file, static_cast<long>(offset), SEEK_SET);
+ if (seekResult != 0) {
+ return FileStatus::Error;
+ }
+
+ auto* destPtr = static_cast<char*>(destination);
+ auto readResult = fread(destPtr, length, 1, m_file);
+ if (readResult != 1) {
+ static_cast<void>(reset());
+ return FileStatus::Error;
+ }
+
+ return FileStatus::Success;
+}
+
+FileStatus CBinaryFile::reset() const {
+ if (!isOpen()) {
+ return FileStatus::InvalidState;
+ }
+ auto result = fseek(m_file, 0, SEEK_SET);
+ return result == 0 ? FileStatus::Success : FileStatus::Error;
+}
+
} // namespace fud