#![feature(non_ascii_idents)]
#![cfg_attr(test, feature(plugin))]
#![no_std]
#![cfg_attr(test, plugin(quickcheck_macros))]
#![deny(missing_debug_implementations)]
extern crate containers;
extern crate either;
extern crate loca;
extern crate void;
#[cfg(test)] extern crate quickcheck;
#[cfg(test)] extern crate rand;
#[cfg(test)] extern crate std;
use containers::collections::Vec;
use core::cmp::max;
use core::convert::From;
use core::marker::PhantomData;
use core::mem::MaybeUninit as MU;
use core::ops::*;
use either::Either::{self, *};
use loca::Alloc;
use void::Void;
mod pos;
pub use pos::Pos;
mod util;
#[derive(Debug)] pub struct EndOfFile;
#[derive(Debug)] pub struct NoMemory;
pub trait TryRead<T: Copy> {
type Err;
#[inline]
fn try_read(&mut self, buf: &mut [T]) -> Result<Result<usize, EndOfFile>, Self::Err> { self.try_readv(&mut [buf]) }
#[inline]
fn try_readv(&mut self, bufs: &mut [&mut [T]]) -> Result<Result<usize, EndOfFile>, Self::Err> {
for buf in bufs { if buf.len() > 0 { return self.try_read(buf) } }
Ok(Ok(0))
}
}
pub trait Read<T: Copy> {
type Err;
#[inline]
fn read(&mut self, buf: &mut [T]) -> Result<usize, Self::Err> { self.readv(&mut [buf]) }
#[inline]
fn readv(&mut self, bufs: &mut [&mut [T]]) -> Result<usize, Self::Err> {
for buf in bufs { if buf.len() > 0 { return self.read(buf) } }
Ok(0)
}
#[inline]
fn try_read_full(&mut self, buf: &mut [T]) -> Result<usize, (Self::Err, usize)> {
let mut n = 0;
while let Some(buf) = buf.get_mut(n..) {
match self.read(buf) {
Err(e) => return Err((e, n)),
Ok(0) => break,
Ok(m) => n += m,
}
}
Ok(n)
}
#[inline]
fn read_full<E: From<Self::Err> + From<EndOfFile>>(&mut self, buf: &mut [T]) -> Result<(), (E, usize)> {
match self.try_read_full(buf) {
Err((e, n)) => Err((E::from(e), n)),
Ok(n) => if n < buf.len() { Err((E::from(EndOfFile), n)) } else { Ok(()) },
}
}
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { (0, None) }
#[inline] fn data(self) -> Data<Self, T> where Self: Sized { Data(PhantomData, self) }
#[inline]
fn read_onto_vec<A: Alloc>(&mut self, xs: &mut Vec<T, A>) -> Result<usize, Self::Err> {
let l = xs.len();
let m = self.read(unsafe { &mut xs.storage_mut()[l..] })?;
unsafe { xs.set_length(l+m) };
Ok(m)
}
#[inline]
fn split<P: FnMut(T) -> bool, E: From<Self::Err> + From<NoMemory>>(self, p: P, keep_delim: bool) -> Split<Self, T, P, E> where Self: Sized {
Split{ φ: PhantomData, r: self, p, buf: Some(Vec::new()), keep_delim }
}
}
pub trait PosRead<T: Copy>: Read<T> {
#[inline]
fn pread(&mut self, buf: &mut [T], pos: usize) -> Result<usize, Self::Err> { self.preadv(&mut [buf], pos) }
#[inline]
fn preadv(&mut self, bufs: &mut [&mut [T]], pos: usize) -> Result<usize, Self::Err> {
for buf in bufs { if buf.len() > 0 { return self.pread(buf, pos) } }
Ok(0)
}
#[inline]
fn pread_full<E: From<Self::Err> + From<EndOfFile>>(&mut self, buf: &mut [T], mut pos: usize) -> Result<(), (E, usize)> {
let mut n = 0;
while let Some(buf) = buf.get_mut(n..) {
match self.pread(buf, pos) {
Err(e) => return Err((E::from(e), n)),
Ok(0) => return Err((E::from(EndOfFile), n)),
Ok(m) => {
n += m;
pos += m;
},
}
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Data<R: Read<T>, T: Copy>(PhantomData<T>, R);
impl<R: Read<T>, T: Copy> Iterator for Data<R, T> {
type Item = Result<T, R::Err>;
#[inline] fn next(&mut self) -> Option<Self::Item> { unsafe {
let mut buf: MU<[T; 1]> = MU::uninit();
match self.1.read(&mut *buf.as_mut_ptr()) {
Err(e) => Some(Err(e)),
Ok(0) => None,
Ok(_) => Some(Ok(buf.assume_init()[0])),
}
} }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.1.size_hint() }
}
impl<R: Read<T>, T: Copy> Deref for Data<R, T> {
type Target = R;
#[inline]
fn deref(&self) -> &R { &self.1 }
}
impl<R: Read<T>, T: Copy> DerefMut for Data<R, T> {
#[inline]
fn deref_mut(&mut self) -> &mut R { &mut self.1 }
}
#[derive(Debug)]
pub struct Split<R: Read<T>, T: Copy, P: FnMut(T) -> bool, E: From<R::Err> + From<NoMemory>> {
φ: PhantomData<E>,
pub r: R,
p: P,
pub buf: Option<Vec<T>>,
keep_delim: bool,
}
impl<R: Read<T>, T: Copy, P: FnMut(T) -> bool, E: From<R::Err> + From<NoMemory>> Iterator for Split<R, T, P, E> {
type Item = Result<Vec<T>, E>;
#[inline] fn next(&mut self) -> Option<Self::Item> {
let mut buf = match self.buf.take() { Some(buf) => buf, None => return None, };
let p = &mut self.p;
loop {
if let Some(n) = buf.iter().position(|&x| p(x)) {
return match buf.split_off(n+1) {
None => {
self.buf = Some(buf);
Some(Err(E::from(NoMemory)))
},
Some(xs) => {
self.buf = Some(xs);
if !self.keep_delim { buf.pop(); }
Some(Ok(buf))
},
}
}
let l = buf.len();
if !buf.reserve(max(l, 1)) {
self.buf = Some(buf);
return Some(Err(E::from(NoMemory)));
}
match self.r.read_onto_vec(&mut buf) {
Err(e) => {
self.buf = Some(buf);
return Some(Err(E::from(e)));
},
Ok(_) => if buf.len() == l { return Some(Ok(buf)) },
}
}
}
}
pub trait TryWrite<T: Copy> {
type Err;
#[inline]
fn try_write(&mut self, buf: &[T]) -> Result<Result<usize, EndOfFile>, Self::Err> { self.try_writev(&[buf]) }
#[inline]
fn try_writev(&mut self, bufs: &[&[T]]) -> Result<Result<usize, EndOfFile>, Self::Err> {
for buf in bufs { if buf.len() > 0 { return self.try_write(buf) } }
Ok(Ok(0))
}
}
pub trait Write<T: Copy> {
type Err;
#[inline]
fn write(&mut self, buf: &[T]) -> Result<usize, Self::Err> { self.writev(&[buf]) }
#[inline]
fn writev(&mut self, bufs: &[&[T]]) -> Result<usize, Self::Err> {
for buf in bufs { if buf.len() > 0 { return self.write(buf) } }
Ok(0)
}
fn flush(&mut self) -> Result<(), Self::Err>;
#[inline]
fn write_all(&mut self, buf: &[T]) -> Result<(), (Self::Err, usize)> where Self::Err: From<EndOfFile> {
self.write_all_e(buf).map_err(|(x, y)| (match x { Left(a) => a.into(), Right(b) => b }, y))
}
#[inline]
fn write_all_e(&mut self, buf: &[T]) -> Result<(), (Either<EndOfFile, Self::Err>, usize)> {
let mut n = 0;
while let Some(buf) = buf.get(n..) {
if 0 == buf.len() { break }
match self.write(buf) {
Err(e) => return Err((Right(e), n)),
Ok(0) => return Err((Left(EndOfFile), n)),
Ok(m) => n += m,
}
}
Ok(())
}
}
pub trait PosWrite<T: Copy> : Write<T> {
fn pwrite(&mut self, buf: &[T], pos: usize) -> Result<usize, Self::Err> { self.pwritev(&[buf], pos) }
fn pwritev(&mut self, bufs: &[&[T]], pos: usize) -> Result<usize, Self::Err> {
for buf in bufs { if buf.len() > 0 { return self.pwrite(buf, pos) } }
Ok(0)
}
#[inline] fn pwrite_all(&mut self, buf: &[T], mut pos: usize) -> Result<(), (Self::Err, usize)> where Self::Err: From<EndOfFile> {
let mut n = 0;
while let Some(buf) = buf.get(n..) {
match self.pwrite(buf, pos) {
Err(e) => return Err((e, n)),
Ok(0) => return Err((Self::Err::from(EndOfFile), n)),
Ok(m) => {
n += m;
pos += m;
},
}
}
Ok(())
}
}
impl<'a, T: Copy, R: ?Sized + DerefMut> Read<T> for R where R::Target: Read<T> {
type Err = <R::Target as Read<T>>::Err;
#[inline]
fn read(&mut self, buf: &mut [T]) -> Result<usize, Self::Err> {
R::Target::read(self.deref_mut(), buf)
}
#[inline]
fn readv(&mut self, buf: &mut [&mut [T]]) -> Result<usize, Self::Err> {
R::Target::readv(self.deref_mut(), buf)
}
}
impl<'a, T: Copy, W: ?Sized + DerefMut> Write<T> for W where W::Target: Write<T> {
type Err = <W::Target as Write<T>>::Err;
#[inline]
fn write(&mut self, buf: &[T]) -> Result<usize, Self::Err> {
W::Target::write(self.deref_mut(), buf)
}
#[inline]
fn writev(&mut self, buf: &[&[T]]) -> Result<usize, Self::Err> {
W::Target::writev(self.deref_mut(), buf)
}
#[inline]
fn flush(&mut self) -> Result<(), Self::Err> {
W::Target::flush(self.deref_mut())
}
}
impl From<Void> for EndOfFile { fn from(void: Void) -> Self { match void {} } }
impl From<Void> for NoMemory { fn from(void: Void) -> Self { match void {} } }
#[cfg(test)] mod tests {
use std;
use std::iter::Iterator;
use containers::collections::Vec;
use ::util::*;
use super::*;
use super::pos::*;
fn test_split_singleton<T: Copy + Eq>(xs: std::vec::Vec<T>, keep_delim: bool) -> bool {
Iterator::eq(xs.clone().into_iter(),
Pos::from(xs).split(|_| false, keep_delim).map(Result::<_, NoMemory>::unwrap).next().unwrap().into_iter())
}
#[quickcheck] fn split_singleton_unit(xs: std::vec::Vec<()>, keep_delim: bool) -> bool { test_split_singleton(xs, keep_delim) }
#[quickcheck] fn split_singleton_ABC(xs: std::vec::Vec<ABC>, keep_delim: bool) -> bool { test_split_singleton(xs, keep_delim) }
fn test_split_count<T: Copy + Eq>(xs: std::vec::Vec<T>, y: T, keep_delim: bool) -> bool {
xs.clone().into_iter().filter(|&x| x == y).count() + 1 == Pos::from(xs).split(|x| x == y, keep_delim).map(Result::<_, NoMemory>::unwrap).count()
}
#[quickcheck] fn split_count_unit(xs: std::vec::Vec<()>, keep_delim: bool) -> bool { test_split_count(xs, (), keep_delim) }
#[quickcheck] fn split_count_abc(xs: std::vec::Vec<ABC>, y: ABC, keep_delim: bool) -> bool { test_split_count(xs, y, keep_delim) }
fn test_split_concatenation<T: Copy + Eq>(xs: std::vec::Vec<T>, y: T) -> bool {
Iterator::eq(xs.clone().into_iter(),
Pos::from(xs).split(|x| x == y, true).map(Result::<_, NoMemory>::unwrap).flat_map(Vec::into_iter))
}
#[quickcheck] fn split_concatenation_unit(xs: std::vec::Vec<()>) -> bool { test_split_concatenation(xs, ()) }
#[quickcheck] fn split_concatenation_abc(xs: std::vec::Vec<ABC>, y: ABC) -> bool { test_split_concatenation(xs, y) }
}