aboutsummaryrefslogtreecommitdiff
path: root/src/common/platform/win/StreamConvert.cpp
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-02-03 17:55:00 +0800
committercrupest <crupest@outlook.com>2022-02-03 17:55:00 +0800
commit5aca7b099c46a87a859f40110efce708200a4bc8 (patch)
tree76a0daef247ab2b2269eebdbbda10134f213d1ca /src/common/platform/win/StreamConvert.cpp
parentd15172cfe1ac8558567c1b1c10c2e671b0d1f033 (diff)
downloadcru-5aca7b099c46a87a859f40110efce708200a4bc8.tar.gz
cru-5aca7b099c46a87a859f40110efce708200a4bc8.tar.bz2
cru-5aca7b099c46a87a859f40110efce708200a4bc8.zip
...
Diffstat (limited to 'src/common/platform/win/StreamConvert.cpp')
-rw-r--r--src/common/platform/win/StreamConvert.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/common/platform/win/StreamConvert.cpp b/src/common/platform/win/StreamConvert.cpp
new file mode 100644
index 00000000..1d077573
--- /dev/null
+++ b/src/common/platform/win/StreamConvert.cpp
@@ -0,0 +1,53 @@
+#include "cru/common/platform/win/StreamConvert.hpp"
+#include "BrigdeComStream.hpp"
+#include "cru/common/Exception.hpp"
+#include "cru/common/io/MemoryStream.hpp"
+#include "cru/common/io/OpenFileFlag.hpp"
+#include "cru/common/platform/win/ComAutoInit.hpp"
+#include "cru/common/platform/win/Exception.hpp"
+#include "cru/common/platform/win/Win32FileStream.hpp"
+
+#include <shlwapi.h>
+#include <winnt.h>
+
+namespace cru::platform::win {
+IStream* ConvertStreamToComStream(io::Stream* stream) {
+ static ComAutoInit com_auto_init;
+
+ if (auto memory_stream = dynamic_cast<io::MemoryStream*>(stream)) {
+ return SHCreateMemStream(
+ reinterpret_cast<const BYTE*>(memory_stream->GetBuffer()),
+ memory_stream->GetSize());
+ } else if (auto file_stream = dynamic_cast<Win32FileStream*>(stream)) {
+ auto path = file_stream->GetPath();
+ auto flags = file_stream->GetOpenFileFlags();
+ DWORD grfMode = STGM_SHARE_DENY_NONE | STGM_FAILIFTHERE;
+ if (flags & io::OpenFileFlags::Read) {
+ if (flags & io::OpenFileFlags::Write) {
+ grfMode |= STGM_READWRITE;
+ } else {
+ grfMode |= STGM_READ;
+ }
+ } else {
+ if (flags & io::OpenFileFlags::Write) {
+ grfMode |= STGM_WRITE;
+ } else {
+ throw Exception(u"Stream must be readable or writable.");
+ }
+ }
+
+ IStream* result;
+
+ ThrowIfFailed(SHCreateStreamOnFileEx(
+ path.WinCStr(), grfMode, FILE_ATTRIBUTE_NORMAL, FALSE, NULL, &result));
+
+ LARGE_INTEGER position;
+ position.QuadPart = stream->Tell();
+ result->Seek(position, STREAM_SEEK_SET, NULL);
+
+ return result;
+ } else {
+ return new BridgeComStream(stream);
+ }
+}
+} // namespace cru::platform::win