diff --git a/serial-core/src/lib.rs b/serial-core/src/lib.rs index 8d26249..80f60a1 100644 --- a/serial-core/src/lib.rs +++ b/serial-core/src/lib.rs @@ -274,6 +274,19 @@ pub enum FlowControl { FlowHardware, } +/// Queues available to purge. +#[derive(Debug,Copy,Clone,PartialEq,Eq)] +pub enum Queue { + /// Receive queue. + Input, + + /// Transmit queue. + Output, + + /// Both the input and output queues. + Both, +} + /// A trait for implementing serial devices. /// /// This trait is meant to be used to implement new serial port devices. To use a serial port @@ -346,6 +359,12 @@ pub trait SerialDevice: io::Read + io::Write { /// Sets the timeout for future I/O operations. fn set_timeout(&mut self, timeout: Duration) -> ::Result<()>; + /// Purges the send or receive queue. + /// + /// Clears any data that has been queued for sending or receiving. The data is discarded + /// without being sent or received. + fn purge(&mut self, queue: Queue) -> ::Result<()>; + /// Sets the state of the RTS (Request To Send) control signal. /// /// Setting a value of `true` asserts the RTS control signal. `false` clears the signal. @@ -494,6 +513,12 @@ pub trait SerialPort: io::Read + io::Write { /// ``` fn reconfigure(&mut self, setup: &Fn(&mut SerialPortSettings) -> ::Result<()>) -> ::Result<()>; + /// Purges the send or receive queue. + /// + /// Clears any data that has been queued for sending or receiving. The data is discarded + /// without being sent or received. + fn purge(&mut self, queue: Queue) -> ::Result<()>; + /// Sets the state of the RTS (Request To Send) control signal. /// /// Setting a value of `true` asserts the RTS control signal. `false` clears the signal. @@ -602,6 +627,10 @@ impl SerialPort for T T::write_settings(self, &device_settings) } + fn purge(&mut self, queue: Queue) -> ::Result<()> { + T::purge(self, queue) + } + fn set_rts(&mut self, level: bool) -> ::Result<()> { T::set_rts(self, level) } diff --git a/serial-windows/src/com.rs b/serial-windows/src/com.rs index ba1b0cb..6c33080 100644 --- a/serial-windows/src/com.rs +++ b/serial-windows/src/com.rs @@ -183,6 +183,21 @@ impl SerialDevice for COMPort { Ok(()) } + fn purge(&mut self, queue: core::Queue) -> core::Result<()> { + use core::Queue::*; + + let flags = match queue { + Input => PURGE_RXCLEAR, + Output => PURGE_TXCLEAR, + Both => PURGE_RXCLEAR | PURGE_TXCLEAR, + }; + + match unsafe { PurgeComm(self.handle, flags) } { + 0 => Err(error::last_os_error()), + _ => Ok(()), + } + } + fn set_rts(&mut self, level: bool) -> core::Result<()> { if level { self.escape_comm_function(SETRTS) diff --git a/serial-windows/src/ffi.rs b/serial-windows/src/ffi.rs index c2fc98a..80b14cf 100644 --- a/serial-windows/src/ffi.rs +++ b/serial-windows/src/ffi.rs @@ -133,6 +133,10 @@ pub const MS_DSR_ON: DWORD = 0x0020; pub const MS_RING_ON: DWORD = 0x0040; pub const MS_RLSD_ON: DWORD = 0x0080; +// PurgeComm values +pub const PURGE_RXCLEAR: DWORD = 0x0008; +pub const PURGE_TXCLEAR: DWORD = 0x0004; + #[derive(Copy,Clone,Debug)] #[repr(C)] pub struct COMMTIMEOUTS { @@ -166,6 +170,7 @@ extern "system" { lpOverlapped: LPOVERLAPPED) -> BOOL; pub fn FlushFileBuffers(hFile: HANDLE) -> BOOL; + pub fn PurgeComm(hFile: HANDLE, dwFlags: DWORD) -> BOOL; pub fn GetCommState(hFile: HANDLE, lpDCB: *mut DCB) -> BOOL; pub fn SetCommState(hFile: HANDLE, lpDCB: *const DCB) -> BOOL;