Skip to content

Commit

Permalink
no_std
Browse files Browse the repository at this point in the history
  • Loading branch information
pftbest committed Oct 8, 2017
1 parent 6b80e7c commit 05649f4
Show file tree
Hide file tree
Showing 22 changed files with 2,393 additions and 37 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[workspace]
members = [
"nostd",
"num-traits",
"rmp",
"rmp-serde",
"rmp-serialize",
Expand Down
17 changes: 17 additions & 0 deletions nostd/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "nostd"
version = "0.1.0"
authors = ["Vadzim Dambrouski <pftbest@gmail.com>"]

[dependencies.byteorder]
version = "1"
default-features = false

[dependencies.arrayvec]
version = "0.4"
default-features = false

[features]
default = []
# this feature is used for tests `cargo test --features=std`
std = []
17 changes: 17 additions & 0 deletions nostd/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use core::fmt::{Debug, Display};
use core::str::Utf8Error;

pub trait Error: Debug + Display {
fn description(&self) -> &str;
fn cause(&self) -> Option<&Error> { None }
}

impl Error for Utf8Error {
fn description(&self) -> &str {
"Utf8Error"
}

fn cause(&self) -> Option<&Error> {
None
}
}
31 changes: 31 additions & 0 deletions nostd/src/io/cursor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use core::cmp;
use io::{Read, Result};

#[derive(Clone, Debug)]
pub struct Cursor<T> {
inner: T,
pos: u64,
}

impl<T> Cursor<T> {
pub fn new(inner: T) -> Cursor<T> {
Cursor { pos: 0, inner: inner }
}

pub fn position(&self) -> u64 { self.pos }
}

impl<T> Cursor<T> where T: AsRef<[u8]> {
fn fill_buf(&mut self) -> Result<&[u8]> {
let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64);
Ok(&self.inner.as_ref()[(amt as usize)..])
}
}

impl<T> Read for Cursor<T> where T: AsRef<[u8]> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let n = Read::read(&mut self.fill_buf()?, buf)?;
self.pos += n as u64;
Ok(n)
}
}
41 changes: 41 additions & 0 deletions nostd/src/io/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use core::{result, fmt};
use core::fmt::{Display, Formatter};
use error;

pub type Result<T> = result::Result<T, Error>;

#[derive(Debug)]
pub struct Error {
reason: &'static str,
}

impl Error {
pub fn new(reason: &'static str) -> Self {
Error {
reason: reason,
}
}
}

impl error::Error for Error {
fn description(&self) -> &str {
self.reason
}

fn cause(&self) -> Option<&error::Error> {
None
}
}

impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> result::Result<(), fmt::Error> {
error::Error::description(self).fmt(f)
}
}

#[cfg(feature = "std")]
impl From<::std::io::Error> for Error {
fn from(_err: ::std::io::Error) -> Self {
return ::io::Error { reason: "IO Error" };
}
}
9 changes: 9 additions & 0 deletions nostd/src/io/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
mod read;
mod write;
mod error;
mod cursor;

pub use self::read::Read;
pub use self::write::Write;
pub use self::error::{Error, Result};
pub use self::cursor::Cursor;
77 changes: 77 additions & 0 deletions nostd/src/io/read.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use core::cmp;
use io::{Error, Result};

pub trait Read {
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
while !buf.is_empty() {
match self.read(buf) {
Ok(0) => break,
Ok(n) => { let tmp = buf; buf = &mut tmp[n..]; }
Err(e) => return Err(e),
}
}
if !buf.is_empty() {
Err(Error::new("failed to fill whole buffer"))
} else {
Ok(())
}
}
}

impl<'a, R: Read + ?Sized> Read for &'a mut R {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
(**self).read(buf)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
(**self).read_exact(buf)
}
}

impl<'a> Read for &'a [u8] {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let amt = cmp::min(buf.len(), self.len());
let (a, b) = self.split_at(amt);

// First check if the amount of bytes we want to read is small:
// `copy_from_slice` will generally expand to a call to `memcpy`, and
// for a single byte the overhead is significant.
if amt == 1 {
buf[0] = a[0];
} else {
buf[..amt].copy_from_slice(a);
}

*self = b;
Ok(amt)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
if buf.len() > self.len() {
return Err(Error::new("failed to fill whole buffer"));
}
let (a, b) = self.split_at(buf.len());

// First check if the amount of bytes we want to read is small:
// `copy_from_slice` will generally expand to a call to `memcpy`, and
// for a single byte the overhead is significant.
if buf.len() == 1 {
buf[0] = a[0];
} else {
buf.copy_from_slice(a);
}

*self = b;
Ok(())
}
}

#[cfg(feature = "std")]
impl<T> Read for ::std::io::Cursor<T> where T: AsRef<[u8]> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
::std::io::Read::read(self, buf).map_err(Into::into)
}
}
50 changes: 50 additions & 0 deletions nostd/src/io/write.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use core::{mem, cmp};
use io::{Result, Error};

pub trait Write {
fn write(&mut self, buf: &[u8]) -> Result<usize>;
fn write_all(&mut self, buf: &[u8]) -> Result<()>;
}

impl<'a, W: Write + ?Sized> Write for &'a mut W {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize> {
(**self).write(buf)
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
(**self).write_all(buf)
}
}

impl<'a> Write for &'a mut [u8] {
#[inline]
fn write(&mut self, data: &[u8]) -> Result<usize> {
let amt = cmp::min(data.len(), self.len());
let (a, b) = mem::replace(self, &mut []).split_at_mut(amt);
a.copy_from_slice(&data[..amt]);
*self = b;
Ok(amt)
}

#[inline]
fn write_all(&mut self, data: &[u8]) -> Result<()> {
if self.write(data)? == data.len() {
Ok(())
} else {
Err(Error::new("failed to write whole buffer"))
}
}
}

#[cfg(feature = "std")]
impl Write for ::std::vec::Vec<u8> {
fn write(&mut self, data: &[u8]) -> Result<usize> {
self.extend_from_slice(data);
Ok(data.len())
}
fn write_all(&mut self, data: &[u8]) -> Result<()> {
self.extend_from_slice(data);
Ok(())
}
}
Loading

0 comments on commit 05649f4

Please sign in to comment.