in reverie-ptrace/src/gdbstub/commands/base/_vCont.rs [23:75]
fn parse(mut bytes: BytesMut) -> Option<Self> {
if bytes == b"?"[..] {
Some(vCont::Query)
} else if bytes.is_empty() {
None
} else {
let mut bytes = bytes.split_off(1);
// example packet: $vCont;s:p3e86d3.3e86d3;c:p3e86d3.-1#3b
// with prefix (`$vCont`) and checksum stripped.
let actions: Vec<(ResumeAction, ThreadId)> = bytes
.split_mut(|c| *c == b';')
.filter_map(|act| {
let mut iter = act.split_mut(|c| *c == b':');
let action = iter.next()?;
let thread_id = iter.next().and_then(|tid| ThreadId::decode(tid))?;
let action = if action.is_empty() {
None
} else {
match action[0] {
b'c' => Some(ResumeAction::Continue(None)),
b'C' => {
let sig = decode_hex::<i32>(&action[1..])
.ok()
.and_then(|s| Signal::try_from(s).ok())?;
Some(ResumeAction::Continue(Some(sig)))
}
b's' => Some(ResumeAction::Step(None)),
b'S' => {
let sig = decode_hex::<i32>(&action[1..])
.ok()
.and_then(|s| Signal::try_from(s).ok())?;
Some(ResumeAction::Step(Some(sig)))
}
b't' => Some(ResumeAction::Stop),
b'r' => {
let mut iter = action[1..].split_mut(|c| *c == b',');
let start: u64 = iter.next().and_then(|x| decode_hex(x).ok())?;
let end: u64 = iter.next().and_then(|x| decode_hex(x).ok())?;
Some(ResumeAction::StepUntil(start, end))
}
_ => None,
}
}?;
Some((action, thread_id))
})
.collect();
if actions.is_empty() {
None
} else {
Some(vCont::Actions(actions))
}
}
}