android_usb_serial/
xonxoff.rs1use crate::config::{CHAR_XOFF, CHAR_XON};
4
5#[derive(Debug, Clone, Default)]
6pub struct XonXoffFilter {
7 pub enabled: bool,
8 pub paused: bool,
9}
10
11impl XonXoffFilter {
12 pub fn new(enabled: bool) -> Self {
13 Self {
14 enabled,
15 paused: false,
16 }
17 }
18
19 pub fn filter(&mut self, input: &[u8]) -> Vec<u8> {
21 if !self.enabled {
22 return input.to_vec();
23 }
24 let ctrl_count = input
25 .iter()
26 .filter(|&&b| b == CHAR_XON || b == CHAR_XOFF)
27 .count();
28 if ctrl_count == 0 {
29 return input.to_vec();
30 }
31 let mut out = Vec::with_capacity(input.len().saturating_sub(ctrl_count));
32 for &b in input {
33 match b {
34 CHAR_XON => self.paused = false,
35 CHAR_XOFF => self.paused = true,
36 _ => out.push(b),
37 }
38 }
39 out
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn filters_between_xoff_and_xon() {
49 let mut f = XonXoffFilter::new(true);
50 let out = f.filter(&[b'a', CHAR_XOFF, b'b', CHAR_XON, b'c']);
51 assert_eq!(out, vec![b'a', b'b', b'c']);
52 }
53}