diff options
author | crupest <crupest@outlook.com> | 2023-07-05 01:54:08 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2023-07-05 01:54:08 +0800 |
commit | bcfd51a7fabf7adf5f134247ca1020fac98b24b5 (patch) | |
tree | 41471cee6af6a7e49140e50ba818366b316c8ea7 /src | |
parent | aa9bc6bb7c11e810745c80548dd5ed5b2cb08740 (diff) | |
download | cru-bcfd51a7fabf7adf5f134247ca1020fac98b24b5.tar.gz cru-bcfd51a7fabf7adf5f134247ca1020fac98b24b5.tar.bz2 cru-bcfd51a7fabf7adf5f134247ca1020fac98b24b5.zip |
Add CFileStream. Move ErrnoException.
Diffstat (limited to 'src')
-rw-r--r-- | src/common/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/common/Exception.cpp | 11 | ||||
-rw-r--r-- | src/common/io/CFileStream.cpp | 132 | ||||
-rw-r--r-- | src/common/platform/unix/ErrnoException.cpp | 11 |
4 files changed, 145 insertions, 10 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index fb2dd471..2c7f28e0 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -6,6 +6,7 @@ add_library(CruBase String.cpp StringToNumberConverter.cpp StringUtil.cpp + io/CFileStream.cpp io/Stream.cpp io/Resource.cpp io/MemoryStream.cpp diff --git a/src/common/Exception.cpp b/src/common/Exception.cpp index 86816720..b0053bac 100644 --- a/src/common/Exception.cpp +++ b/src/common/Exception.cpp @@ -1,5 +1,9 @@ #include "cru/common/Exception.h" +#include "cru/common/Format.h" + +#include <cerrno> + namespace cru { Exception::Exception() {} @@ -14,4 +18,11 @@ const char* Exception::what() const noexcept { return utf8_message_.c_str(); } + +ErrnoException::ErrnoException(const String& message) + : ErrnoException(message, errno) {} + +ErrnoException::ErrnoException(const String& message, int errno_code) + : Exception(Format(u"{}. Errno is {}.", message, errno_code)), + errno_code_(errno_code) {} } // namespace cru diff --git a/src/common/io/CFileStream.cpp b/src/common/io/CFileStream.cpp new file mode 100644 index 00000000..de195538 --- /dev/null +++ b/src/common/io/CFileStream.cpp @@ -0,0 +1,132 @@ +#include "cru/common/io/CFileStream.h" +#include "cru/common/Exception.h" +#include "cru/common/io/Stream.h" + +#include <cstdio> + +namespace cru::io { +static bool ModeCanRead(const char* mode) { + for (const char* p = mode; *p != '\0'; p++) { + if (*p == 'r' || *p == '+') { + return true; + } + } + return false; +} + +static bool ModeCanWrite(const char* mode) { + for (const char* p = mode; *p != '\0'; p++) { + if (*p == 'w' || *p == 'a' || *p == '+') { + return true; + } + } + return false; +} + +CFileStream::CFileStream(const char* path, const char* mode) + : file_(std::fopen(path, mode)), + readable_(ModeCanRead(mode)), + writable_(ModeCanWrite(mode)), + auto_close_(true) { + if (file_ == nullptr) { + throw ErrnoException(u"Cannot open file."); + } +} + +CFileStream::CFileStream(std::FILE* file, bool readable, bool writable, + bool auto_close) + : file_(file), + readable_(readable), + writable_(writable), + auto_close_(auto_close) { + if (file_ == nullptr) { + throw Exception(u"File is NULL."); + } +} + +CFileStream::~CFileStream() { + if (auto_close_ && file_ != nullptr) { + std::fclose(file_); + } +} + +bool CFileStream::CanSeek() { + CheckClosed(); + return true; +} + +static int ConvertOriginFlag(Stream::SeekOrigin origin) { + switch (origin) { + case Stream::SeekOrigin::Begin: + return SEEK_SET; + case Stream::SeekOrigin::Current: + return SEEK_CUR; + case Stream::SeekOrigin::End: + return SEEK_END; + default: + throw Exception(u"Unknown seek origin."); + } +} + +Index CFileStream::Seek(Index offset, SeekOrigin origin) { + CheckClosed(); + if (std::fseek(file_, offset, ConvertOriginFlag(origin))) { + throw ErrnoException(u"Seek failed."); + } + return Tell(); +} + +Index CFileStream::Tell() { + CheckClosed(); + long position = std::ftell(file_); + if (position == -1) { + throw ErrnoException(u"Tell failed."); + } + return position; +} + +void CFileStream::Rewind() { + CheckClosed(); + std::rewind(file_); +} + +bool CFileStream::CanRead() { + CheckClosed(); + return readable_; +} + +Index CFileStream::Read(std::byte* buffer, Index offset, Index size) { + CheckClosed(); + auto count = std::fread(buffer + offset, 1, size, file_); + return count; +} + +bool CFileStream::CanWrite() { + CheckClosed(); + return writable_; +} + +Index CFileStream::Write(const std::byte* buffer, Index offset, Index size) { + CheckClosed(); + auto count = std::fwrite(buffer + offset, 1, size, file_); + return count; +} + +void CFileStream::Flush() { + CheckClosed(); + std::fflush(file_); +} + +void CFileStream::Close() { + if (file_ != nullptr) { + std::fclose(file_); + file_ = nullptr; + } +} + +void CFileStream::CheckClosed() { + if (file_ == nullptr) { + throw StreamAlreadyClosedException(u"File is closed."); + } +} +} // namespace cru::io diff --git a/src/common/platform/unix/ErrnoException.cpp b/src/common/platform/unix/ErrnoException.cpp index f2171943..06c42ff6 100644 --- a/src/common/platform/unix/ErrnoException.cpp +++ b/src/common/platform/unix/ErrnoException.cpp @@ -1,14 +1,5 @@ #include "cru/common/platform/unix/ErrnoException.h" -#include "cru/common/Format.h" - -#include <errno.h> - namespace cru::platform::unix { -ErrnoException::ErrnoException(const String& message) - : ErrnoException(message, errno) {} - -ErrnoException::ErrnoException(const String& message, int errno_code) - : PlatformException(Format(u"{}. Errno is {}.", message, errno_code)), - errno_code_(errno_code) {} +// Moved to Exception.cpp } // namespace cru::platform::unix |