firmware: migrate session_proto to new libio.

This commit is contained in:
whitequark 2018-05-14 13:33:38 +00:00
parent e9c88e32e6
commit 09617c9f5e
6 changed files with 75 additions and 24 deletions

View File

@ -190,7 +190,7 @@ impl Write for Cursor<::alloc::Vec<u8>> {
}
#[cfg(feature = "std_artiq")]
impl<T> Read for T where T: std_artiq::io::Read {
impl<T> Read for T where T: std_artiq::io::Read + ?Sized {
type ReadError = std_artiq::io::Error;
fn read(&mut self, buf: &mut [u8]) -> result::Result<usize, Self::ReadError> {
@ -199,7 +199,7 @@ impl<T> Read for T where T: std_artiq::io::Read {
}
#[cfg(feature = "std_artiq")]
impl<T> Write for T where T: std_artiq::io::Write {
impl<T> Write for T where T: std_artiq::io::Write + ?Sized {
type WriteError = std_artiq::io::Error;
type FlushError = std_artiq::io::Error;

View File

@ -1,7 +1,50 @@
use core::fmt;
use alloc::string;
use byteorder::{ByteOrder, NetworkEndian};
use ::{Read, Write, Error as IoError};
#[derive(Debug)]
pub enum ReadStringError<T> {
Utf8Error(string::FromUtf8Error),
Other(T)
}
impl<T: fmt::Display> fmt::Display for ReadStringError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&ReadStringError::Utf8Error(ref err) =>
write!(f, "invalid UTF-8 ({})", err),
&ReadStringError::Other(ref err) =>
write!(f, "{}", err)
}
}
}
impl<T> From<ReadStringError<IoError<T>>> for IoError<T>
{
fn from(value: ReadStringError<IoError<T>>) -> IoError<T> {
match value {
ReadStringError::Utf8Error(_) => IoError::Unrecognized,
ReadStringError::Other(err) => err
}
}
}
#[cfg(feature = "std_artiq")]
impl<T> From<ReadStringError<T>> for ::std_artiq::io::Error
where T: Into<::std_artiq::io::Error>
{
fn from(value: ReadStringError<T>) -> ::std_artiq::io::Error {
match value {
ReadStringError::Utf8Error(_) =>
::std_artiq::io::Error::new(::std_artiq::io::ErrorKind::InvalidData,
"invalid UTF-8"),
ReadStringError::Other(err) => err.into()
}
}
}
pub trait ProtoRead {
type ReadError;
@ -49,11 +92,18 @@ pub trait ProtoRead {
Ok(value)
}
// fn read_string(&mut self) -> Result<String, Self::ReadError> {
// let bytes = self.read_bytes()?;
// String::from_utf8(bytes)
// .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "invalid UTF-8"))
// }
#[cfg(feature = "alloc")]
#[inline]
fn read_string(&mut self) -> Result<::alloc::String, ReadStringError<Self::ReadError>> {
match self.read_bytes() {
Ok(bytes) =>
match ::alloc::String::from_utf8(bytes) {
Ok(string) => Ok(string),
Err(err) => Err(ReadStringError::Utf8Error(err))
},
Err(err) => Err(ReadStringError::Other(err))
}
}
}
pub trait ProtoWrite {
@ -132,7 +182,7 @@ pub trait ProtoWrite {
}
}
impl<T> ProtoRead for T where T: Read {
impl<T> ProtoRead for T where T: Read + ?Sized {
type ReadError = IoError<T::ReadError>;
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::ReadError> {
@ -140,7 +190,7 @@ impl<T> ProtoRead for T where T: Read {
}
}
impl<T> ProtoWrite for T where T: Write {
impl<T> ProtoWrite for T where T: Write + ?Sized {
type WriteError = IoError<T::WriteError>;
fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::WriteError> {

View File

@ -41,9 +41,9 @@ pub enum Reply<'a> {
}
impl Request {
pub fn read_from<T: Read>(reader: &mut T) -> Result<Self, T::ReadError> {
pub fn read_from<T: Read + ?Sized>(reader: &mut T) -> Result<Self, T::ReadError> {
#[cfg(feature = "log")]
fn read_log_level_filter<T: Read>(reader: &mut T) ->
fn read_log_level_filter<T: Read + ?Sized>(reader: &mut T) ->
Result<log::LevelFilter, T::ReadError> {
Ok(match reader.read_u8()? {
0 => log::LevelFilter::Off,
@ -80,7 +80,7 @@ impl Request {
}
impl<'a> Reply<'a> {
pub fn write_to<T: Write>(&self, writer: &mut T) -> Result<(), T::WriteError> {
pub fn write_to<T: Write + ?Sized>(&self, writer: &mut T) -> Result<(), T::WriteError> {
match *self {
Reply::Success => {
writer.write_u8(1)?;

View File

@ -15,7 +15,7 @@ pub enum DeviceMessage {
}
impl HostMessage {
pub fn read_from<T: Read>(reader: &mut T) -> Result<Self, T::ReadError> {
pub fn read_from<T: Read + ?Sized>(reader: &mut T) -> Result<Self, T::ReadError> {
Ok(match reader.read_u8()? {
0 => HostMessage::Monitor {
enable: if reader.read_u8()? == 0 { false } else { true },
@ -37,7 +37,7 @@ impl HostMessage {
}
impl DeviceMessage {
pub fn write_to<T: Write>(&self, writer: &mut T) -> Result<(), T::WriteError> {
pub fn write_to<T: Write + ?Sized>(&self, writer: &mut T) -> Result<(), T::WriteError> {
match *self {
DeviceMessage::MonitorStatus { channel, probe, value } => {
writer.write_u8(0)?;

View File

@ -1,9 +1,10 @@
use std::io::{self, Read, Write};
use std::vec::Vec;
use std::string::String;
use {ReadExt, WriteExt};
use alloc::vec::Vec;
use alloc::string::String;
fn read_sync(reader: &mut Read) -> io::Result<()> {
use io::{Read, Write, Error, Result};
use io::proto::{ProtoRead, ProtoWrite};
fn read_sync<T: Read + ?Sized>(reader: &mut T) -> Result<(), T::ReadError> {
let mut sync = [0; 4];
for i in 0.. {
sync[i % 4] = reader.read_u8()?;
@ -12,7 +13,7 @@ fn read_sync(reader: &mut Read) -> io::Result<()> {
Ok(())
}
fn write_sync(writer: &mut Write) -> io::Result<()> {
fn write_sync<T: Write + ?Sized>(writer: &mut T) -> Result<(), T::WriteError> {
writer.write_all(&[0x5a; 4])
}
@ -42,7 +43,7 @@ pub enum Request {
}
impl Request {
pub fn read_from(reader: &mut Read) -> io::Result<Request> {
pub fn read_from<T: Read + ?Sized>(reader: &mut T) -> Result<Self, T::ReadError> {
read_sync(reader)?;
Ok(match reader.read_u8()? {
3 => Request::SystemInfo,
@ -74,7 +75,7 @@ impl Request {
12 => Request::FlashRemove {
key: reader.read_string()?
},
_ => return Err(io::Error::new(io::ErrorKind::InvalidData, "unknown request type"))
_ => return Err(Error::Unrecognized)
})
}
}
@ -115,7 +116,7 @@ pub enum Reply<'a> {
}
impl<'a> Reply<'a> {
pub fn write_to(&self, writer: &mut Write) -> io::Result<()> {
pub fn write_to<T: Write + ?Sized>(&self, writer: &mut T) -> Result<(), T::WriteError> {
write_sync(writer)?;
match *self {
Reply::SystemInfo { ident, finished_cleanly } => {

View File

@ -127,7 +127,7 @@ fn host_read(stream: &mut TcpStream) -> io::Result<host::Request> {
fn host_write(stream: &mut Write, reply: host::Reply) -> io::Result<()> {
debug!("comm->host {:?}", reply);
reply.write_to(stream)
Ok(reply.write_to(stream)?)
}
pub fn kern_send(io: &Io, request: &kern::Message) -> io::Result<()> {