master
cpp 117 lines 2.98 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 Streams.cpp
8
9 Abstract:
10
11 This file contains the implementation of WinRT wrappers for streams.
12
13 --*/
14
15 #include "precomp.h"
16 #include "Streams.h"
17
18 using namespace winrt::Windows::Foundation;
19 using namespace winrt::Windows::Storage::Streams;
20
21 namespace winrt::Microsoft::WSL::Containers::implementation {
22
23 IOHandleInputStream::IOHandleInputStream(wil::unique_handle&& handle) : m_handle(std::move(handle))
24 {
25 }
26
27 IAsyncOperationWithProgress<IBuffer, uint32_t> IOHandleInputStream::ReadAsync(IBuffer buffer, uint32_t count, InputStreamOptions options)
28 {
29 if (!m_handle)
30 {
31 throw winrt::hresult_illegal_method_call(L"Stream is closed");
32 }
33
34 if (options != InputStreamOptions::None)
35 {
36 throw winrt::hresult_error(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), L"Only InputStreamOptions::None is supported");
37 }
38
39 if (buffer == nullptr)
40 {
41 throw winrt::hresult_error(E_POINTER, L"Buffer cannot be null");
42 }
43
44 if (count > buffer.Capacity())
45 {
46 throw winrt::hresult_error(E_BOUNDS, L"Count cannot be greater than the buffer capacity");
47 }
48
49 // Move to a background thread, ensuring that this object stays alive until the async operation completes.
50 auto self = get_strong();
51 co_await winrt::resume_background();
52
53 DWORD bytesRead = 0;
54 if (!ReadFile(self->m_handle.get(), buffer.data(), count, &bytesRead, nullptr))
55 {
56 const auto error = GetLastError();
57 if (error == ERROR_BROKEN_PIPE)
58 {
59 bytesRead = 0;
60 }
61 else
62 {
63 THROW_WIN32(error);
64 }
65 }
66
67 buffer.Length(bytesRead);
68 co_return buffer;
69 }
70
71 void IOHandleInputStream::Close()
72 {
73 m_handle.reset();
74 }
75
76 IOHandleOutputStream::IOHandleOutputStream(wil::unique_handle&& handle) : m_handle(std::move(handle))
77 {
78 }
79
80 IAsyncOperationWithProgress<uint32_t, uint32_t> IOHandleOutputStream::WriteAsync(IBuffer const& buffer)
81 {
82 if (!m_handle)
83 {
84 throw winrt::hresult_illegal_method_call(L"Stream is closed");
85 }
86
87 // Move to a background thread, ensuring that this object stays alive until the async operation completes.
88 auto self = get_strong();
89 co_await winrt::resume_background();
90
91 DWORD bytesWritten = 0;
92 THROW_IF_WIN32_BOOL_FALSE(WriteFile(self->m_handle.get(), buffer.data(), buffer.Length(), &bytesWritten, nullptr));
93
94 co_return bytesWritten;
95 }
96
97 winrt::Windows::Foundation::IAsyncOperation<bool> IOHandleOutputStream::FlushAsync()
98 {
99 if (!m_handle)
100 {
101 throw winrt::hresult_illegal_method_call(L"Stream is closed");
102 }
103
104 // Move to a background thread, ensuring that this object stays alive until the async operation completes.
105 auto self = get_strong();
106 co_await winrt::resume_background();
107
108 THROW_IF_WIN32_BOOL_FALSE(FlushFileBuffers(self->m_handle.get()));
109 co_return true;
110 }
111
112 void IOHandleOutputStream::Close()
113 {
114 m_handle.reset();
115 }
116
117 } // namespace winrt::Microsoft::WSL::Containers::implementation