mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-08-01 13:57:21 +00:00
Makes ZMODEM crate use BufRead
Using a buffered reader instead of the byte-at-a-time implementation avoids doing a syscall for each byte. Change-Id: Ia7bc42e4836593f358ff964962c910f8c94b6f8e GitOrigin-RevId: e70697d398b07d6de6f03d1d0a4b5204139bc59a
This commit is contained in:
parent
a91f8f7916
commit
c26d79fff8
@ -116,30 +116,6 @@ impl Read for &[u8] {
|
||||
}
|
||||
}
|
||||
|
||||
/// Forwarding implementation of Read for &mut
|
||||
impl<'a, T: ?Sized> Read for &'a mut T
|
||||
where
|
||||
T: Read,
|
||||
{
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||
(**self).read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
/// Forwarding implementation of Write for &mut
|
||||
impl<'a, T: ?Sized> Write for &'a mut T
|
||||
where
|
||||
T: Write,
|
||||
{
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
(**self).write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<()> {
|
||||
(**self).flush()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BufReader<R> {
|
||||
inner: R,
|
||||
buf: Box<[u8]>,
|
||||
@ -206,3 +182,41 @@ impl<R: Read> BufRead for BufReader<R> {
|
||||
self.pos = cmp::min(self.pos + amt, self.cap);
|
||||
}
|
||||
}
|
||||
|
||||
/// Forwarding implementation of Read for &mut
|
||||
impl<'a, T: ?Sized> Read for &'a mut T
|
||||
where
|
||||
T: Read,
|
||||
{
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||
(**self).read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
/// Forwarding implementation of BufRead for &mut
|
||||
impl<'a, T: ?Sized> BufRead for &'a mut T
|
||||
where
|
||||
T: BufRead,
|
||||
{
|
||||
fn fill_buf(&mut self) -> Result<&[u8]> {
|
||||
(**self).fill_buf()
|
||||
}
|
||||
|
||||
fn consume(&mut self, amt: usize) {
|
||||
(**self).consume(amt)
|
||||
}
|
||||
}
|
||||
|
||||
/// Forwarding implementation of Write for &mut
|
||||
impl<'a, T: ?Sized> Write for &'a mut T
|
||||
where
|
||||
T: Write,
|
||||
{
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
(**self).write(buf)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<()> {
|
||||
(**self).flush()
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ impl From<io::Error> for CommandError {
|
||||
}
|
||||
|
||||
/// Read-eval-print loop for the DebugConsole command line interface.
|
||||
pub fn repl(output: &mut dyn io::Write, input: &mut dyn io::Read) -> ! {
|
||||
pub fn repl<T: io::BufRead>(output: &mut dyn io::Write, input: &mut T) -> ! {
|
||||
let mut line_reader = LineReader::new();
|
||||
loop {
|
||||
const PROMPT: &str = "KATA> ";
|
||||
@ -84,7 +84,7 @@ pub fn repl(output: &mut dyn io::Write, input: &mut dyn io::Read) -> ! {
|
||||
///
|
||||
/// The line is split on whitespace. The first token is the command; the
|
||||
/// remaining tokens are the arguments.
|
||||
fn dispatch_command(cmdline: &str, input: &mut dyn io::Read, output: &mut dyn io::Write) {
|
||||
fn dispatch_command(cmdline: &str, input: &mut dyn io::BufRead, output: &mut dyn io::Write) {
|
||||
let mut args = cmdline.split_ascii_whitespace();
|
||||
match args.nth(0) {
|
||||
Some(command) => {
|
||||
@ -193,7 +193,7 @@ fn loglevel_command(
|
||||
|
||||
/// Implements a command to receive a blob using ZMODEM.
|
||||
fn rz_command(
|
||||
input: &mut dyn io::Read,
|
||||
input: &mut dyn io::BufRead,
|
||||
mut output: &mut dyn io::Write,
|
||||
) -> Result<(), CommandError> {
|
||||
let upload = rz::rz(input, &mut output)?;
|
||||
|
@ -43,7 +43,7 @@ impl io::Write for Upload {
|
||||
}
|
||||
|
||||
/// Receives using ZMODEM and wraps the result as an Upload.
|
||||
pub fn rz<R: io::Read, W: io::Write>(r: R, w: W) -> Result<Upload, io::Error> {
|
||||
pub fn rz<R: io::BufRead, W: io::Write>(r: R, w: W) -> Result<Upload, io::Error> {
|
||||
let mut upload = Upload::new();
|
||||
zmodem::recv::recv(r, w, &mut upload)?;
|
||||
Ok(upload)
|
||||
|
@ -106,37 +106,15 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Read into buf until and including the byte delim
|
||||
///
|
||||
/// This is a one-off implementation of a method of io::BufRead that the
|
||||
/// original lexxvir/zmodem had used. (So far kata_io is deferring implementing
|
||||
/// buffering to validate it will become needed in more places.)
|
||||
fn read_until<R>(r: &mut R, delim: u8, buf: &mut Vec<u8>) -> io::Result<usize>
|
||||
where
|
||||
R: io::Read,
|
||||
{
|
||||
let mut n = 0usize;
|
||||
loop {
|
||||
let b = read_byte(r)?;
|
||||
buf.push(b);
|
||||
n += 1;
|
||||
if b == delim {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(n)
|
||||
}
|
||||
|
||||
/// Receives sequence: <escaped data> ZLDE ZCRC* <CRC bytes>
|
||||
/// Unescapes sequencies such as 'ZLDE <escaped byte>'
|
||||
/// If Ok returns <unescaped data> in buf and ZCRC* byte as return value
|
||||
pub fn recv_zlde_frame<R>(header: u8, r: &mut R, buf: &mut Vec<u8>) -> io::Result<Option<u8>>
|
||||
where
|
||||
R: io::Read,
|
||||
R: io::BufRead,
|
||||
{
|
||||
loop {
|
||||
read_until(r, ZLDE, buf)?;
|
||||
r.read_until(ZLDE, buf)?;
|
||||
let b = read_byte(r)?;
|
||||
|
||||
if !is_escaped(b) {
|
||||
@ -173,7 +151,7 @@ pub fn recv_data<CI, CO, DO>(
|
||||
data_out: &mut DO,
|
||||
) -> io::Result<bool>
|
||||
where
|
||||
CI: io::Read,
|
||||
CI: io::BufRead,
|
||||
CO: io::Write,
|
||||
DO: io::Write,
|
||||
{
|
||||
|
@ -59,7 +59,7 @@ pub fn recv<CI, CO, DO>(
|
||||
mut data_out: DO,
|
||||
) -> io::Result<usize>
|
||||
where
|
||||
CI: io::Read,
|
||||
CI: io::BufRead,
|
||||
CO: io::Write,
|
||||
DO: io::Write,
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user