Skip to content

Commit

Permalink
Split opauqe_*() functions into sos_*(), pm_*(), apc_*().
Browse files Browse the repository at this point in the history
Split the `opaque_[start|put|end]()` set of functions into 3 different
sets of functions for SOS, PM and APC sequences.
  • Loading branch information
boazy committed Oct 17, 2024
1 parent 790e34e commit cbbdde3
Showing 1 changed file with 158 additions and 28 deletions.
186 changes: 158 additions & 28 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub struct Parser<const OSC_RAW_BUF_SIZE: usize = MAX_OSC_RAW> {
osc_num_params: usize,
ignoring: bool,
utf8_parser: utf8::Parser,
opaque_sequence_kind: Option<OpaqueSequenceKind>,
}

impl Parser {
Expand Down Expand Up @@ -385,10 +386,34 @@ impl<const OSC_RAW_BUF_SIZE: usize> Parser<OSC_RAW_BUF_SIZE> {
// byte value, this branch is unreachable.
_ => unreachable!("invalid opaque sequence kind"),
};
performer.opaque_start(kind)
self.opaque_sequence_kind = Some(kind);
match kind {
OpaqueSequenceKind::Sos => performer.sos_start(),
OpaqueSequenceKind::Pm => performer.pm_start(),
OpaqueSequenceKind::Apc => performer.apc_start(),
}
},
Action::OpaquePut => {
match self.opaque_sequence_kind {
Some(OpaqueSequenceKind::Sos) => performer.sos_put(byte),
Some(OpaqueSequenceKind::Pm) => performer.pm_put(byte),
Some(OpaqueSequenceKind::Apc) => performer.apc_put(byte),
// This action is only triggered inside the OpaqueString state, which requires
// that the opaque_sequence_kind is set to a Some(x) value.
None => unreachable!("opaque sequence kind not set"),
}
},
Action::OpaqueEnd => {
match self.opaque_sequence_kind {
Some(OpaqueSequenceKind::Sos) => performer.sos_end(),
Some(OpaqueSequenceKind::Pm) => performer.pm_end(),
Some(OpaqueSequenceKind::Apc) => performer.apc_end(),
// This action is only triggered inside the OpaqueString state, which requires
// that the opaque_sequence_kind is set to a Some(x) value.
None => unreachable!("opaque sequence kind not set"),
}
self.opaque_sequence_kind = None;
},
Action::OpaquePut => performer.opaque_put(byte),
Action::OpaqueEnd => performer.opaque_end(),
}
}
}
Expand Down Expand Up @@ -454,19 +479,41 @@ pub trait Perform {
/// subsequent characters were ignored.
fn esc_dispatch(&mut self, _intermediates: &[u8], _ignore: bool, _byte: u8) {}

/// The start of an opaque sequence (SOS, PM or APC) has been detected.
/// The start of an SOS sequence has been detected.
///
/// The `kind` parameter indicates the type of sequence that was started.
/// Until the SOS sequence ends (at which point `sos_end` will be called), invalid
/// characters will be ignored while valid characters will be passed on to `sos_put`.
fn sos_start(&mut self) {}

/// A byte has been received as part of an ongoing SOS sequence.
fn sos_put(&mut self, _byte: u8) {}

/// We've reached the end of the ongoing SOS sequence.
fn sos_end(&mut self) {}

/// The start of a PM sequence has been detected.
///
/// Until the PM sequence ends (at which point `pm_end` will be called), invalid
/// characters will be ignored while valid characters will be passed on to `pm_put`.
fn pm_start(&mut self) {}

/// A byte has been received as part of an ongoing PM sequence.
fn pm_put(&mut self, _byte: u8) {}

/// We've reached the end of the ongoing PM sequence.
fn pm_end(&mut self) {}

/// The start of an APC sequence has been detected.
///
/// Until the opaque sequence ends (at which point `opaque_end` will be called), invalid
/// characters will be ignored while valid characters will be passed on to `opaque_put`.
fn opaque_start(&mut self, _kind: OpaqueSequenceKind) {}
/// Until the APC sequence ends (at which point `apc_end` will be called), invalid
/// characters will be ignored while valid characters will be passed on to `apc_put`.
fn apc_start(&mut self) {}

/// We've reached the end of the ongoing opaque sequence (SOS, PM or APC).
fn opaque_end(&mut self) {}
/// A byte has been received as part of an ongoing APC sequence.
fn apc_put(&mut self, _byte: u8) {}

/// A byte has been received as part of an ongoing opaque sequence.
fn opaque_put(&mut self, _byte: u8) {}
/// We've reached the end of the ongoing APC sequence.
fn apc_end(&mut self) {}
}

