refactor(async): let read_by_hint() optionally accumulate unmatched bytes

The caller can then decide what to do.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
Marc-André Lureau
2024-08-19 06:44:15 -04:00
committed by Benoît Cortier
parent 46b703e813
commit 98e7dbab99
3 changed files with 17 additions and 6 deletions
+1 -1
View File
@@ -171,7 +171,7 @@ where
);
let pdu = framed
.read_by_hint(next_pdu_hint)
.read_by_hint(next_pdu_hint, None)
.await
.map_err(|e| ironrdp_connector::custom_err!("read frame by hint", e))?;
+15 -4
View File
@@ -164,14 +164,25 @@ where
/// `tokio::select!` statement and some other branch
/// completes first, then it is safe to drop the future and re-create it later.
/// Data may have been read, but it will be stored in the internal buffer.
pub async fn read_by_hint(&mut self, hint: &dyn PduHint) -> io::Result<Bytes> {
pub async fn read_by_hint(
&mut self,
hint: &dyn PduHint,
mut unmatched: Option<&mut Vec<Bytes>>,
) -> io::Result<Bytes> {
loop {
match hint
.find_size(self.peek())
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?
{
Some((_matched, length)) => {
return Ok(self.read_exact(length).await?.freeze());
Some((matched, length)) => {
let bytes = self.read_exact(length).await?.freeze();
if matched {
return Ok(bytes);
} else if let Some(ref mut unmatched) = unmatched {
unmatched.push(bytes);
} else {
warn!("Received and lost an unexpected PDU");
}
}
None => {
let len = self.read().await?;
@@ -246,7 +257,7 @@ where
);
let pdu = framed
.read_by_hint(next_pdu_hint)
.read_by_hint(next_pdu_hint, None)
.await
.map_err(|e| ironrdp_connector::custom_err!("read frame by hint", e))?;
+1 -1
View File
@@ -940,7 +940,7 @@ where
// RDCleanPath response
let rdcleanpath_res = framed
.read_by_hint(&RDCLEANPATH_HINT)
.read_by_hint(&RDCLEANPATH_HINT, None)
.await
.context("read RDCleanPath request")?;