1 | // |
2 | // detail/win_iocp_serial_port_service.hpp |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4 | // |
5 | // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
6 | // Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com) |
7 | // |
8 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
9 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
10 | // |
11 | |
12 | #ifndef BOOST_ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP |
13 | #define BOOST_ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP |
14 | |
15 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) |
16 | # pragma once |
17 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) |
18 | |
19 | #include <boost/asio/detail/config.hpp> |
20 | |
21 | #if defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT) |
22 | |
23 | #include <string> |
24 | #include <boost/asio/error.hpp> |
25 | #include <boost/asio/io_service.hpp> |
26 | #include <boost/asio/detail/win_iocp_handle_service.hpp> |
27 | |
28 | #include <boost/asio/detail/push_options.hpp> |
29 | |
30 | namespace boost { |
31 | namespace asio { |
32 | namespace detail { |
33 | |
34 | // Extend win_iocp_handle_service to provide serial port support. |
35 | class win_iocp_serial_port_service |
36 | { |
37 | public: |
38 | // The native type of a serial port. |
39 | typedef win_iocp_handle_service::native_handle_type native_handle_type; |
40 | |
41 | // The implementation type of the serial port. |
42 | typedef win_iocp_handle_service::implementation_type implementation_type; |
43 | |
44 | // Constructor. |
45 | BOOST_ASIO_DECL win_iocp_serial_port_service( |
46 | boost::asio::io_service& io_service); |
47 | |
48 | // Destroy all user-defined handler objects owned by the service. |
49 | BOOST_ASIO_DECL void shutdown_service(); |
50 | |
51 | // Construct a new serial port implementation. |
52 | void construct(implementation_type& impl) |
53 | { |
54 | handle_service_.construct(impl); |
55 | } |
56 | |
57 | // Move-construct a new serial port implementation. |
58 | void move_construct(implementation_type& impl, |
59 | implementation_type& other_impl) |
60 | { |
61 | handle_service_.move_construct(impl, other_impl); |
62 | } |
63 | |
64 | // Move-assign from another serial port implementation. |
65 | void move_assign(implementation_type& impl, |
66 | win_iocp_serial_port_service& other_service, |
67 | implementation_type& other_impl) |
68 | { |
69 | handle_service_.move_assign(impl, |
70 | other_service.handle_service_, other_impl); |
71 | } |
72 | |
73 | // Destroy a serial port implementation. |
74 | void destroy(implementation_type& impl) |
75 | { |
76 | handle_service_.destroy(impl); |
77 | } |
78 | |
79 | // Open the serial port using the specified device name. |
80 | BOOST_ASIO_DECL boost::system::error_code open(implementation_type& impl, |
81 | const std::string& device, boost::system::error_code& ec); |
82 | |
83 | // Assign a native handle to a serial port implementation. |
84 | boost::system::error_code assign(implementation_type& impl, |
85 | const native_handle_type& handle, boost::system::error_code& ec) |
86 | { |
87 | return handle_service_.assign(impl, handle, ec); |
88 | } |
89 | |
90 | // Determine whether the serial port is open. |
91 | bool is_open(const implementation_type& impl) const |
92 | { |
93 | return handle_service_.is_open(impl); |
94 | } |
95 | |
96 | // Destroy a serial port implementation. |
97 | boost::system::error_code close(implementation_type& impl, |
98 | boost::system::error_code& ec) |
99 | { |
100 | return handle_service_.close(impl, ec); |
101 | } |
102 | |
103 | // Get the native serial port representation. |
104 | native_handle_type native_handle(implementation_type& impl) |
105 | { |
106 | return handle_service_.native_handle(impl); |
107 | } |
108 | |
109 | // Cancel all operations associated with the handle. |
110 | boost::system::error_code cancel(implementation_type& impl, |
111 | boost::system::error_code& ec) |
112 | { |
113 | return handle_service_.cancel(impl, ec); |
114 | } |
115 | |
116 | // Set an option on the serial port. |
117 | template <typename SettableSerialPortOption> |
118 | boost::system::error_code set_option(implementation_type& impl, |
119 | const SettableSerialPortOption& option, boost::system::error_code& ec) |
120 | { |
121 | return do_set_option(impl, |
122 | &win_iocp_serial_port_service::store_option<SettableSerialPortOption>, |
123 | &option, ec); |
124 | } |
125 | |
126 | // Get an option from the serial port. |
127 | template <typename GettableSerialPortOption> |
128 | boost::system::error_code get_option(const implementation_type& impl, |
129 | GettableSerialPortOption& option, boost::system::error_code& ec) const |
130 | { |
131 | return do_get_option(impl, |
132 | &win_iocp_serial_port_service::load_option<GettableSerialPortOption>, |
133 | &option, ec); |
134 | } |
135 | |
136 | // Send a break sequence to the serial port. |
137 | boost::system::error_code send_break(implementation_type&, |
138 | boost::system::error_code& ec) |
139 | { |
140 | ec = boost::asio::error::operation_not_supported; |
141 | return ec; |
142 | } |
143 | |
144 | // Write the given data. Returns the number of bytes sent. |
145 | template <typename ConstBufferSequence> |
146 | size_t write_some(implementation_type& impl, |
147 | const ConstBufferSequence& buffers, boost::system::error_code& ec) |
148 | { |
149 | return handle_service_.write_some(impl, buffers, ec); |
150 | } |
151 | |
152 | // Start an asynchronous write. The data being written must be valid for the |
153 | // lifetime of the asynchronous operation. |
154 | template <typename ConstBufferSequence, typename Handler> |
155 | void async_write_some(implementation_type& impl, |
156 | const ConstBufferSequence& buffers, Handler& handler) |
157 | { |
158 | handle_service_.async_write_some(impl, buffers, handler); |
159 | } |
160 | |
161 | // Read some data. Returns the number of bytes received. |
162 | template <typename MutableBufferSequence> |
163 | size_t read_some(implementation_type& impl, |
164 | const MutableBufferSequence& buffers, boost::system::error_code& ec) |
165 | { |
166 | return handle_service_.read_some(impl, buffers, ec); |
167 | } |
168 | |
169 | // Start an asynchronous read. The buffer for the data being received must be |
170 | // valid for the lifetime of the asynchronous operation. |
171 | template <typename MutableBufferSequence, typename Handler> |
172 | void async_read_some(implementation_type& impl, |
173 | const MutableBufferSequence& buffers, Handler& handler) |
174 | { |
175 | handle_service_.async_read_some(impl, buffers, handler); |
176 | } |
177 | |
178 | private: |
179 | // Function pointer type for storing a serial port option. |
180 | typedef boost::system::error_code (*store_function_type)( |
181 | const void*, ::DCB&, boost::system::error_code&); |
182 | |
183 | // Helper function template to store a serial port option. |
184 | template <typename SettableSerialPortOption> |
185 | static boost::system::error_code store_option(const void* option, |
186 | ::DCB& storage, boost::system::error_code& ec) |
187 | { |
188 | return static_cast<const SettableSerialPortOption*>(option)->store( |
189 | storage, ec); |
190 | } |
191 | |
192 | // Helper function to set a serial port option. |
193 | BOOST_ASIO_DECL boost::system::error_code do_set_option( |
194 | implementation_type& impl, store_function_type store, |
195 | const void* option, boost::system::error_code& ec); |
196 | |
197 | // Function pointer type for loading a serial port option. |
198 | typedef boost::system::error_code (*load_function_type)( |
199 | void*, const ::DCB&, boost::system::error_code&); |
200 | |
201 | // Helper function template to load a serial port option. |
202 | template <typename GettableSerialPortOption> |
203 | static boost::system::error_code load_option(void* option, |
204 | const ::DCB& storage, boost::system::error_code& ec) |
205 | { |
206 | return static_cast<GettableSerialPortOption*>(option)->load(storage, ec); |
207 | } |
208 | |
209 | // Helper function to get a serial port option. |
210 | BOOST_ASIO_DECL boost::system::error_code do_get_option( |
211 | const implementation_type& impl, load_function_type load, |
212 | void* option, boost::system::error_code& ec) const; |
213 | |
214 | // The implementation used for initiating asynchronous operations. |
215 | win_iocp_handle_service handle_service_; |
216 | }; |
217 | |
218 | } // namespace detail |
219 | } // namespace asio |
220 | } // namespace boost |
221 | |
222 | #include <boost/asio/detail/pop_options.hpp> |
223 | |
224 | #if defined(BOOST_ASIO_HEADER_ONLY) |
225 | # include <boost/asio/detail/impl/win_iocp_serial_port_service.ipp> |
226 | #endif // defined(BOOST_ASIO_HEADER_ONLY) |
227 | |
228 | #endif // defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT) |
229 | |
230 | #endif // BOOST_ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP |
231 | |