#[cfg(all(test, feature = "no_std"))]
Expand Down Expand Up @@ -499,9 +546,15 @@ mod tests {
DcsHook(Vec<Vec<u16>>, Vec<u8>, bool, char),
DcsPut(u8),
DcsUnhook,
OpaqueStart(OpaqueSequenceKind),
OpaquePut(u8),
OpaqueEnd,
SosStart,
SosPut(u8),
SosEnd,
PmStart,
PmPut(u8),
PmEnd,
ApcStart,
ApcPut(u8),
ApcEnd,
}

impl Perform for Dispatcher {
Expand Down Expand Up @@ -535,16 +588,40 @@ mod tests {
self.dispatched.push(Sequence::DcsUnhook);
}

fn opaque_start(&mut self, _kind: OpaqueSequenceKind) {
self.dispatched.push(Sequence::OpaqueStart(_kind));
fn sos_start(&mut self) {
self.dispatched.push(Sequence::SosStart);
}

fn opaque_put(&mut self, byte: u8) {
self.dispatched.push(Sequence::OpaquePut(byte));
fn sos_put(&mut self, byte: u8) {
self.dispatched.push(Sequence::SosPut(byte));
}

fn opaque_end(&mut self) {
self.dispatched.push(Sequence::OpaqueEnd);
fn sos_end(&mut self) {
self.dispatched.push(Sequence::SosEnd);
}

fn pm_start(&mut self) {
self.dispatched.push(Sequence::PmStart);
}

fn pm_put(&mut self, byte: u8) {
self.dispatched.push(Sequence::PmPut(byte));
}

fn pm_end(&mut self) {
self.dispatched.push(Sequence::PmEnd);
}

fn apc_start(&mut self) {
self.dispatched.push(Sequence::ApcStart);
}

fn apc_put(&mut self, byte: u8) {
self.dispatched.push(Sequence::ApcPut(byte));
}

fn apc_end(&mut self) {
self.dispatched.push(Sequence::ApcEnd);
}
}

Expand Down Expand Up @@ -682,6 +759,56 @@ mod tests {
}
}

#[test]
fn parse_sos() {
const INPUT: &[u8] = b"\x1bXabc\x1b\\";

// Test with ESC \ terminator.

let mut dispatcher = Dispatcher::default();
let mut parser = Parser::new();

for byte in INPUT {
parser.advance(&mut dispatcher, *byte);
}
assert_eq!(dispatcher.dispatched.len(), 6);
assert_eq!(
dispatcher.dispatched[0..5],
vec![
Sequence::SosStart,
Sequence::SosPut(b'a'),
Sequence::SosPut(b'b'),
Sequence::SosPut(b'c'),
Sequence::SosEnd,
]
)
}

#[test]
fn parse_pm() {
const INPUT: &[u8] = b"\x1b^abc\x1b\\";

// Test with ESC \ terminator.

let mut dispatcher = Dispatcher::default();
let mut parser = Parser::new();

for byte in INPUT {
parser.advance(&mut dispatcher, *byte);
}
assert_eq!(dispatcher.dispatched.len(), 6);
assert_eq!(
dispatcher.dispatched[0..5],
vec![
Sequence::PmStart,
Sequence::PmPut(b'a'),
Sequence::PmPut(b'b'),
Sequence::PmPut(b'c'),
Sequence::PmEnd,
]
)
}

#[test]
fn parse_apc() {
const INPUT: &[u8] = b"\x1b_abc\x1b\\";
Expand All @@ -695,13 +822,16 @@ mod tests {
parser.advance(&mut dispatcher, *byte);
}
assert_eq!(dispatcher.dispatched.len(), 6);
assert_eq!(dispatcher.dispatched[0..5], vec![
Sequence::OpaqueStart(OpaqueSequenceKind::Apc),
Sequence::OpaquePut(b'a'),
Sequence::OpaquePut(b'b'),
Sequence::OpaquePut(b'c'),
Sequence::OpaqueEnd,
])
assert_eq!(
dispatcher.dispatched[0..5],
vec![
Sequence::ApcStart,
Sequence::ApcPut(b'a'),
Sequence::ApcPut(b'b'),
Sequence::ApcPut(b'c'),
Sequence::ApcEnd,
]
)
}

#[test]
Expand Down

0 comments on commit cbbdde3

Please sign in to comment.