1//
2// detail/impl/buffer_sequence_adapter.ipp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef BOOST_ASIO_DETAIL_IMPL_BUFFER_SEQUENCE_ADAPTER_IPP
12#define BOOST_ASIO_DETAIL_IMPL_BUFFER_SEQUENCE_ADAPTER_IPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/config.hpp>
19
20#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
21
22#include <robuffer.h>
23#include <windows.storage.streams.h>
24#include <wrl/implements.h>
25#include <boost/asio/detail/buffer_sequence_adapter.hpp>
26
27#include <boost/asio/detail/push_options.hpp>
28
29namespace boost {
30namespace asio {
31namespace detail {
32
33class winrt_buffer_impl :
34  public Microsoft::WRL::RuntimeClass<
35    Microsoft::WRL::RuntimeClassFlags<
36      Microsoft::WRL::RuntimeClassType::WinRtClassicComMix>,
37    ABI::Windows::Storage::Streams::IBuffer,
38    Windows::Storage::Streams::IBufferByteAccess>
39{
40public:
41  explicit winrt_buffer_impl(const boost::asio::const_buffer& b)
42  {
43    bytes_ = const_cast<byte*>(static_cast<const byte*>(b.data()));
44    length_ = b.size();
45    capacity_ = b.size();
46  }
47
48  explicit winrt_buffer_impl(const boost::asio::mutable_buffer& b)
49  {
50    bytes_ = static_cast<byte*>(b.data());
51    length_ = 0;
52    capacity_ = b.size();
53  }
54
55  ~winrt_buffer_impl()
56  {
57  }
58
59  STDMETHODIMP Buffer(byte** value)
60  {
61    *value = bytes_;
62    return S_OK;
63  }
64
65  STDMETHODIMP get_Capacity(UINT32* value)
66  {
67    *value = capacity_;
68    return S_OK;
69  }
70
71  STDMETHODIMP get_Length(UINT32 *value)
72  {
73    *value = length_;
74    return S_OK;
75  }
76
77  STDMETHODIMP put_Length(UINT32 value)
78  {
79    if (value > capacity_)
80      return E_INVALIDARG;
81    length_ = value;
82    return S_OK;
83  }
84
85private:
86  byte* bytes_;
87  UINT32 length_;
88  UINT32 capacity_;
89};
90
91void buffer_sequence_adapter_base::init_native_buffer(
92    buffer_sequence_adapter_base::native_buffer_type& buf,
93    const boost::asio::mutable_buffer& buffer)
94{
95  std::memset(&buf, 0, sizeof(native_buffer_type));
96  Microsoft::WRL::ComPtr<IInspectable> insp
97    = Microsoft::WRL::Make<winrt_buffer_impl>(buffer);
98  buf = reinterpret_cast<Windows::Storage::Streams::IBuffer^>(insp.Get());
99}
100
101void buffer_sequence_adapter_base::init_native_buffer(
102    buffer_sequence_adapter_base::native_buffer_type& buf,
103    const boost::asio::const_buffer& buffer)
104{
105  std::memset(&buf, 0, sizeof(native_buffer_type));
106  Microsoft::WRL::ComPtr<IInspectable> insp
107    = Microsoft::WRL::Make<winrt_buffer_impl>(buffer);
108  Platform::Object^ buf_obj = reinterpret_cast<Platform::Object^>(insp.Get());
109  buf = reinterpret_cast<Windows::Storage::Streams::IBuffer^>(insp.Get());
110}
111
112} // namespace detail
113} // namespace asio
114} // namespace boost
115
116#include <boost/asio/detail/pop_options.hpp>
117
118#endif // defined(BOOST_ASIO_WINDOWS_RUNTIME)
119
120#endif // BOOST_ASIO_DETAIL_IMPL_BUFFER_SEQUENCE_ADAPTER_IPP
121