parent
35250b3f56
commit
23bb185644
@ -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