diff options
-rw-r--r-- | include/cru/common/platform/win/BrigdeComStream.hpp | 48 | ||||
-rw-r--r-- | src/common/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/common/platform/win/BridgeComStream.cpp | 98 |
3 files changed, 147 insertions, 0 deletions
diff --git a/include/cru/common/platform/win/BrigdeComStream.hpp b/include/cru/common/platform/win/BrigdeComStream.hpp new file mode 100644 index 00000000..38b75dae --- /dev/null +++ b/include/cru/common/platform/win/BrigdeComStream.hpp @@ -0,0 +1,48 @@ +#pragma once +#include "../../PreConfig.hpp" +#ifdef CRU_PLATFORM_WINDOWS + +#include "WinPreConfig.hpp" + +#include "../../io/Stream.hpp" + +#include <objidlbase.h> + +namespace cru::platform::win { +class BridgeComStream : public IStream { + public: + explicit BridgeComStream(io::Stream* stream); + + CRU_DELETE_COPY(BridgeComStream) + CRU_DELETE_MOVE(BridgeComStream) + + ~BridgeComStream(); + + public: + ULONG AddRef() override; + ULONG Release() override; + HRESULT QueryInterface(REFIID riid, void** ppvObject) override; + + HRESULT Read(void* pv, ULONG cb, ULONG* pcbRead) override; + HRESULT Write(const void* pv, ULONG cb, ULONG* pcbWritten) override; + HRESULT Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, + ULARGE_INTEGER* plibNewPosition) override; + HRESULT SetSize(ULARGE_INTEGER libNewSize) override; + HRESULT CopyTo(IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, + ULARGE_INTEGER* pcbWritten) override; + HRESULT Commit(DWORD grfCommitFlags) override; + HRESULT Revert() override; + HRESULT LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, + DWORD dwLockType) override; + HRESULT UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, + DWORD dwLockType) override; + HRESULT Stat(STATSTG* pstatstg, DWORD grfStatFlag) override; + HRESULT Clone(IStream** ppstm) override; + + private: + io::Stream* stream_; + ULONG ref_count_; +}; +} // namespace cru::platform::win + +#endif diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 200ea7fa..3294b2f0 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -34,6 +34,7 @@ endif() if (WIN32) target_sources(cru_base PRIVATE + platform/win/BridgeComStream.cpp platform/win/Win32FileStream.cpp platform/win/Exception.cpp ) diff --git a/src/common/platform/win/BridgeComStream.cpp b/src/common/platform/win/BridgeComStream.cpp new file mode 100644 index 00000000..eaa53b92 --- /dev/null +++ b/src/common/platform/win/BridgeComStream.cpp @@ -0,0 +1,98 @@ +#include "cru/common/io/Stream.hpp" +#include "cru/common/platform/win/BrigdeComStream.hpp" + +namespace cru::platform::win { +BridgeComStream::BridgeComStream(io::Stream *stream) + : stream_(stream), ref_count_(1) {} + +BridgeComStream::~BridgeComStream() {} + +ULONG BridgeComStream::AddRef() { return ++ref_count_; } + +ULONG BridgeComStream::Release() { + --ref_count_; + + if (ref_count_ == 0) { + delete this; + return 0; + } + + return ref_count_; +} + +HRESULT BridgeComStream::QueryInterface(const IID &riid, void **ppvObject) { + if (riid == IID_IStream) { + *ppvObject = static_cast<IStream *>(this); + AddRef(); + return S_OK; + } else if (riid == IID_ISequentialStream) { + *ppvObject = static_cast<ISequentialStream *>(this); + AddRef(); + return S_OK; + } else if (riid == IID_IUnknown) { + *ppvObject = static_cast<IUnknown *>(this); + AddRef(); + return S_OK; + } else { + return E_NOINTERFACE; + } +} + +HRESULT BridgeComStream::Read(void *pv, ULONG cb, ULONG *pcbRead) { + *pcbRead = stream_->Read(static_cast<std::byte *>(pv), cb); + return S_OK; +} + +HRESULT BridgeComStream::Write(const void *pv, ULONG cb, ULONG *pcbWritten) { + *pcbWritten = stream_->Write(static_cast<const std::byte *>(pv), cb); + return S_OK; +} + +HRESULT BridgeComStream::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, + ULARGE_INTEGER *plibNewPosition) { + io::Stream::SeekOrigin so = + dwOrigin == STREAM_SEEK_SET + ? io::Stream::SeekOrigin::Begin + : (STREAM_SEEK_CUR ? io::Stream::SeekOrigin::Current + : io::Stream::SeekOrigin::End); + + stream_->Seek(dlibMove.QuadPart, so); + plibNewPosition->QuadPart = stream_->Tell(); + + return S_OK; +} + +HRESULT BridgeComStream::SetSize(ULARGE_INTEGER libNewSize) { + return E_NOTIMPL; +} + +HRESULT BridgeComStream::CopyTo(IStream *pstm, ULARGE_INTEGER cb, + ULARGE_INTEGER *pcbRead, + ULARGE_INTEGER *pcbWritten) { + return E_NOTIMPL; +} + +HRESULT BridgeComStream::Commit(DWORD grfCommitFlags) { return S_OK; } + +HRESULT BridgeComStream::Revert() { return S_OK; } + +HRESULT BridgeComStream::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, + DWORD dwLockType) { + return S_OK; +} + +HRESULT BridgeComStream::UnlockRegion(ULARGE_INTEGER libOffset, + ULARGE_INTEGER cb, DWORD dwLockType) { + return S_OK; +} + +HRESULT BridgeComStream::Stat(STATSTG *pstatstg, DWORD grfStatFlag) { + return E_NOTIMPL; +} + +HRESULT BridgeComStream::Clone(IStream **ppstm) { + *ppstm = new BridgeComStream(stream_); + return S_OK; +} + +} // namespace cru::platform::win |