1 | // |
2 | // serial_port_service.hpp |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~ |
4 | // |
5 | // Copyright (c) 2003-2015 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_SERIAL_PORT_SERVICE_HPP |
12 | #define BOOST_ASIO_SERIAL_PORT_SERVICE_HPP |
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_HAS_SERIAL_PORT) \ |
21 | || defined(GENERATING_DOCUMENTATION) |
22 | |
23 | #include <cstddef> |
24 | #include <string> |
25 | #include <boost/asio/async_result.hpp> |
26 | #include <boost/asio/detail/reactive_serial_port_service.hpp> |
27 | #include <boost/asio/detail/win_iocp_serial_port_service.hpp> |
28 | #include <boost/asio/error.hpp> |
29 | #include <boost/asio/io_service.hpp> |
30 | #include <boost/asio/serial_port_base.hpp> |
31 | |
32 | #include <boost/asio/detail/push_options.hpp> |
33 | |
34 | namespace boost { |
35 | namespace asio { |
36 | |
37 | /// Default service implementation for a serial port. |
38 | class serial_port_service |
39 | #if defined(GENERATING_DOCUMENTATION) |
40 | : public boost::asio::io_service::service |
41 | #else |
42 | : public boost::asio::detail::service_base<serial_port_service> |
43 | #endif |
44 | { |
45 | public: |
46 | #if defined(GENERATING_DOCUMENTATION) |
47 | /// The unique service identifier. |
48 | static boost::asio::io_service::id id; |
49 | #endif |
50 | |
51 | private: |
52 | // The type of the platform-specific implementation. |
53 | #if defined(BOOST_ASIO_HAS_IOCP) |
54 | typedef detail::win_iocp_serial_port_service service_impl_type; |
55 | #else |
56 | typedef detail::reactive_serial_port_service service_impl_type; |
57 | #endif |
58 | |
59 | public: |
60 | /// The type of a serial port implementation. |
61 | #if defined(GENERATING_DOCUMENTATION) |
62 | typedef implementation_defined implementation_type; |
63 | #else |
64 | typedef service_impl_type::implementation_type implementation_type; |
65 | #endif |
66 | |
67 | /// (Deprecated: Use native_handle_type.) The native handle type. |
68 | #if defined(GENERATING_DOCUMENTATION) |
69 | typedef implementation_defined native_type; |
70 | #else |
71 | typedef service_impl_type::native_handle_type native_type; |
72 | #endif |
73 | |
74 | /// The native handle type. |
75 | #if defined(GENERATING_DOCUMENTATION) |
76 | typedef implementation_defined native_handle_type; |
77 | #else |
78 | typedef service_impl_type::native_handle_type native_handle_type; |
79 | #endif |
80 | |
81 | /// Construct a new serial port service for the specified io_service. |
82 | explicit serial_port_service(boost::asio::io_service& io_service) |
83 | : boost::asio::detail::service_base<serial_port_service>(io_service), |
84 | service_impl_(io_service) |
85 | { |
86 | } |
87 | |
88 | /// Construct a new serial port implementation. |
89 | void construct(implementation_type& impl) |
90 | { |
91 | service_impl_.construct(impl); |
92 | } |
93 | |
94 | #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) |
95 | /// Move-construct a new serial port implementation. |
96 | void move_construct(implementation_type& impl, |
97 | implementation_type& other_impl) |
98 | { |
99 | service_impl_.move_construct(impl, other_impl); |
100 | } |
101 | |
102 | /// Move-assign from another serial port implementation. |
103 | void move_assign(implementation_type& impl, |
104 | serial_port_service& other_service, |
105 | implementation_type& other_impl) |
106 | { |
107 | service_impl_.move_assign(impl, other_service&: other_service.service_impl_, other_impl); |
108 | } |
109 | #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) |
110 | |
111 | /// Destroy a serial port implementation. |
112 | void destroy(implementation_type& impl) |
113 | { |
114 | service_impl_.destroy(impl); |
115 | } |
116 | |
117 | /// Open a serial port. |
118 | boost::system::error_code open(implementation_type& impl, |
119 | const std::string& device, boost::system::error_code& ec) |
120 | { |
121 | return service_impl_.open(impl, device, ec); |
122 | } |
123 | |
124 | /// Assign an existing native handle to a serial port. |
125 | boost::system::error_code assign(implementation_type& impl, |
126 | const native_handle_type& handle, boost::system::error_code& ec) |
127 | { |
128 | return service_impl_.assign(impl, native_descriptor: handle, ec); |
129 | } |
130 | |
131 | /// Determine whether the handle is open. |
132 | bool is_open(const implementation_type& impl) const |
133 | { |
134 | return service_impl_.is_open(impl); |
135 | } |
136 | |
137 | /// Close a serial port implementation. |
138 | boost::system::error_code close(implementation_type& impl, |
139 | boost::system::error_code& ec) |
140 | { |
141 | return service_impl_.close(impl, ec); |
142 | } |
143 | |
144 | /// (Deprecated: Use native_handle().) Get the native handle implementation. |
145 | native_type native(implementation_type& impl) |
146 | { |
147 | return service_impl_.native_handle(impl); |
148 | } |
149 | |
150 | /// Get the native handle implementation. |
151 | native_handle_type native_handle(implementation_type& impl) |
152 | { |
153 | return service_impl_.native_handle(impl); |
154 | } |
155 | |
156 | /// Cancel all asynchronous operations associated with the handle. |
157 | boost::system::error_code cancel(implementation_type& impl, |
158 | boost::system::error_code& ec) |
159 | { |
160 | return service_impl_.cancel(impl, ec); |
161 | } |
162 | |
163 | /// Set a serial port option. |
164 | template <typename SettableSerialPortOption> |
165 | boost::system::error_code set_option(implementation_type& impl, |
166 | const SettableSerialPortOption& option, boost::system::error_code& ec) |
167 | { |
168 | return service_impl_.set_option(impl, option, ec); |
169 | } |
170 | |
171 | /// Get a serial port option. |
172 | template <typename GettableSerialPortOption> |
173 | boost::system::error_code get_option(const implementation_type& impl, |
174 | GettableSerialPortOption& option, boost::system::error_code& ec) const |
175 | { |
176 | return service_impl_.get_option(impl, option, ec); |
177 | } |
178 | |
179 | /// Send a break sequence to the serial port. |
180 | boost::system::error_code send_break(implementation_type& impl, |
181 | boost::system::error_code& ec) |
182 | { |
183 | return service_impl_.send_break(impl, ec); |
184 | } |
185 | |
186 | /// Write the given data to the stream. |
187 | template <typename ConstBufferSequence> |
188 | std::size_t write_some(implementation_type& impl, |
189 | const ConstBufferSequence& buffers, boost::system::error_code& ec) |
190 | { |
191 | return service_impl_.write_some(impl, buffers, ec); |
192 | } |
193 | |
194 | /// Start an asynchronous write. |
195 | template <typename ConstBufferSequence, typename WriteHandler> |
196 | BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, |
197 | void (boost::system::error_code, std::size_t)) |
198 | async_write_some(implementation_type& impl, |
199 | const ConstBufferSequence& buffers, |
200 | BOOST_ASIO_MOVE_ARG(WriteHandler) handler) |
201 | { |
202 | detail::async_result_init< |
203 | WriteHandler, void (boost::system::error_code, std::size_t)> init( |
204 | BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); |
205 | |
206 | service_impl_.async_write_some(impl, buffers, init.handler); |
207 | |
208 | return init.result.get(); |
209 | } |
210 | |
211 | /// Read some data from the stream. |
212 | template <typename MutableBufferSequence> |
213 | std::size_t read_some(implementation_type& impl, |
214 | const MutableBufferSequence& buffers, boost::system::error_code& ec) |
215 | { |
216 | return service_impl_.read_some(impl, buffers, ec); |
217 | } |
218 | |
219 | /// Start an asynchronous read. |
220 | template <typename MutableBufferSequence, typename ReadHandler> |
221 | BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, |
222 | void (boost::system::error_code, std::size_t)) |
223 | async_read_some(implementation_type& impl, |
224 | const MutableBufferSequence& buffers, |
225 | BOOST_ASIO_MOVE_ARG(ReadHandler) handler) |
226 | { |
227 | detail::async_result_init< |
228 | ReadHandler, void (boost::system::error_code, std::size_t)> init( |
229 | BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); |
230 | |
231 | service_impl_.async_read_some(impl, buffers, init.handler); |
232 | |
233 | return init.result.get(); |
234 | } |
235 | |
236 | private: |
237 | // Destroy all user-defined handler objects owned by the service. |
238 | void shutdown_service() |
239 | { |
240 | service_impl_.shutdown_service(); |
241 | } |
242 | |
243 | // The platform-specific implementation. |
244 | service_impl_type service_impl_; |
245 | }; |
246 | |
247 | } // namespace asio |
248 | } // namespace boost |
249 | |
250 | #include <boost/asio/detail/pop_options.hpp> |
251 | |
252 | #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) |
253 | // || defined(GENERATING_DOCUMENTATION) |
254 | |
255 | #endif // BOOST_ASIO_SERIAL_PORT_SERVICE_HPP |
256 | |