From b6967c8a9190efa4e9128850fa723fe3ea3140f7 Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Sat, 28 Sep 2024 11:14:31 -0500 Subject: Expand directory interface, remove FileStatus for FudStatus. --- source/fud_c_file.cpp | 46 +++++++------- source/fud_directory.cpp | 158 ++++++++++++++++++++++++++++++----------------- 2 files changed, 123 insertions(+), 81 deletions(-) (limited to 'source') diff --git a/source/fud_c_file.cpp b/source/fud_c_file.cpp index cad4c9d..b323847 100644 --- a/source/fud_c_file.cpp +++ b/source/fud_c_file.cpp @@ -38,13 +38,13 @@ CBinaryFile::~CBinaryFile() { close(); } -FileStatus CBinaryFile::open() +FudStatus CBinaryFile::open() { if (!m_filename.valid()) { - return FileStatus::InvalidName; + return FudStatus::ObjectInvalid; } m_file = fopen(m_filename.c_str(), m_mode.c_str()); - return m_file != nullptr ? FileStatus::Success : FileStatus::Error; + return m_file != nullptr ? FudStatus::Success : FudStatus::Failure; } void CBinaryFile::close() @@ -70,27 +70,27 @@ bool CBinaryFile::isOpen() const return m_file != nullptr; } -Result CBinaryFile::size() const +Result CBinaryFile::size() const { - using RetType = Result; + using RetType = Result; if (!isOpen()) { - return RetType::error(FileStatus::InvalidState); + return RetType::error(FudStatus::OperationInvalid); } auto seekStatus = fseek(m_file, 0, SEEK_END); if (seekStatus != 0) { - return RetType::error(FileStatus::Error); + return RetType::error(FudStatus::Failure); } auto fileSizeResult = ftell(m_file); if (fileSizeResult < 0) { - return RetType::error(FileStatus::Error); + return RetType::error(FudStatus::Failure); } auto fileSize = static_cast(fileSizeResult); auto resetStatus = reset(); - if (resetStatus != FileStatus::Success) { + if (resetStatus != FudStatus::Success) { return RetType::error(resetStatus); } @@ -110,12 +110,12 @@ ReadResult CBinaryFile::read(void* destination, size_t destinationSize, size_t l } if (destination == nullptr) { - result.status = FileStatus::NullPointer; + result.status = FudStatus::NullPointer; return result; } if (offset > LONG_MAX || SIZE_MAX - offset < length || destinationSize < length) { - result.status = FileStatus::InvalidArgument; + result.status = FudStatus::InvalidInput; return result; } @@ -127,13 +127,13 @@ ReadResult CBinaryFile::read(void* destination, size_t destinationSize, size_t l auto fileSize = fileSizeResult.getOkay(); if (offset + length > fileSize) { - result.status = FileStatus::InvalidArgument; + result.status = FudStatus::InvalidInput; return result; } auto seekResult = fseek(m_file, static_cast(offset), SEEK_SET); if (seekResult != 0) { - result.status = FileStatus::Error; + result.status = FudStatus::Failure; return result; } @@ -141,9 +141,9 @@ ReadResult CBinaryFile::read(void* destination, size_t destinationSize, size_t l result.bytesRead = fread(destBytes, 1, length, m_file); static_cast(reset()); if (result.bytesRead != length) { - result.status = FileStatus::PartialSuccess; + result.status = FudStatus::Partial; } else { - result.status = FileStatus::Success; + result.status = FudStatus::Success; } return result; @@ -167,12 +167,12 @@ WriteResult CBinaryFile::write(const void* source, size_t sourceSize, size_t len } if (source == nullptr) { - result.status = FileStatus::NullPointer; + result.status = FudStatus::NullPointer; return result; } if (offset > LONG_MAX || SIZE_MAX - offset < length || sourceSize < length) { - result.status = FileStatus::InvalidArgument; + result.status = FudStatus::InvalidInput; return result; } @@ -192,7 +192,7 @@ WriteResult CBinaryFile::write(const void* source, size_t sourceSize, size_t len } if (seekResult != 0) { - result.status = FileStatus::Error; + result.status = FudStatus::Failure; return result; } @@ -200,20 +200,20 @@ WriteResult CBinaryFile::write(const void* source, size_t sourceSize, size_t len result.bytesWritten = fwrite(sourceBytes, 1, length, m_file); static_cast(reset()); if (result.bytesWritten != length) { - result.status = FileStatus::PartialSuccess; + result.status = FudStatus::Partial; } else { - result.status = FileStatus::Success; + result.status = FudStatus::Success; } return result; } -FileStatus CBinaryFile::reset() const { +FudStatus CBinaryFile::reset() const { if (!isOpen()) { - return FileStatus::InvalidState; + return FudStatus::OperationInvalid; } auto result = fseek(m_file, 0, SEEK_SET); - return result == 0 ? FileStatus::Success : FileStatus::Error; + return result == 0 ? FudStatus::Success : FudStatus::Failure; } } // namespace fud diff --git a/source/fud_directory.cpp b/source/fud_directory.cpp index 39f2e10..99f3600 100644 --- a/source/fud_directory.cpp +++ b/source/fud_directory.cpp @@ -23,6 +23,57 @@ namespace fud { +using CStat = struct stat; +struct Stat : public CStat {}; + +Result DirectoryEntry::fromStat(const String& name, const Stat& statBuffer) +{ + using RetType = Result; + static_assert(std::is_same_v); + static_assert(sizeof(decltype(statBuffer.st_size)) <= sizeof(size_t)); + + static_assert(std::is_same_v); + static_assert(sizeof(decltype(statBuffer.st_nlink)) <= sizeof(size_t)); + + size_t size{0}; + if (statBuffer.st_size < 0) { + return RetType::error(FudStatus::Failure); + } else { + size = static_cast(statBuffer.st_size); + } + + DirectoryEntryType entryType; + switch (statBuffer.st_mode & S_IFMT) { + case S_IFBLK: + entryType = DirectoryEntryType::Block; + break; + case S_IFCHR: + entryType = DirectoryEntryType::Character; + break; + case S_IFDIR: + entryType = DirectoryEntryType::Directory; + break; + case S_IFIFO: + entryType = DirectoryEntryType::NamedPipe; + break; + case S_IFLNK: + entryType = DirectoryEntryType::SymbolicLink; + break; + case S_IFREG: + entryType = DirectoryEntryType::RegularFile; + break; + case S_IFSOCK: + entryType = DirectoryEntryType::UnixSocket; + break; + default: + entryType = DirectoryEntryType::Unknown; + break; + } + + return RetType::okay( + DirectoryEntry{name, size, static_cast(statBuffer.st_nlink), statBuffer.st_mtime, entryType}); +} + Directory::Directory(String name) : m_name{name} { if (!m_name.valid()) { @@ -81,11 +132,45 @@ Directory::~Directory() } } +bool Directory::valid() const +{ + return m_directory != nullptr && m_dirFd != -1; +} + +Result Directory::info() +{ + using RetType = Result; + + if (!valid()) { + m_status = FudStatus::ObjectInvalid; + return RetType::error(m_status); + } + + Stat statBuffer{}; + auto status = fstat(m_dirFd, &statBuffer); + if (status == -1) { + m_errorCode = errno; + m_status = FudStatus::Failure; + return RetType::error(m_status); + } + + auto retValue = DirectoryEntry::fromStat(m_name, statBuffer); + + if (retValue.isOkay()) { + m_errorCode = 0; + m_status = FudStatus::Success; + } else { + m_status = retValue.getError(); + } + + return retValue; +} + Result, FudStatus> Directory::getNextEntry() { using RetType = Result, FudStatus>; - if (m_directory == nullptr || m_dirFd == -1) { + if (!valid()) { m_status = FudStatus::ObjectInvalid; return RetType::error(m_status); } @@ -102,8 +187,8 @@ Result, FudStatus> Directory::getNextEntry() } } - const char* entryName = dirEntry->d_name; - if (entryName == nullptr) { + const char* entryNameCString = dirEntry->d_name; + if (entryNameCString == nullptr) { m_errorCode = -1; m_status = FudStatus::NullPointer; return RetType::error(m_status); @@ -111,82 +196,39 @@ Result, FudStatus> Directory::getNextEntry() m_errorCode = 0; - using Stat = struct stat; Stat statBuffer{}; auto flags = 0; - auto status = fstatat(m_dirFd, entryName, &statBuffer, flags); + auto status = fstatat(m_dirFd, entryNameCString, &statBuffer, flags); if (status == -1) { m_errorCode = errno; m_status = FudStatus::Failure; return RetType::error(m_status); } - DirectoryEntryType entryType; - switch (statBuffer.st_mode & S_IFMT) { - case S_IFBLK: - entryType = DirectoryEntryType::Block; - break; - case S_IFCHR: - entryType = DirectoryEntryType::Character; - break; - case S_IFDIR: - entryType = DirectoryEntryType::Directory; - break; - case S_IFIFO: - entryType = DirectoryEntryType::NamedPipe; - break; - case S_IFLNK: - entryType = DirectoryEntryType::SymbolicLink; - break; - case S_IFREG: - entryType = DirectoryEntryType::RegularFile; - break; - case S_IFSOCK: - entryType = DirectoryEntryType::UnixSocket; - break; - default: - entryType = DirectoryEntryType::Unknown; - break; - } - - static_assert(std::is_same_v); - static_assert(sizeof(decltype(statBuffer.st_size)) <= sizeof(size_t)); + auto entryName = String{entryNameCString}; + auto retValue = DirectoryEntry::fromStat(entryName, statBuffer); - size_t size{0}; - if (statBuffer.st_size < 0) { - size = SIZE_MAX; - } else { - size = static_cast(statBuffer.st_size); + if (retValue.isOkay()) { + m_errorCode = 0; + m_status = FudStatus::Success; + return RetType::okay(retValue.getOkay()); } - static_assert(std::is_same_v); - static_assert(sizeof(decltype(statBuffer.st_nlink)) <= sizeof(size_t)); - - DirectoryEntry entry{ - String{dirEntry->d_name}, - size, - static_cast(statBuffer.st_nlink), - statBuffer.st_mtime, - entryType}; - - if (!entry.name.valid()) { - m_status = FudStatus::StringInvalid; - return RetType::error(m_status); - } - - m_status = FudStatus::Success; - return RetType::okay(std::move(entry)); + m_status = retValue.getError(); + return RetType::error(retValue.getError()); } FudStatus Directory::reset() { + if (!valid()) { + } if (m_directory != nullptr) { rewinddir(m_directory); } else { m_status = FudStatus::ObjectInvalid; return m_status; } - return FudStatus::NotImplemented; + return FudStatus::Success; } } // namespace fud -- cgit v1.2.3