diff options
Diffstat (limited to 'include/cru/base/platform')
-rw-r--r-- | include/cru/base/platform/Exception.h | 12 | ||||
-rw-r--r-- | include/cru/base/platform/osx/Convert.h | 18 | ||||
-rw-r--r-- | include/cru/base/platform/osx/Exception.h | 15 | ||||
-rw-r--r-- | include/cru/base/platform/unix/PosixSpawnSubProcess.h | 50 | ||||
-rw-r--r-- | include/cru/base/platform/unix/UnixFileStream.h | 39 | ||||
-rw-r--r-- | include/cru/base/platform/unix/UnixPipe.h | 70 | ||||
-rw-r--r-- | include/cru/base/platform/web/WebException.h | 16 | ||||
-rw-r--r-- | include/cru/base/platform/win/ComAutoInit.h | 21 | ||||
-rw-r--r-- | include/cru/base/platform/win/DebugLogTarget.h | 25 | ||||
-rw-r--r-- | include/cru/base/platform/win/Exception.h | 56 | ||||
-rw-r--r-- | include/cru/base/platform/win/StreamConvert.h | 14 | ||||
-rw-r--r-- | include/cru/base/platform/win/Win32FileStream.h | 56 | ||||
-rw-r--r-- | include/cru/base/platform/win/WinPreConfig.h | 13 |
13 files changed, 405 insertions, 0 deletions
diff --git a/include/cru/base/platform/Exception.h b/include/cru/base/platform/Exception.h new file mode 100644 index 00000000..74dd6ad4 --- /dev/null +++ b/include/cru/base/platform/Exception.h @@ -0,0 +1,12 @@ +#pragma once +#include "../Base.h" +#include "../Exception.h" + +namespace cru::platform { +class CRU_BASE_API PlatformException : public Exception { + public: + using Exception::Exception; // inherit constructors + + CRU_DEFAULT_DESTRUCTOR(PlatformException) +}; +} // namespace cru::platform diff --git a/include/cru/base/platform/osx/Convert.h b/include/cru/base/platform/osx/Convert.h new file mode 100644 index 00000000..395cbbae --- /dev/null +++ b/include/cru/base/platform/osx/Convert.h @@ -0,0 +1,18 @@ +#pragma once +#include "../../PreConfig.h" + +#ifndef CRU_PLATFORM_OSX +#error "This file can only be included on osx." +#endif + +#include "../../String.h" + +#include <CoreFoundation/CoreFoundation.h> + +namespace cru::platform::osx { +CFStringRef Convert(const String& string); +String Convert(CFStringRef string); + +CFRange Convert(const Range& range); +Range Convert(const CFRange& range); +} // namespace cru::platform::osx diff --git a/include/cru/base/platform/osx/Exception.h b/include/cru/base/platform/osx/Exception.h new file mode 100644 index 00000000..5ab14ebd --- /dev/null +++ b/include/cru/base/platform/osx/Exception.h @@ -0,0 +1,15 @@ +#pragma once +#include "../../PreConfig.h" + +#ifndef CRU_PLATFORM_OSX +#error "This file can only be included on osx." +#endif + +#include "../Exception.h" + +namespace cru::platform::osx { +class OsxException : public PlatformException { + public: + using PlatformException::PlatformException; +}; +} // namespace cru::platform::osx diff --git a/include/cru/base/platform/unix/PosixSpawnSubProcess.h b/include/cru/base/platform/unix/PosixSpawnSubProcess.h new file mode 100644 index 00000000..ee4e912a --- /dev/null +++ b/include/cru/base/platform/unix/PosixSpawnSubProcess.h @@ -0,0 +1,50 @@ +#pragma once + +#include "../../PreConfig.h" + +#ifndef CRU_PLATFORM_UNIX +#error "This file can only be included on unix." +#endif + +#include "../../Base.h" +#include "../../SubProcess.h" +#include "../../io/AutoReadStream.h" + +#include "UnixFileStream.h" +#include "UnixPipe.h" + +#include <spawn.h> + +namespace cru::platform::unix { +class PosixSpawnSubProcessImpl : public Object, + public virtual IPlatformSubProcessImpl { + CRU_DEFINE_CLASS_LOG_TAG(u"PosixSpawnSubProcess") + + public: + explicit PosixSpawnSubProcessImpl(); + ~PosixSpawnSubProcessImpl(); + + void PlatformCreateProcess(const SubProcessStartInfo& start_info) override; + SubProcessExitResult PlatformWaitForProcess() override; + void PlatformKillProcess() override; + + io::Stream* GetStdinStream() override; + io::Stream* GetStdoutStream() override; + io::Stream* GetStderrStream() override; + + private: + pid_t pid_; + int exit_code_; + + UnixPipe stdin_pipe_; + UnixPipe stdout_pipe_; + UnixPipe stderr_pipe_; + + std::unique_ptr<UnixFileStream> stdin_stream_; + std::unique_ptr<UnixFileStream> stdout_stream_; + std::unique_ptr<UnixFileStream> stderr_stream_; + + std::unique_ptr<io::AutoReadStream> stdout_buffer_stream_; + std::unique_ptr<io::AutoReadStream> stderr_buffer_stream_; +}; +} // namespace cru::platform::unix diff --git a/include/cru/base/platform/unix/UnixFileStream.h b/include/cru/base/platform/unix/UnixFileStream.h new file mode 100644 index 00000000..8021f21a --- /dev/null +++ b/include/cru/base/platform/unix/UnixFileStream.h @@ -0,0 +1,39 @@ +#pragma once + +#include "../../PreConfig.h" + +#ifndef CRU_PLATFORM_UNIX +#error "This file can only be included on unix." +#endif + +#include "../../io/Stream.h" + +namespace cru::platform::unix { +class UnixFileStream : public io::Stream { + private: + static constexpr auto kLogTag = u"cru::platform::unix::UnixFileStream"; + + public: + UnixFileStream(const char* path, int oflag, mode_t mode = 0660); + UnixFileStream(int fd, bool can_seek, bool can_read, bool can_write, + bool auto_close); + ~UnixFileStream() override; + + public: + CRU_STREAM_IMPLEMENT_CLOSE_BY_DO_CLOSE + + int GetFileDescriptor() const { return file_descriptor_; } + + protected: + Index DoSeek(Index offset, SeekOrigin origin = SeekOrigin::Current) override; + Index DoRead(std::byte* buffer, Index offset, Index size) override; + Index DoWrite(const std::byte* buffer, Index offset, Index size) override; + + private: + void DoClose(); + + private: + int file_descriptor_; // -1 for no file descriptor + bool auto_close_; +}; +} // namespace cru::platform::unix diff --git a/include/cru/base/platform/unix/UnixPipe.h b/include/cru/base/platform/unix/UnixPipe.h new file mode 100644 index 00000000..cf35fb11 --- /dev/null +++ b/include/cru/base/platform/unix/UnixPipe.h @@ -0,0 +1,70 @@ +#pragma once + +#include "../../PreConfig.h" + +#ifndef CRU_PLATFORM_UNIX +#error "This file can only be included on unix." +#endif + +#include "../../Base.h" +#include "../../Bitmask.h" + +namespace cru::platform::unix { +namespace details { +struct UnixPipeFlagTag; +} +using UnixPipeFlag = Bitmask<details::UnixPipeFlagTag>; +struct UnixPipeFlags { + constexpr static auto NonBlock = UnixPipeFlag::FromOffset(1); +}; + +/** + * @brief an unix pipe, commonly for communication of parent process and child + * process. + * + * There are two types of pipes sorted by its usage. For stdin, parent process + * SEND data to child process. For stdout and stderr, parent process RECEIVE + * data from child process. Each pipe has two ends, one for read and the other + * for write. But for send and receive, they are reversed. It is a little + * confused to consider which end should be used by parent and which end should + * be used by child. So this class help you make it clear. You specify SEND or + * RECEIVE, and this class give you a parent used end and a child used end. + * + * This class will only close the end used by parent when it is destructed. It + * is the user's duty to close the one used by child. + */ +class UnixPipe : public Object { + private: + constexpr static auto kLogTag = u"cru::platform::unix::UnixPipe"; + + public: + enum class Usage { + Send, + Receive, + }; + + explicit UnixPipe(Usage usage, bool auto_close, UnixPipeFlag flags = {}); + + CRU_DELETE_COPY(UnixPipe) + CRU_DELETE_MOVE(UnixPipe) + + ~UnixPipe(); + + /** + * @brief aka, the one used by parent process. + */ + int GetSelfFileDescriptor(); + + /** + * @brief aka, the one used by child process. + */ + int GetOtherFileDescriptor(); + + private: + Usage usage_; + bool auto_close_; + UnixPipeFlag flags_; + int read_fd_; + int write_fd_; +}; +} // namespace cru::platform::unix diff --git a/include/cru/base/platform/web/WebException.h b/include/cru/base/platform/web/WebException.h new file mode 100644 index 00000000..d98b8943 --- /dev/null +++ b/include/cru/base/platform/web/WebException.h @@ -0,0 +1,16 @@ +#pragma once + +#include "../../PreConfig.h" + +#ifdef CRU_PLATFORM_EMSCRIPTEN + +#include "../Exception.h" + +namespace cru::platform::web { +class WebException : public PlatformException { + public: + using PlatformException::PlatformException; +}; +} // namespace cru::platform::web + +#endif diff --git a/include/cru/base/platform/win/ComAutoInit.h b/include/cru/base/platform/win/ComAutoInit.h new file mode 100644 index 00000000..569085c8 --- /dev/null +++ b/include/cru/base/platform/win/ComAutoInit.h @@ -0,0 +1,21 @@ +#pragma once + +#include "../../PreConfig.h" +#ifdef CRU_PLATFORM_WINDOWS + +#include "WinPreConfig.h" +#include "cru/base/Base.h" + +namespace cru::platform::win { +class CRU_BASE_API ComAutoInit { + public: + ComAutoInit(); + + CRU_DELETE_COPY(ComAutoInit) + CRU_DELETE_MOVE(ComAutoInit) + + ~ComAutoInit(); +}; +} // namespace cru::platform::win + +#endif diff --git a/include/cru/base/platform/win/DebugLogTarget.h b/include/cru/base/platform/win/DebugLogTarget.h new file mode 100644 index 00000000..8257f637 --- /dev/null +++ b/include/cru/base/platform/win/DebugLogTarget.h @@ -0,0 +1,25 @@ +#pragma once + +#include "../../PreConfig.h" +#ifdef CRU_PLATFORM_WINDOWS + +#include "WinPreConfig.h" + +#include "../../log/Logger.h" + +namespace cru::platform::win { + +class CRU_BASE_API WinDebugLogTarget : public ::cru::log::ILogTarget { + public: + WinDebugLogTarget() = default; + + CRU_DELETE_COPY(WinDebugLogTarget) + CRU_DELETE_MOVE(WinDebugLogTarget) + + ~WinDebugLogTarget() = default; + + void Write(::cru::log::LogLevel level, StringView s) override; +}; +} // namespace cru::platform::win + +#endif diff --git a/include/cru/base/platform/win/Exception.h b/include/cru/base/platform/win/Exception.h new file mode 100644 index 00000000..3e63b191 --- /dev/null +++ b/include/cru/base/platform/win/Exception.h @@ -0,0 +1,56 @@ +#pragma once +#include "../../PreConfig.h" +#ifdef CRU_PLATFORM_WINDOWS + +#include "WinPreConfig.h" + +#include "../Exception.h" + +#include <stdexcept> +#include <string_view> + +namespace cru::platform::win { +class CRU_BASE_API HResultError : public platform::PlatformException { + public: + explicit HResultError(HRESULT h_result); + explicit HResultError(HRESULT h_result, std::string_view message); + + CRU_DEFAULT_COPY(HResultError) + CRU_DEFAULT_MOVE(HResultError) + + ~HResultError() override = default; + + HRESULT GetHResult() const { return h_result_; } + + private: + HRESULT h_result_; +}; + +inline void ThrowIfFailed(const HRESULT h_result) { + if (FAILED(h_result)) throw HResultError(h_result); +} + +inline void ThrowIfFailed(const HRESULT h_result, std::string_view message) { + if (FAILED(h_result)) throw HResultError(h_result, message); +} + +class CRU_BASE_API Win32Error : public platform::PlatformException { + public: + // ::GetLastError is automatically called to get the error code. + // The same as Win32Error(::GetLastError(), message) + explicit Win32Error(String message); + Win32Error(DWORD error_code, String message); + + CRU_DEFAULT_COPY(Win32Error) + CRU_DEFAULT_MOVE(Win32Error) + + ~Win32Error() override = default; + + DWORD GetErrorCode() const { return error_code_; } + + private: + DWORD error_code_; +}; +} // namespace cru::platform::win + +#endif diff --git a/include/cru/base/platform/win/StreamConvert.h b/include/cru/base/platform/win/StreamConvert.h new file mode 100644 index 00000000..3499604a --- /dev/null +++ b/include/cru/base/platform/win/StreamConvert.h @@ -0,0 +1,14 @@ +#pragma once +#include "../../PreConfig.h" + +#ifdef CRU_PLATFORM_WINDOWS + +#include "../../io/Stream.h" + +#include <objidlbase.h> + +namespace cru::platform::win { +CRU_BASE_API IStream* ConvertStreamToComStream(io::Stream* stream); +} + +#endif diff --git a/include/cru/base/platform/win/Win32FileStream.h b/include/cru/base/platform/win/Win32FileStream.h new file mode 100644 index 00000000..06656466 --- /dev/null +++ b/include/cru/base/platform/win/Win32FileStream.h @@ -0,0 +1,56 @@ +#pragma once + +#include "../../PreConfig.h" + +#ifdef CRU_PLATFORM_WINDOWS + +#include "../../String.h" +#include "../../io/OpenFileFlag.h" +#include "../../io/Stream.h" + +namespace cru::platform::win { +namespace details { +class Win32FileStreamPrivate; +} + +class CRU_BASE_API Win32FileStream : public io::Stream { + public: + Win32FileStream(String path, io::OpenFileFlag flags); + + CRU_DELETE_COPY(Win32FileStream) + CRU_DELETE_MOVE(Win32FileStream) + + ~Win32FileStream() override; + + public: + bool CanSeek() override; + Index Seek(Index offset, SeekOrigin origin = SeekOrigin::Current) override; + + bool CanRead() override; + Index Read(std::byte* buffer, Index offset, Index size) override; + using Stream::Read; + + bool CanWrite() override; + Index Write(const std::byte* buffer, Index offset, Index size) override; + using Stream::Write; + + void Close() override; + + String GetPath() const { return path_; } + io::OpenFileFlag GetOpenFileFlags() const { return flags_; } + + details::Win32FileStreamPrivate* GetPrivate_() { return p_; } + + private: + void CheckClosed(); + + private: + String path_; + io::OpenFileFlag flags_; + bool closed_ = false; + + details::Win32FileStreamPrivate* p_; +}; +} // namespace cru::platform::win + +#endif diff --git a/include/cru/base/platform/win/WinPreConfig.h b/include/cru/base/platform/win/WinPreConfig.h new file mode 100644 index 00000000..c2284df3 --- /dev/null +++ b/include/cru/base/platform/win/WinPreConfig.h @@ -0,0 +1,13 @@ +#pragma once +#include "../../PreConfig.h" +#ifdef CRU_PLATFORM_WINDOWS + +#define NOMINMAX +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> +#undef CreateWindow +#undef DrawText +#undef CreateFont +#undef CreateEvent + +#endif |