]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // basic_serial_port.hpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
92f5a8d4 | 5 | // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
7c673cae FG |
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_BASIC_SERIAL_PORT_HPP | |
13 | #define BOOST_ASIO_BASIC_SERIAL_PORT_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_SERIAL_PORT) \ | |
22 | || defined(GENERATING_DOCUMENTATION) | |
23 | ||
24 | #include <string> | |
92f5a8d4 | 25 | #include <boost/asio/async_result.hpp> |
7c673cae | 26 | #include <boost/asio/detail/handler_type_requirements.hpp> |
92f5a8d4 TL |
27 | #include <boost/asio/detail/io_object_impl.hpp> |
28 | #include <boost/asio/detail/non_const_lvalue.hpp> | |
7c673cae | 29 | #include <boost/asio/detail/throw_error.hpp> |
92f5a8d4 | 30 | #include <boost/asio/detail/type_traits.hpp> |
7c673cae | 31 | #include <boost/asio/error.hpp> |
92f5a8d4 TL |
32 | #include <boost/asio/execution_context.hpp> |
33 | #include <boost/asio/executor.hpp> | |
7c673cae | 34 | #include <boost/asio/serial_port_base.hpp> |
92f5a8d4 TL |
35 | #if defined(BOOST_ASIO_HAS_IOCP) |
36 | # include <boost/asio/detail/win_iocp_serial_port_service.hpp> | |
37 | #else | |
38 | # include <boost/asio/detail/reactive_serial_port_service.hpp> | |
39 | #endif | |
40 | ||
41 | #if defined(BOOST_ASIO_HAS_MOVE) | |
42 | # include <utility> | |
43 | #endif // defined(BOOST_ASIO_HAS_MOVE) | |
7c673cae FG |
44 | |
45 | #include <boost/asio/detail/push_options.hpp> | |
46 | ||
47 | namespace boost { | |
48 | namespace asio { | |
49 | ||
50 | /// Provides serial port functionality. | |
51 | /** | |
92f5a8d4 TL |
52 | * The basic_serial_port class provides a wrapper over serial port |
53 | * functionality. | |
7c673cae FG |
54 | * |
55 | * @par Thread Safety | |
56 | * @e Distinct @e objects: Safe.@n | |
57 | * @e Shared @e objects: Unsafe. | |
58 | */ | |
92f5a8d4 | 59 | template <typename Executor = executor> |
7c673cae | 60 | class basic_serial_port |
92f5a8d4 | 61 | : public serial_port_base |
7c673cae FG |
62 | { |
63 | public: | |
92f5a8d4 TL |
64 | /// The type of the executor associated with the object. |
65 | typedef Executor executor_type; | |
66 | ||
67 | /// Rebinds the serial port type to another executor. | |
68 | template <typename Executor1> | |
69 | struct rebind_executor | |
70 | { | |
71 | /// The serial port type when rebound to the specified executor. | |
72 | typedef basic_serial_port<Executor1> other; | |
73 | }; | |
74 | ||
7c673cae | 75 | /// The native representation of a serial port. |
92f5a8d4 TL |
76 | #if defined(GENERATING_DOCUMENTATION) |
77 | typedef implementation_defined native_handle_type; | |
78 | #elif defined(BOOST_ASIO_HAS_IOCP) | |
79 | typedef detail::win_iocp_serial_port_service::native_handle_type | |
80 | native_handle_type; | |
81 | #else | |
82 | typedef detail::reactive_serial_port_service::native_handle_type | |
83 | native_handle_type; | |
84 | #endif | |
85 | ||
86 | /// A basic_basic_serial_port is always the lowest layer. | |
87 | typedef basic_serial_port lowest_layer_type; | |
7c673cae | 88 | |
92f5a8d4 TL |
89 | /// Construct a basic_serial_port without opening it. |
90 | /** | |
91 | * This constructor creates a serial port without opening it. | |
92 | * | |
93 | * @param ex The I/O executor that the serial port will use, by default, to | |
94 | * dispatch handlers for any asynchronous operations performed on the | |
95 | * serial port. | |
96 | */ | |
97 | explicit basic_serial_port(const executor_type& ex) | |
98 | : impl_(ex) | |
99 | { | |
100 | } | |
7c673cae FG |
101 | |
102 | /// Construct a basic_serial_port without opening it. | |
103 | /** | |
104 | * This constructor creates a serial port without opening it. | |
105 | * | |
92f5a8d4 TL |
106 | * @param context An execution context which provides the I/O executor that |
107 | * the serial port will use, by default, to dispatch handlers for any | |
108 | * asynchronous operations performed on the serial port. | |
109 | */ | |
110 | template <typename ExecutionContext> | |
111 | explicit basic_serial_port(ExecutionContext& context, | |
112 | typename enable_if< | |
113 | is_convertible<ExecutionContext&, execution_context&>::value, | |
114 | basic_serial_port | |
115 | >::type* = 0) | |
116 | : impl_(context) | |
117 | { | |
118 | } | |
119 | ||
120 | /// Construct and open a basic_serial_port. | |
121 | /** | |
122 | * This constructor creates and opens a serial port for the specified device | |
123 | * name. | |
124 | * | |
125 | * @param ex The I/O executor that the serial port will use, by default, to | |
126 | * dispatch handlers for any asynchronous operations performed on the | |
127 | * serial port. | |
128 | * | |
129 | * @param device The platform-specific device name for this serial | |
130 | * port. | |
131 | */ | |
132 | basic_serial_port(const executor_type& ex, const char* device) | |
133 | : impl_(ex) | |
134 | { | |
135 | boost::system::error_code ec; | |
136 | impl_.get_service().open(impl_.get_implementation(), device, ec); | |
137 | boost::asio::detail::throw_error(ec, "open"); | |
138 | } | |
139 | ||
140 | /// Construct and open a basic_serial_port. | |
141 | /** | |
142 | * This constructor creates and opens a serial port for the specified device | |
143 | * name. | |
144 | * | |
145 | * @param context An execution context which provides the I/O executor that | |
146 | * the serial port will use, by default, to dispatch handlers for any | |
147 | * asynchronous operations performed on the serial port. | |
148 | * | |
149 | * @param device The platform-specific device name for this serial | |
150 | * port. | |
7c673cae | 151 | */ |
92f5a8d4 TL |
152 | template <typename ExecutionContext> |
153 | basic_serial_port(ExecutionContext& context, const char* device, | |
154 | typename enable_if< | |
155 | is_convertible<ExecutionContext&, execution_context&>::value | |
156 | >::type* = 0) | |
157 | : impl_(context) | |
7c673cae | 158 | { |
92f5a8d4 TL |
159 | boost::system::error_code ec; |
160 | impl_.get_service().open(impl_.get_implementation(), device, ec); | |
161 | boost::asio::detail::throw_error(ec, "open"); | |
7c673cae FG |
162 | } |
163 | ||
164 | /// Construct and open a basic_serial_port. | |
165 | /** | |
166 | * This constructor creates and opens a serial port for the specified device | |
167 | * name. | |
168 | * | |
92f5a8d4 TL |
169 | * @param ex The I/O executor that the serial port will use, by default, to |
170 | * dispatch handlers for any asynchronous operations performed on the | |
171 | * serial port. | |
7c673cae FG |
172 | * |
173 | * @param device The platform-specific device name for this serial | |
174 | * port. | |
175 | */ | |
92f5a8d4 TL |
176 | basic_serial_port(const executor_type& ex, const std::string& device) |
177 | : impl_(ex) | |
7c673cae FG |
178 | { |
179 | boost::system::error_code ec; | |
92f5a8d4 | 180 | impl_.get_service().open(impl_.get_implementation(), device, ec); |
7c673cae FG |
181 | boost::asio::detail::throw_error(ec, "open"); |
182 | } | |
183 | ||
184 | /// Construct and open a basic_serial_port. | |
185 | /** | |
186 | * This constructor creates and opens a serial port for the specified device | |
187 | * name. | |
188 | * | |
92f5a8d4 TL |
189 | * @param context An execution context which provides the I/O executor that |
190 | * the serial port will use, by default, to dispatch handlers for any | |
191 | * asynchronous operations performed on the serial port. | |
7c673cae FG |
192 | * |
193 | * @param device The platform-specific device name for this serial | |
194 | * port. | |
195 | */ | |
92f5a8d4 TL |
196 | template <typename ExecutionContext> |
197 | basic_serial_port(ExecutionContext& context, const std::string& device, | |
198 | typename enable_if< | |
199 | is_convertible<ExecutionContext&, execution_context&>::value | |
200 | >::type* = 0) | |
201 | : impl_(context) | |
7c673cae FG |
202 | { |
203 | boost::system::error_code ec; | |
92f5a8d4 | 204 | impl_.get_service().open(impl_.get_implementation(), device, ec); |
7c673cae FG |
205 | boost::asio::detail::throw_error(ec, "open"); |
206 | } | |
207 | ||
208 | /// Construct a basic_serial_port on an existing native serial port. | |
209 | /** | |
210 | * This constructor creates a serial port object to hold an existing native | |
211 | * serial port. | |
212 | * | |
92f5a8d4 TL |
213 | * @param ex The I/O executor that the serial port will use, by default, to |
214 | * dispatch handlers for any asynchronous operations performed on the | |
215 | * serial port. | |
7c673cae FG |
216 | * |
217 | * @param native_serial_port A native serial port. | |
218 | * | |
219 | * @throws boost::system::system_error Thrown on failure. | |
220 | */ | |
92f5a8d4 | 221 | basic_serial_port(const executor_type& ex, |
7c673cae | 222 | const native_handle_type& native_serial_port) |
92f5a8d4 TL |
223 | : impl_(ex) |
224 | { | |
225 | boost::system::error_code ec; | |
226 | impl_.get_service().assign(impl_.get_implementation(), | |
227 | native_serial_port, ec); | |
228 | boost::asio::detail::throw_error(ec, "assign"); | |
229 | } | |
230 | ||
231 | /// Construct a basic_serial_port on an existing native serial port. | |
232 | /** | |
233 | * This constructor creates a serial port object to hold an existing native | |
234 | * serial port. | |
235 | * | |
236 | * @param context An execution context which provides the I/O executor that | |
237 | * the serial port will use, by default, to dispatch handlers for any | |
238 | * asynchronous operations performed on the serial port. | |
239 | * | |
240 | * @param native_serial_port A native serial port. | |
241 | * | |
242 | * @throws boost::system::system_error Thrown on failure. | |
243 | */ | |
244 | template <typename ExecutionContext> | |
245 | basic_serial_port(ExecutionContext& context, | |
246 | const native_handle_type& native_serial_port, | |
247 | typename enable_if< | |
248 | is_convertible<ExecutionContext&, execution_context&>::value | |
249 | >::type* = 0) | |
250 | : impl_(context) | |
7c673cae FG |
251 | { |
252 | boost::system::error_code ec; | |
92f5a8d4 | 253 | impl_.get_service().assign(impl_.get_implementation(), |
7c673cae FG |
254 | native_serial_port, ec); |
255 | boost::asio::detail::throw_error(ec, "assign"); | |
256 | } | |
257 | ||
258 | #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
259 | /// Move-construct a basic_serial_port from another. | |
260 | /** | |
261 | * This constructor moves a serial port from one object to another. | |
262 | * | |
263 | * @param other The other basic_serial_port object from which the move will | |
264 | * occur. | |
265 | * | |
266 | * @note Following the move, the moved-from object is in the same state as if | |
92f5a8d4 TL |
267 | * constructed using the @c basic_serial_port(const executor_type&) |
268 | * constructor. | |
7c673cae FG |
269 | */ |
270 | basic_serial_port(basic_serial_port&& other) | |
92f5a8d4 | 271 | : impl_(std::move(other.impl_)) |
7c673cae FG |
272 | { |
273 | } | |
274 | ||
275 | /// Move-assign a basic_serial_port from another. | |
276 | /** | |
277 | * This assignment operator moves a serial port from one object to another. | |
278 | * | |
279 | * @param other The other basic_serial_port object from which the move will | |
280 | * occur. | |
281 | * | |
282 | * @note Following the move, the moved-from object is in the same state as if | |
92f5a8d4 TL |
283 | * constructed using the @c basic_serial_port(const executor_type&) |
284 | * constructor. | |
7c673cae FG |
285 | */ |
286 | basic_serial_port& operator=(basic_serial_port&& other) | |
287 | { | |
92f5a8d4 | 288 | impl_ = std::move(other.impl_); |
7c673cae FG |
289 | return *this; |
290 | } | |
291 | #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
292 | ||
92f5a8d4 TL |
293 | /// Destroys the serial port. |
294 | /** | |
295 | * This function destroys the serial port, cancelling any outstanding | |
296 | * asynchronous wait operations associated with the serial port as if by | |
297 | * calling @c cancel. | |
298 | */ | |
299 | ~basic_serial_port() | |
300 | { | |
301 | } | |
302 | ||
303 | /// Get the executor associated with the object. | |
304 | executor_type get_executor() BOOST_ASIO_NOEXCEPT | |
305 | { | |
306 | return impl_.get_executor(); | |
307 | } | |
308 | ||
7c673cae FG |
309 | /// Get a reference to the lowest layer. |
310 | /** | |
311 | * This function returns a reference to the lowest layer in a stack of | |
312 | * layers. Since a basic_serial_port cannot contain any further layers, it | |
313 | * simply returns a reference to itself. | |
314 | * | |
315 | * @return A reference to the lowest layer in the stack of layers. Ownership | |
316 | * is not transferred to the caller. | |
317 | */ | |
318 | lowest_layer_type& lowest_layer() | |
319 | { | |
320 | return *this; | |
321 | } | |
322 | ||
323 | /// Get a const reference to the lowest layer. | |
324 | /** | |
325 | * This function returns a const reference to the lowest layer in a stack of | |
326 | * layers. Since a basic_serial_port cannot contain any further layers, it | |
327 | * simply returns a reference to itself. | |
328 | * | |
329 | * @return A const reference to the lowest layer in the stack of layers. | |
330 | * Ownership is not transferred to the caller. | |
331 | */ | |
332 | const lowest_layer_type& lowest_layer() const | |
333 | { | |
334 | return *this; | |
335 | } | |
336 | ||
337 | /// Open the serial port using the specified device name. | |
338 | /** | |
339 | * This function opens the serial port for the specified device name. | |
340 | * | |
341 | * @param device The platform-specific device name. | |
342 | * | |
343 | * @throws boost::system::system_error Thrown on failure. | |
344 | */ | |
345 | void open(const std::string& device) | |
346 | { | |
347 | boost::system::error_code ec; | |
92f5a8d4 | 348 | impl_.get_service().open(impl_.get_implementation(), device, ec); |
7c673cae FG |
349 | boost::asio::detail::throw_error(ec, "open"); |
350 | } | |
351 | ||
352 | /// Open the serial port using the specified device name. | |
353 | /** | |
354 | * This function opens the serial port using the given platform-specific | |
355 | * device name. | |
356 | * | |
357 | * @param device The platform-specific device name. | |
358 | * | |
359 | * @param ec Set the indicate what error occurred, if any. | |
360 | */ | |
b32b8144 | 361 | BOOST_ASIO_SYNC_OP_VOID open(const std::string& device, |
7c673cae FG |
362 | boost::system::error_code& ec) |
363 | { | |
92f5a8d4 | 364 | impl_.get_service().open(impl_.get_implementation(), device, ec); |
b32b8144 | 365 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
366 | } |
367 | ||
368 | /// Assign an existing native serial port to the serial port. | |
369 | /* | |
370 | * This function opens the serial port to hold an existing native serial port. | |
371 | * | |
372 | * @param native_serial_port A native serial port. | |
373 | * | |
374 | * @throws boost::system::system_error Thrown on failure. | |
375 | */ | |
376 | void assign(const native_handle_type& native_serial_port) | |
377 | { | |
378 | boost::system::error_code ec; | |
92f5a8d4 | 379 | impl_.get_service().assign(impl_.get_implementation(), |
7c673cae FG |
380 | native_serial_port, ec); |
381 | boost::asio::detail::throw_error(ec, "assign"); | |
382 | } | |
383 | ||
384 | /// Assign an existing native serial port to the serial port. | |
385 | /* | |
386 | * This function opens the serial port to hold an existing native serial port. | |
387 | * | |
388 | * @param native_serial_port A native serial port. | |
389 | * | |
390 | * @param ec Set to indicate what error occurred, if any. | |
391 | */ | |
b32b8144 | 392 | BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port, |
7c673cae FG |
393 | boost::system::error_code& ec) |
394 | { | |
92f5a8d4 | 395 | impl_.get_service().assign(impl_.get_implementation(), |
7c673cae | 396 | native_serial_port, ec); |
b32b8144 | 397 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
398 | } |
399 | ||
400 | /// Determine whether the serial port is open. | |
401 | bool is_open() const | |
402 | { | |
92f5a8d4 | 403 | return impl_.get_service().is_open(impl_.get_implementation()); |
7c673cae FG |
404 | } |
405 | ||
406 | /// Close the serial port. | |
407 | /** | |
408 | * This function is used to close the serial port. Any asynchronous read or | |
409 | * write operations will be cancelled immediately, and will complete with the | |
410 | * boost::asio::error::operation_aborted error. | |
411 | * | |
412 | * @throws boost::system::system_error Thrown on failure. | |
413 | */ | |
414 | void close() | |
415 | { | |
416 | boost::system::error_code ec; | |
92f5a8d4 | 417 | impl_.get_service().close(impl_.get_implementation(), ec); |
7c673cae FG |
418 | boost::asio::detail::throw_error(ec, "close"); |
419 | } | |
420 | ||
421 | /// Close the serial port. | |
422 | /** | |
423 | * This function is used to close the serial port. Any asynchronous read or | |
424 | * write operations will be cancelled immediately, and will complete with the | |
425 | * boost::asio::error::operation_aborted error. | |
426 | * | |
427 | * @param ec Set to indicate what error occurred, if any. | |
428 | */ | |
b32b8144 | 429 | BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) |
7c673cae | 430 | { |
92f5a8d4 | 431 | impl_.get_service().close(impl_.get_implementation(), ec); |
b32b8144 | 432 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
433 | } |
434 | ||
435 | /// Get the native serial port representation. | |
436 | /** | |
437 | * This function may be used to obtain the underlying representation of the | |
438 | * serial port. This is intended to allow access to native serial port | |
439 | * functionality that is not otherwise provided. | |
440 | */ | |
441 | native_handle_type native_handle() | |
442 | { | |
92f5a8d4 | 443 | return impl_.get_service().native_handle(impl_.get_implementation()); |
7c673cae FG |
444 | } |
445 | ||
446 | /// Cancel all asynchronous operations associated with the serial port. | |
447 | /** | |
448 | * This function causes all outstanding asynchronous read or write operations | |
449 | * to finish immediately, and the handlers for cancelled operations will be | |
450 | * passed the boost::asio::error::operation_aborted error. | |
451 | * | |
452 | * @throws boost::system::system_error Thrown on failure. | |
453 | */ | |
454 | void cancel() | |
455 | { | |
456 | boost::system::error_code ec; | |
92f5a8d4 | 457 | impl_.get_service().cancel(impl_.get_implementation(), ec); |
7c673cae FG |
458 | boost::asio::detail::throw_error(ec, "cancel"); |
459 | } | |
460 | ||
461 | /// Cancel all asynchronous operations associated with the serial port. | |
462 | /** | |
463 | * This function causes all outstanding asynchronous read or write operations | |
464 | * to finish immediately, and the handlers for cancelled operations will be | |
465 | * passed the boost::asio::error::operation_aborted error. | |
466 | * | |
467 | * @param ec Set to indicate what error occurred, if any. | |
468 | */ | |
b32b8144 | 469 | BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) |
7c673cae | 470 | { |
92f5a8d4 | 471 | impl_.get_service().cancel(impl_.get_implementation(), ec); |
b32b8144 | 472 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
473 | } |
474 | ||
475 | /// Send a break sequence to the serial port. | |
476 | /** | |
477 | * This function causes a break sequence of platform-specific duration to be | |
478 | * sent out the serial port. | |
479 | * | |
480 | * @throws boost::system::system_error Thrown on failure. | |
481 | */ | |
482 | void send_break() | |
483 | { | |
484 | boost::system::error_code ec; | |
92f5a8d4 | 485 | impl_.get_service().send_break(impl_.get_implementation(), ec); |
7c673cae FG |
486 | boost::asio::detail::throw_error(ec, "send_break"); |
487 | } | |
488 | ||
489 | /// Send a break sequence to the serial port. | |
490 | /** | |
491 | * This function causes a break sequence of platform-specific duration to be | |
492 | * sent out the serial port. | |
493 | * | |
494 | * @param ec Set to indicate what error occurred, if any. | |
495 | */ | |
b32b8144 | 496 | BOOST_ASIO_SYNC_OP_VOID send_break(boost::system::error_code& ec) |
7c673cae | 497 | { |
92f5a8d4 | 498 | impl_.get_service().send_break(impl_.get_implementation(), ec); |
b32b8144 | 499 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
500 | } |
501 | ||
502 | /// Set an option on the serial port. | |
503 | /** | |
504 | * This function is used to set an option on the serial port. | |
505 | * | |
506 | * @param option The option value to be set on the serial port. | |
507 | * | |
508 | * @throws boost::system::system_error Thrown on failure. | |
509 | * | |
510 | * @sa SettableSerialPortOption @n | |
511 | * boost::asio::serial_port_base::baud_rate @n | |
512 | * boost::asio::serial_port_base::flow_control @n | |
513 | * boost::asio::serial_port_base::parity @n | |
514 | * boost::asio::serial_port_base::stop_bits @n | |
515 | * boost::asio::serial_port_base::character_size | |
516 | */ | |
517 | template <typename SettableSerialPortOption> | |
518 | void set_option(const SettableSerialPortOption& option) | |
519 | { | |
520 | boost::system::error_code ec; | |
92f5a8d4 | 521 | impl_.get_service().set_option(impl_.get_implementation(), option, ec); |
7c673cae FG |
522 | boost::asio::detail::throw_error(ec, "set_option"); |
523 | } | |
524 | ||
525 | /// Set an option on the serial port. | |
526 | /** | |
527 | * This function is used to set an option on the serial port. | |
528 | * | |
529 | * @param option The option value to be set on the serial port. | |
530 | * | |
531 | * @param ec Set to indicate what error occurred, if any. | |
532 | * | |
533 | * @sa SettableSerialPortOption @n | |
534 | * boost::asio::serial_port_base::baud_rate @n | |
535 | * boost::asio::serial_port_base::flow_control @n | |
536 | * boost::asio::serial_port_base::parity @n | |
537 | * boost::asio::serial_port_base::stop_bits @n | |
538 | * boost::asio::serial_port_base::character_size | |
539 | */ | |
540 | template <typename SettableSerialPortOption> | |
b32b8144 | 541 | BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option, |
7c673cae FG |
542 | boost::system::error_code& ec) |
543 | { | |
92f5a8d4 | 544 | impl_.get_service().set_option(impl_.get_implementation(), option, ec); |
b32b8144 | 545 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
546 | } |
547 | ||
548 | /// Get an option from the serial port. | |
549 | /** | |
550 | * This function is used to get the current value of an option on the serial | |
551 | * port. | |
552 | * | |
553 | * @param option The option value to be obtained from the serial port. | |
554 | * | |
555 | * @throws boost::system::system_error Thrown on failure. | |
556 | * | |
557 | * @sa GettableSerialPortOption @n | |
558 | * boost::asio::serial_port_base::baud_rate @n | |
559 | * boost::asio::serial_port_base::flow_control @n | |
560 | * boost::asio::serial_port_base::parity @n | |
561 | * boost::asio::serial_port_base::stop_bits @n | |
562 | * boost::asio::serial_port_base::character_size | |
563 | */ | |
564 | template <typename GettableSerialPortOption> | |
92f5a8d4 | 565 | void get_option(GettableSerialPortOption& option) const |
7c673cae FG |
566 | { |
567 | boost::system::error_code ec; | |
92f5a8d4 | 568 | impl_.get_service().get_option(impl_.get_implementation(), option, ec); |
7c673cae FG |
569 | boost::asio::detail::throw_error(ec, "get_option"); |
570 | } | |
571 | ||
572 | /// Get an option from the serial port. | |
573 | /** | |
574 | * This function is used to get the current value of an option on the serial | |
575 | * port. | |
576 | * | |
577 | * @param option The option value to be obtained from the serial port. | |
578 | * | |
579 | * @param ec Set to indicate what error occurred, if any. | |
580 | * | |
581 | * @sa GettableSerialPortOption @n | |
582 | * boost::asio::serial_port_base::baud_rate @n | |
583 | * boost::asio::serial_port_base::flow_control @n | |
584 | * boost::asio::serial_port_base::parity @n | |
585 | * boost::asio::serial_port_base::stop_bits @n | |
586 | * boost::asio::serial_port_base::character_size | |
587 | */ | |
588 | template <typename GettableSerialPortOption> | |
b32b8144 | 589 | BOOST_ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option, |
92f5a8d4 | 590 | boost::system::error_code& ec) const |
7c673cae | 591 | { |
92f5a8d4 | 592 | impl_.get_service().get_option(impl_.get_implementation(), option, ec); |
b32b8144 | 593 | BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); |
7c673cae FG |
594 | } |
595 | ||
596 | /// Write some data to the serial port. | |
597 | /** | |
598 | * This function is used to write data to the serial port. The function call | |
599 | * will block until one or more bytes of the data has been written | |
600 | * successfully, or until an error occurs. | |
601 | * | |
602 | * @param buffers One or more data buffers to be written to the serial port. | |
603 | * | |
604 | * @returns The number of bytes written. | |
605 | * | |
606 | * @throws boost::system::system_error Thrown on failure. An error code of | |
607 | * boost::asio::error::eof indicates that the connection was closed by the | |
608 | * peer. | |
609 | * | |
610 | * @note The write_some operation may not transmit all of the data to the | |
611 | * peer. Consider using the @ref write function if you need to ensure that | |
612 | * all data is written before the blocking operation completes. | |
613 | * | |
614 | * @par Example | |
615 | * To write a single data buffer use the @ref buffer function as follows: | |
616 | * @code | |
92f5a8d4 | 617 | * basic_serial_port.write_some(boost::asio::buffer(data, size)); |
7c673cae FG |
618 | * @endcode |
619 | * See the @ref buffer documentation for information on writing multiple | |
620 | * buffers in one go, and how to use it with arrays, boost::array or | |
621 | * std::vector. | |
622 | */ | |
623 | template <typename ConstBufferSequence> | |
624 | std::size_t write_some(const ConstBufferSequence& buffers) | |
625 | { | |
626 | boost::system::error_code ec; | |
92f5a8d4 TL |
627 | std::size_t s = impl_.get_service().write_some( |
628 | impl_.get_implementation(), buffers, ec); | |
7c673cae FG |
629 | boost::asio::detail::throw_error(ec, "write_some"); |
630 | return s; | |
631 | } | |
632 | ||
633 | /// Write some data to the serial port. | |
634 | /** | |
635 | * This function is used to write data to the serial port. The function call | |
636 | * will block until one or more bytes of the data has been written | |
637 | * successfully, or until an error occurs. | |
638 | * | |
639 | * @param buffers One or more data buffers to be written to the serial port. | |
640 | * | |
641 | * @param ec Set to indicate what error occurred, if any. | |
642 | * | |
643 | * @returns The number of bytes written. Returns 0 if an error occurred. | |
644 | * | |
645 | * @note The write_some operation may not transmit all of the data to the | |
646 | * peer. Consider using the @ref write function if you need to ensure that | |
647 | * all data is written before the blocking operation completes. | |
648 | */ | |
649 | template <typename ConstBufferSequence> | |
650 | std::size_t write_some(const ConstBufferSequence& buffers, | |
651 | boost::system::error_code& ec) | |
652 | { | |
92f5a8d4 TL |
653 | return impl_.get_service().write_some( |
654 | impl_.get_implementation(), buffers, ec); | |
7c673cae FG |
655 | } |
656 | ||
657 | /// Start an asynchronous write. | |
658 | /** | |
659 | * This function is used to asynchronously write data to the serial port. | |
660 | * The function call always returns immediately. | |
661 | * | |
662 | * @param buffers One or more data buffers to be written to the serial port. | |
663 | * Although the buffers object may be copied as necessary, ownership of the | |
664 | * underlying memory blocks is retained by the caller, which must guarantee | |
665 | * that they remain valid until the handler is called. | |
666 | * | |
667 | * @param handler The handler to be called when the write operation completes. | |
668 | * Copies will be made of the handler as required. The function signature of | |
669 | * the handler must be: | |
670 | * @code void handler( | |
671 | * const boost::system::error_code& error, // Result of operation. | |
672 | * std::size_t bytes_transferred // Number of bytes written. | |
673 | * ); @endcode | |
674 | * Regardless of whether the asynchronous operation completes immediately or | |
92f5a8d4 TL |
675 | * not, the handler will not be invoked from within this function. On |
676 | * immediate completion, invocation of the handler will be performed in a | |
677 | * manner equivalent to using boost::asio::post(). | |
7c673cae FG |
678 | * |
679 | * @note The write operation may not transmit all of the data to the peer. | |
680 | * Consider using the @ref async_write function if you need to ensure that all | |
681 | * data is written before the asynchronous operation completes. | |
682 | * | |
683 | * @par Example | |
684 | * To write a single data buffer use the @ref buffer function as follows: | |
685 | * @code | |
92f5a8d4 TL |
686 | * basic_serial_port.async_write_some( |
687 | * boost::asio::buffer(data, size), handler); | |
7c673cae FG |
688 | * @endcode |
689 | * See the @ref buffer documentation for information on writing multiple | |
690 | * buffers in one go, and how to use it with arrays, boost::array or | |
691 | * std::vector. | |
692 | */ | |
92f5a8d4 TL |
693 | template <typename ConstBufferSequence, |
694 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
695 | std::size_t)) WriteHandler | |
696 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> | |
697 | BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, | |
7c673cae FG |
698 | void (boost::system::error_code, std::size_t)) |
699 | async_write_some(const ConstBufferSequence& buffers, | |
92f5a8d4 TL |
700 | BOOST_ASIO_MOVE_ARG(WriteHandler) handler |
701 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) | |
7c673cae | 702 | { |
92f5a8d4 TL |
703 | return async_initiate<WriteHandler, |
704 | void (boost::system::error_code, std::size_t)>( | |
705 | initiate_async_write_some(this), handler, buffers); | |
7c673cae FG |
706 | } |
707 | ||
708 | /// Read some data from the serial port. | |
709 | /** | |
710 | * This function is used to read data from the serial port. The function | |
711 | * call will block until one or more bytes of data has been read successfully, | |
712 | * or until an error occurs. | |
713 | * | |
714 | * @param buffers One or more buffers into which the data will be read. | |
715 | * | |
716 | * @returns The number of bytes read. | |
717 | * | |
718 | * @throws boost::system::system_error Thrown on failure. An error code of | |
719 | * boost::asio::error::eof indicates that the connection was closed by the | |
720 | * peer. | |
721 | * | |
722 | * @note The read_some operation may not read all of the requested number of | |
723 | * bytes. Consider using the @ref read function if you need to ensure that | |
724 | * the requested amount of data is read before the blocking operation | |
725 | * completes. | |
726 | * | |
727 | * @par Example | |
728 | * To read into a single data buffer use the @ref buffer function as follows: | |
729 | * @code | |
92f5a8d4 | 730 | * basic_serial_port.read_some(boost::asio::buffer(data, size)); |
7c673cae FG |
731 | * @endcode |
732 | * See the @ref buffer documentation for information on reading into multiple | |
733 | * buffers in one go, and how to use it with arrays, boost::array or | |
734 | * std::vector. | |
735 | */ | |
736 | template <typename MutableBufferSequence> | |
737 | std::size_t read_some(const MutableBufferSequence& buffers) | |
738 | { | |
739 | boost::system::error_code ec; | |
92f5a8d4 TL |
740 | std::size_t s = impl_.get_service().read_some( |
741 | impl_.get_implementation(), buffers, ec); | |
7c673cae FG |
742 | boost::asio::detail::throw_error(ec, "read_some"); |
743 | return s; | |
744 | } | |
745 | ||
746 | /// Read some data from the serial port. | |
747 | /** | |
748 | * This function is used to read data from the serial port. The function | |
749 | * call will block until one or more bytes of data has been read successfully, | |
750 | * or until an error occurs. | |
751 | * | |
752 | * @param buffers One or more buffers into which the data will be read. | |
753 | * | |
754 | * @param ec Set to indicate what error occurred, if any. | |
755 | * | |
756 | * @returns The number of bytes read. Returns 0 if an error occurred. | |
757 | * | |
758 | * @note The read_some operation may not read all of the requested number of | |
759 | * bytes. Consider using the @ref read function if you need to ensure that | |
760 | * the requested amount of data is read before the blocking operation | |
761 | * completes. | |
762 | */ | |
763 | template <typename MutableBufferSequence> | |
764 | std::size_t read_some(const MutableBufferSequence& buffers, | |
765 | boost::system::error_code& ec) | |
766 | { | |
92f5a8d4 TL |
767 | return impl_.get_service().read_some( |
768 | impl_.get_implementation(), buffers, ec); | |
7c673cae FG |
769 | } |
770 | ||
771 | /// Start an asynchronous read. | |
772 | /** | |
773 | * This function is used to asynchronously read data from the serial port. | |
774 | * The function call always returns immediately. | |
775 | * | |
776 | * @param buffers One or more buffers into which the data will be read. | |
777 | * Although the buffers object may be copied as necessary, ownership of the | |
778 | * underlying memory blocks is retained by the caller, which must guarantee | |
779 | * that they remain valid until the handler is called. | |
780 | * | |
781 | * @param handler The handler to be called when the read operation completes. | |
782 | * Copies will be made of the handler as required. The function signature of | |
783 | * the handler must be: | |
784 | * @code void handler( | |
785 | * const boost::system::error_code& error, // Result of operation. | |
786 | * std::size_t bytes_transferred // Number of bytes read. | |
787 | * ); @endcode | |
788 | * Regardless of whether the asynchronous operation completes immediately or | |
92f5a8d4 TL |
789 | * not, the handler will not be invoked from within this function. On |
790 | * immediate completion, invocation of the handler will be performed in a | |
791 | * manner equivalent to using boost::asio::post(). | |
7c673cae FG |
792 | * |
793 | * @note The read operation may not read all of the requested number of bytes. | |
794 | * Consider using the @ref async_read function if you need to ensure that the | |
795 | * requested amount of data is read before the asynchronous operation | |
796 | * completes. | |
797 | * | |
798 | * @par Example | |
799 | * To read into a single data buffer use the @ref buffer function as follows: | |
800 | * @code | |
92f5a8d4 TL |
801 | * basic_serial_port.async_read_some( |
802 | * boost::asio::buffer(data, size), handler); | |
7c673cae FG |
803 | * @endcode |
804 | * See the @ref buffer documentation for information on reading into multiple | |
805 | * buffers in one go, and how to use it with arrays, boost::array or | |
806 | * std::vector. | |
807 | */ | |
92f5a8d4 TL |
808 | template <typename MutableBufferSequence, |
809 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
810 | std::size_t)) ReadHandler | |
811 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> | |
812 | BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, | |
7c673cae FG |
813 | void (boost::system::error_code, std::size_t)) |
814 | async_read_some(const MutableBufferSequence& buffers, | |
92f5a8d4 TL |
815 | BOOST_ASIO_MOVE_ARG(ReadHandler) handler |
816 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) | |
7c673cae | 817 | { |
92f5a8d4 TL |
818 | return async_initiate<ReadHandler, |
819 | void (boost::system::error_code, std::size_t)>( | |
820 | initiate_async_read_some(this), handler, buffers); | |
7c673cae | 821 | } |
92f5a8d4 TL |
822 | |
823 | private: | |
824 | // Disallow copying and assignment. | |
825 | basic_serial_port(const basic_serial_port&) BOOST_ASIO_DELETED; | |
826 | basic_serial_port& operator=(const basic_serial_port&) BOOST_ASIO_DELETED; | |
827 | ||
828 | class initiate_async_write_some | |
829 | { | |
830 | public: | |
831 | typedef Executor executor_type; | |
832 | ||
833 | explicit initiate_async_write_some(basic_serial_port* self) | |
834 | : self_(self) | |
835 | { | |
836 | } | |
837 | ||
838 | executor_type get_executor() const BOOST_ASIO_NOEXCEPT | |
839 | { | |
840 | return self_->get_executor(); | |
841 | } | |
842 | ||
843 | template <typename WriteHandler, typename ConstBufferSequence> | |
844 | void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, | |
845 | const ConstBufferSequence& buffers) const | |
846 | { | |
847 | // If you get an error on the following line it means that your handler | |
848 | // does not meet the documented type requirements for a WriteHandler. | |
849 | BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; | |
850 | ||
851 | detail::non_const_lvalue<WriteHandler> handler2(handler); | |
852 | self_->impl_.get_service().async_write_some( | |
853 | self_->impl_.get_implementation(), buffers, handler2.value, | |
854 | self_->impl_.get_implementation_executor()); | |
855 | } | |
856 | ||
857 | private: | |
858 | basic_serial_port* self_; | |
859 | }; | |
860 | ||
861 | class initiate_async_read_some | |
862 | { | |
863 | public: | |
864 | typedef Executor executor_type; | |
865 | ||
866 | explicit initiate_async_read_some(basic_serial_port* self) | |
867 | : self_(self) | |
868 | { | |
869 | } | |
870 | ||
871 | executor_type get_executor() const BOOST_ASIO_NOEXCEPT | |
872 | { | |
873 | return self_->get_executor(); | |
874 | } | |
875 | ||
876 | template <typename ReadHandler, typename MutableBufferSequence> | |
877 | void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, | |
878 | const MutableBufferSequence& buffers) const | |
879 | { | |
880 | // If you get an error on the following line it means that your handler | |
881 | // does not meet the documented type requirements for a ReadHandler. | |
882 | BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; | |
883 | ||
884 | detail::non_const_lvalue<ReadHandler> handler2(handler); | |
885 | self_->impl_.get_service().async_read_some( | |
886 | self_->impl_.get_implementation(), buffers, handler2.value, | |
887 | self_->impl_.get_implementation_executor()); | |
888 | } | |
889 | ||
890 | private: | |
891 | basic_serial_port* self_; | |
892 | }; | |
893 | ||
894 | #if defined(BOOST_ASIO_HAS_IOCP) | |
895 | detail::io_object_impl<detail::win_iocp_serial_port_service, Executor> impl_; | |
896 | #else | |
897 | detail::io_object_impl<detail::reactive_serial_port_service, Executor> impl_; | |
898 | #endif | |
7c673cae FG |
899 | }; |
900 | ||
901 | } // namespace asio | |
902 | } // namespace boost | |
903 | ||
904 | #include <boost/asio/detail/pop_options.hpp> | |
905 | ||
906 | #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT) | |
907 | // || defined(GENERATING_DOCUMENTATION) | |
908 | ||
909 | #endif // BOOST_ASIO_BASIC_SERIAL_PORT_HPP |