diff options
-rw-r--r-- | include/cru/common/ErrnoException.hpp | 22 | ||||
-rw-r--r-- | include/cru/common/io/Stream.hpp | 2 | ||||
-rw-r--r-- | include/cru/common/io/UnixFileStream.hpp | 41 | ||||
-rw-r--r-- | include/cru/platform/UnixFileStream.hpp | 20 | ||||
-rw-r--r-- | src/common/CMakeLists.txt | 8 | ||||
-rw-r--r-- | src/common/ErrnoException.cpp | 11 | ||||
-rw-r--r-- | src/common/io/Stream.cpp | 2 | ||||
-rw-r--r-- | src/common/io/UnixFileStream.cpp | 125 | ||||
-rw-r--r-- | src/platform/CMakeLists.txt | 9 | ||||
-rw-r--r-- | src/platform/UnixFileStream.cpp | 3 | ||||
-rw-r--r-- | src/platform/filesystem/CMakeLists.txt | 0 |
11 files changed, 211 insertions, 32 deletions
diff --git a/include/cru/common/ErrnoException.hpp b/include/cru/common/ErrnoException.hpp new file mode 100644 index 00000000..6feb1aca --- /dev/null +++ b/include/cru/common/ErrnoException.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "Exception.hpp" + +namespace cru { +class ErrnoException : public Exception { + public: + ErrnoException() : ErrnoException(String{}) {} + explicit ErrnoException(const String& message); + ErrnoException(const String& message, int errno_code); + + CRU_DELETE_COPY(ErrnoException) + CRU_DELETE_MOVE(ErrnoException) + + ~ErrnoException() override = default; + + int GetErrnoCode() const { return errno_code_; } + + private: + int errno_code_; +}; +} // namespace cru diff --git a/include/cru/common/io/Stream.hpp b/include/cru/common/io/Stream.hpp index e13e5388..5fa307ed 100644 --- a/include/cru/common/io/Stream.hpp +++ b/include/cru/common/io/Stream.hpp @@ -32,5 +32,7 @@ class CRU_BASE_API Stream : public Object { virtual Index Write(const std::byte* buffer, Index size); virtual void Flush() = 0; + + virtual void Close(); }; } // namespace cru::io diff --git a/include/cru/common/io/UnixFileStream.hpp b/include/cru/common/io/UnixFileStream.hpp new file mode 100644 index 00000000..c8c3fe52 --- /dev/null +++ b/include/cru/common/io/UnixFileStream.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "../String.hpp" +#include "OpenFileFlag.hpp" +#include "Stream.hpp" + +namespace cru::io { +class UnixFileStream : public Stream { + public: + UnixFileStream(String path, OpenFileFlag flags); + + CRU_DELETE_COPY(UnixFileStream) + CRU_DELETE_MOVE(UnixFileStream) + + ~UnixFileStream() override; + + public: + bool CanSeek() override; + Index Tell() override; + void Seek(Index offset, SeekOrigin origin = SeekOrigin::Current) override; + + bool CanRead() override; + Index Read(std::byte* buffer, Index offset, Index size) override; + + bool CanWrite() override; + Index Write(const std::byte* buffer, Index offset, Index size) override; + + void Flush() override; + + void Close() override; + + private: + void CheckClosed(); + + private: + String path_; + OpenFileFlag flags; + int file_descriptor_; + bool closed_ = false; +}; +} // namespace cru::io diff --git a/include/cru/platform/UnixFileStream.hpp b/include/cru/platform/UnixFileStream.hpp deleted file mode 100644 index 612a08f0..00000000 --- a/include/cru/platform/UnixFileStream.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "cru/common/String.hpp" -#include "cru/common/io/OpenFileFlag.hpp" -#include "cru/common/io/Stream.hpp" - -namespace cru::platform { -class UnixFileStream : public io::Stream { - public: - UnixFileStream(String path, io::OpenFileFlag flags); - UnixFileStream(int file_descriptor, bool auto_close); - - CRU_DELETE_COPY(UnixFileStream) - CRU_DELETE_MOVE(UnixFileStream) - - ~UnixFileStream() override; - - private: -}; -} // namespace cru::platform diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index b91b380c..19821797 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -26,6 +26,14 @@ target_include_directories(cru_base PUBLIC ${CRU_INCLUDE_DIR}) target_compile_definitions(cru_base PUBLIC $<$<CONFIG:Debug>:CRU_DEBUG>) target_compile_definitions(cru_base PRIVATE CRU_BASE_EXPORT_API) +if (UNIX) + target_sources(cru_base PRIVATE + io/UnixFileStream.cpp + PUBLIC + ${CRU_BASE_INCLUDE_DIR}/io/UnixFileStream.hpp + ) +endif() + if (WIN32) target_compile_definitions(cru_base PUBLIC CRU_PLATFORM_WINDOWS) elseif(APPLE) diff --git a/src/common/ErrnoException.cpp b/src/common/ErrnoException.cpp new file mode 100644 index 00000000..df2349ac --- /dev/null +++ b/src/common/ErrnoException.cpp @@ -0,0 +1,11 @@ +#include "cru/common/ErrnoException.hpp" + +#include <errno.h> + +namespace cru { +ErrnoException::ErrnoException(const String& message) + : ErrnoException(message, errno) {} + +ErrnoException::ErrnoException(const String& message, int errno_code) + : Exception(message), errno_code_(errno_code) {} +} // namespace cru diff --git a/src/common/io/Stream.cpp b/src/common/io/Stream.cpp index 6addfdc0..1a39b653 100644 --- a/src/common/io/Stream.cpp +++ b/src/common/io/Stream.cpp @@ -18,4 +18,6 @@ Index Stream::Read(std::byte* buffer, Index size) { Index Stream::Write(const std::byte* buffer, Index size) { return Write(buffer, 0, size); } + +void Stream::Close() {} } // namespace cru::io diff --git a/src/common/io/UnixFileStream.cpp b/src/common/io/UnixFileStream.cpp new file mode 100644 index 00000000..23c11dad --- /dev/null +++ b/src/common/io/UnixFileStream.cpp @@ -0,0 +1,125 @@ +#include "cru/common/io/UnixFileStream.hpp" +#include "cru/common/ErrnoException.hpp" +#include "cru/common/io/OpenFileFlag.hpp" + +#include <fcntl.h> +#include <unistd.h> + +namespace cru::io { + +namespace { +int MapOpenFileFlag(OpenFileFlag flag) { + int result = 0; + if (flag & OpenFileFlags::Read) { + if (flag & OpenFileFlags::Write) { + result |= O_RDWR; + } else { + result |= O_RDONLY; + } + } else { + if (flag & OpenFileFlags::Write) { + result |= O_WRONLY; + } else { + throw Exception(u"Invalid open file flag."); + } + } + + if (flag | OpenFileFlags::Append) { + result |= O_APPEND; + } + + if (flag | OpenFileFlags::Create) { + result |= O_CREAT; + } + + if (flag | OpenFileFlags::ThrowOnExist) { + result |= O_EXCL; + } + + return result; +} + +int MapSeekOrigin(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"Invalid seek origin."); + } +} +} // namespace + +UnixFileStream::UnixFileStream(String path, OpenFileFlag flags) { + file_descriptor_ = ::open(path.ToUtf8().c_str(), MapOpenFileFlag(flags)); + if (file_descriptor_ == -1) { + throw ErrnoException(u"Failed to open file."); + } +} + +bool UnixFileStream::CanSeek() { + CheckClosed(); + return true; +} + +Index UnixFileStream::Tell() { + CheckClosed(); + auto result = ::lseek(file_descriptor_, 0, SEEK_CUR); + if (result == -1) { + throw ErrnoException(u"Failed to get file position."); + } + return result; +} + +void UnixFileStream::Seek(Index offset, SeekOrigin origin) { + CheckClosed(); + int result = ::lseek(file_descriptor_, offset, MapSeekOrigin(origin)); + if (result == -1) { + throw ErrnoException(u"Failed to seek file."); + } +} + +bool UnixFileStream::CanRead() { + CheckClosed(); + return flags & OpenFileFlags::Read; +} + +Index UnixFileStream::Read(std::byte *buffer, Index offset, Index size) { + CheckClosed(); + auto result = ::read(file_descriptor_, buffer + offset, size); + if (result == -1) { + throw ErrnoException(u"Failed to read file."); + } + return result; +} + +bool UnixFileStream::CanWrite() { + CheckClosed(); + return flags & OpenFileFlags::Write; +} + +Index UnixFileStream::Write(const std::byte *buffer, Index offset, Index size) { + CheckClosed(); + auto result = ::write(file_descriptor_, buffer + offset, size); + if (result == -1) { + throw ErrnoException(u"Failed to write file."); + } + return result; +} + +void UnixFileStream::Close() { + if (closed_) return; + if (::close(file_descriptor_) == -1) { + throw ErrnoException(u"Failed to close file."); + } +} + +void UnixFileStream::CheckClosed() { + if (closed_) { + throw Exception(u"File is closed."); + } +} +} // namespace cru::io diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt index 2d12ce86..e1ce69a3 100644 --- a/src/platform/CMakeLists.txt +++ b/src/platform/CMakeLists.txt @@ -15,15 +15,6 @@ target_sources(cru_platform_base PUBLIC target_link_libraries(cru_platform_base PUBLIC cru_base) target_compile_definitions(cru_platform_base PRIVATE CRU_PLATFORM_EXPORT_API) -if (UNIX) -target_sources(cru_platform_base PRIVATE - UnixFileStream.cpp -PUBLIC - ${CRU_PLATFORM_BASE_INCLUDE_DIR}/UnixFileStream.hpp -) -endif() - -add_subdirectory(filesystem) add_subdirectory(graphics) add_subdirectory(gui) diff --git a/src/platform/UnixFileStream.cpp b/src/platform/UnixFileStream.cpp deleted file mode 100644 index d4745980..00000000 --- a/src/platform/UnixFileStream.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "cru/platform/UnixFileStream.hpp" - - diff --git a/src/platform/filesystem/CMakeLists.txt b/src/platform/filesystem/CMakeLists.txt deleted file mode 100644 index e69de29b..00000000 --- a/src/platform/filesystem/CMakeLists.txt +++ /dev/null |