forked from M-Labs/nac3
add libio (to be shared between runtime and satman)
Reviewed-on: M-Labs/artiq-zynq#138 Co-authored-by: mwojcik <mw@m-labs.hk> Co-committed-by: mwojcik <mw@m-labs.hk>
This commit is contained in:
parent
35250b3f56
commit
d7f45d473e
|
@ -0,0 +1,17 @@
|
||||||
|
[package]
|
||||||
|
authors = ["M-Labs"]
|
||||||
|
name = "io"
|
||||||
|
version = "0.0.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "io"
|
||||||
|
path = "lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
core_io = { version = "0.1", features = ["collections"] }
|
||||||
|
byteorder = { version = "1.0", default-features = false, optional = true }
|
||||||
|
|
||||||
|
libsupport_zynq = { default-features = false, features = ["alloc_core"], git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
alloc = []
|
|
@ -0,0 +1,81 @@
|
||||||
|
use core_io::{Read, Write, Error as IoError};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Cursor<T> {
|
||||||
|
inner: T,
|
||||||
|
pos: usize
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Cursor<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(inner: T) -> Cursor<T> {
|
||||||
|
Cursor { inner, pos: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn into_inner(self) -> T {
|
||||||
|
self.inner
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn get_ref(&self) -> &T {
|
||||||
|
&self.inner
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn get_mut(&mut self) -> &mut T {
|
||||||
|
&mut self.inner
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn position(&self) -> usize {
|
||||||
|
self.pos
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_position(&mut self, pos: usize) {
|
||||||
|
self.pos = pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsRef<[u8]>> Read for Cursor<T> {
|
||||||
|
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, IoError> {
|
||||||
|
let data = &self.inner.as_ref()[self.pos..];
|
||||||
|
let len = buf.len().min(data.len());
|
||||||
|
buf[..len].copy_from_slice(&data[..len]);
|
||||||
|
self.pos += len;
|
||||||
|
Ok(len)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Write for Cursor<&mut [u8]> {
|
||||||
|
|
||||||
|
fn write(&mut self, buf: &[u8]) -> Result<usize, IoError> {
|
||||||
|
let data = &mut self.inner[self.pos..];
|
||||||
|
let len = buf.len().min(data.len());
|
||||||
|
data[..len].copy_from_slice(&buf[..len]);
|
||||||
|
self.pos += len;
|
||||||
|
Ok(len)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn flush(&mut self) -> Result<(), IoError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
impl Write for Cursor<::alloc::Vec<u8>> {
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write(&mut self, buf: &[u8]) -> Result<usize, IoError> {
|
||||||
|
self.inner.extend_from_slice(buf);
|
||||||
|
Ok(buf.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn flush(&mut self) -> Result<(), IoError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#![no_std]
|
||||||
|
#![feature(never_type)]
|
||||||
|
#![cfg_attr(feature = "alloc", feature(alloc))]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
extern crate core_io;
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
#[macro_use]
|
||||||
|
use alloc;
|
||||||
|
#[cfg(feature = "byteorder")]
|
||||||
|
extern crate byteorder;
|
||||||
|
|
||||||
|
pub mod cursor;
|
||||||
|
#[cfg(feature = "byteorder")]
|
||||||
|
pub mod proto;
|
||||||
|
|
||||||
|
pub use cursor::Cursor;
|
||||||
|
#[cfg(feature = "byteorder")]
|
||||||
|
pub use proto::{ProtoRead, ProtoWrite};
|
||||||
|
#[cfg(all(feature = "byteorder", feature = "alloc"))]
|
||||||
|
pub use proto::ReadStringError;
|
|
@ -0,0 +1,158 @@
|
||||||
|
use core::str::Utf8Error;
|
||||||
|
use byteorder::{ByteOrder, NativeEndian};
|
||||||
|
use alloc::vec;
|
||||||
|
use alloc::string::String;
|
||||||
|
|
||||||
|
use core_io::{Read, Write, Error as IoError};
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum ReadStringError<T> {
|
||||||
|
Utf8(Utf8Error),
|
||||||
|
Other(T)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ProtoRead {
|
||||||
|
type ReadError;
|
||||||
|
|
||||||
|
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::ReadError>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn read_u8(&mut self) -> Result<u8, Self::ReadError> {
|
||||||
|
let mut bytes = [0; 1];
|
||||||
|
self.read_exact(&mut bytes)?;
|
||||||
|
Ok(bytes[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn read_u16(&mut self) -> Result<u16, Self::ReadError> {
|
||||||
|
let mut bytes = [0; 2];
|
||||||
|
self.read_exact(&mut bytes)?;
|
||||||
|
Ok(NativeEndian::read_u16(&bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn read_u32(&mut self) -> Result<u32, Self::ReadError> {
|
||||||
|
let mut bytes = [0; 4];
|
||||||
|
self.read_exact(&mut bytes)?;
|
||||||
|
Ok(NativeEndian::read_u32(&bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn read_u64(&mut self) -> Result<u64, Self::ReadError> {
|
||||||
|
let mut bytes = [0; 8];
|
||||||
|
self.read_exact(&mut bytes)?;
|
||||||
|
Ok(NativeEndian::read_u64(&bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn read_bool(&mut self) -> Result<bool, Self::ReadError> {
|
||||||
|
Ok(self.read_u8()? != 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn read_bytes(&mut self) -> Result<::alloc::vec::Vec<u8>, Self::ReadError> {
|
||||||
|
let length = self.read_u32()?;
|
||||||
|
let mut value = vec![0; length as usize];
|
||||||
|
self.read_exact(&mut value)?;
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn read_string(&mut self) -> Result<::alloc::string::String, ReadStringError<Self::ReadError>> {
|
||||||
|
let bytes = self.read_bytes().map_err(ReadStringError::Other)?;
|
||||||
|
String::from_utf8(bytes).map_err(|err| ReadStringError::Utf8(err.utf8_error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ProtoWrite {
|
||||||
|
type WriteError;
|
||||||
|
|
||||||
|
fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::WriteError>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_u8(&mut self, value: u8) -> Result<(), Self::WriteError> {
|
||||||
|
let bytes = [value; 1];
|
||||||
|
self.write_all(&bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_i8(&mut self, value: i8) -> Result<(), Self::WriteError> {
|
||||||
|
let bytes = [value as u8; 1];
|
||||||
|
self.write_all(&bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_u16(&mut self, value: u16) -> Result<(), Self::WriteError> {
|
||||||
|
let mut bytes = [0; 2];
|
||||||
|
NativeEndian::write_u16(&mut bytes, value);
|
||||||
|
self.write_all(&bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_i16(&mut self, value: i16) -> Result<(), Self::WriteError> {
|
||||||
|
let mut bytes = [0; 2];
|
||||||
|
NativeEndian::write_i16(&mut bytes, value);
|
||||||
|
self.write_all(&bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_u32(&mut self, value: u32) -> Result<(), Self::WriteError> {
|
||||||
|
let mut bytes = [0; 4];
|
||||||
|
NativeEndian::write_u32(&mut bytes, value);
|
||||||
|
self.write_all(&bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_i32(&mut self, value: i32) -> Result<(), Self::WriteError> {
|
||||||
|
let mut bytes = [0; 4];
|
||||||
|
NativeEndian::write_i32(&mut bytes, value);
|
||||||
|
self.write_all(&bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_u64(&mut self, value: u64) -> Result<(), Self::WriteError> {
|
||||||
|
let mut bytes = [0; 8];
|
||||||
|
NativeEndian::write_u64(&mut bytes, value);
|
||||||
|
self.write_all(&bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_i64(&mut self, value: i64) -> Result<(), Self::WriteError> {
|
||||||
|
let mut bytes = [0; 8];
|
||||||
|
NativeEndian::write_i64(&mut bytes, value);
|
||||||
|
self.write_all(&bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_bool(&mut self, value: bool) -> Result<(), Self::WriteError> {
|
||||||
|
self.write_u8(value as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_bytes(&mut self, value: &[u8]) -> Result<(), Self::WriteError> {
|
||||||
|
self.write_u32(value.len() as u32)?;
|
||||||
|
self.write_all(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_string(&mut self, value: &str) -> Result<(), Self::WriteError> {
|
||||||
|
self.write_bytes(value.as_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ProtoRead for T where T: Read + ?Sized {
|
||||||
|
type ReadError = IoError;
|
||||||
|
|
||||||
|
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Self::ReadError> {
|
||||||
|
T::read_exact(self, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ProtoWrite for T where T: Write + ?Sized {
|
||||||
|
type WriteError = IoError;
|
||||||
|
|
||||||
|
fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::WriteError> {
|
||||||
|
T::write_all(self, buf)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue