mod stateful;
mod slice;
pub mod data_source;
use std::io;
use std::ops;
use std::ptr;
use std::cell::Cell;
use types::{Input, ParseResult};
use types::Buffer as InputBuffer;
use primitives::Guard;
pub use self::slice::SliceStream;
pub use self::data_source::DataSource;
pub use self::stateful::Source;
const DEFAULT_BUFFER_SIZE: usize = 6 * 1024;
#[derive(Debug)]
pub enum StreamError<B: InputBuffer, E> {
ParseError(B, E),
Incomplete,
IoError(io::Error),
EndOfInput,
Retry,
}
impl<B: InputBuffer, E: PartialEq<E>> PartialEq for StreamError<B, E> {
#[inline]
fn eq(&self, other: &StreamError<B, E>) -> bool {
match (self, other) {
(&StreamError::ParseError(ref b1, ref e1), &StreamError::ParseError(ref b2, ref e2)) => b1 == b2 && e1 == e2,
(&StreamError::Incomplete, &StreamError::Incomplete)
| (&StreamError::EndOfInput, &StreamError::EndOfInput)
| (&StreamError::Retry, &StreamError::Retry) => true,
_ => false,
}
}
}
pub trait Stream<'a, 'i> {
type Input: Input + 'i;
#[inline]
fn parse<F, T, E>(&'a mut self, f: F) -> Result<T, StreamError<<Self::Input as Input>::Buffer, E>>
where F: FnOnce(Self::Input) -> ParseResult<Self::Input, T, E>,
T: 'i,
E: 'i;
}
#[must_use]
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct InputBuf<'a, I: 'a>(
/// If this is set to true a parser has tried to read past the end of this buffer.
bool,
/// Current buffer slice
&'a [I],
);
impl<'a, I: 'a> InputBuf<'a, I> {
#[inline]
pub fn new(buf: &'a [I]) -> Self {
InputBuf(false, buf)
}
#[inline]
pub fn is_incomplete(&self) -> bool {
self.0
}
#[inline]
pub fn len(&self) -> usize {
self.1.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl<'a, I: Copy + PartialEq> Input for InputBuf<'a, I> {
type Token = I;
type Marker = &'a [I];
type Buffer = &'a [I];
#[inline]
fn _peek(&mut self, _g: Guard) -> Option<Self::Token> {
if let Some(c) = self.1.first() {
Some(*c)
} else {
self.0 = true;
None
}
}
#[inline]
fn _pop(&mut self, g: Guard) -> Option<Self::Token> {
self._peek(g).map(|c| {
self.1 = &self.1[1..];
c
})
}
#[inline]
fn _consume(&mut self, _g: Guard, n: usize) -> Option<Self::Buffer> {
if n > self.1.len() {
self.0 = true;
None
} else {
let b = &self.1[..n];
self.1 = &self.1[n..];
Some(b)
}
}
#[inline]
fn _consume_while<F>(&mut self, g: Guard, mut f: F) -> Self::Buffer
where F: FnMut(Self::Token) -> bool {
if let Some(n) = self.1.iter().position(|c| !f(*c)) {
let b = &self.1[..n];
self.1 = &self.1[n..];
b
} else {
self._consume_remaining(g)
}
}
#[inline]
fn _consume_from(&mut self, _g: Guard, m: Self::Marker) -> Self::Buffer {
&m[..m.len() - self.1.len()]
}
#[inline]
fn _consume_remaining(&mut self, _g: Guard) -> Self::Buffer {
self.0 = true;
let b = self.1;
self.1 = &self.1[..0];
b
}
#[inline]
fn _mark(&self, _g: Guard) -> Self::Marker {
self.1
}
#[inline]
fn _restore(mut self, _g: Guard, m: Self::Marker) -> Self {
self.1 = m;
self
}
}
pub trait Buffer<I: Copy + PartialEq>: ops::Deref<Target=[I]> {
#[inline]
fn fill<S: DataSource<Item=I>>(&mut self, &mut S) -> io::Result<usize>;
#[inline]
fn request_space(&mut self, usize);
#[inline]
fn consume(&self, items: usize);
#[inline]
fn len(&self) -> usize;
#[inline]
fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
fn capacity(&self) -> usize;
}
#[derive(Debug, Eq, PartialEq)]
pub struct FixedSizeBuffer<I: Copy + PartialEq> {
buffer: Vec<I>,
populated: usize,
used: Cell<usize>,
}
impl<I: Copy + PartialEq> FixedSizeBuffer<I> {
#[inline]
pub fn new() -> Self {
Self::with_size(DEFAULT_BUFFER_SIZE)
}
#[inline]
pub fn with_size(size: usize) -> Self {
assert!(size > 0);
let mut buf = Vec::with_capacity(size);
unsafe {
buf.set_len(size);
}
FixedSizeBuffer {
buffer: buf,
populated: 0,
used: Cell::new(0),
}
}
}
impl<I: Copy + PartialEq> ops::Deref for FixedSizeBuffer<I> {
type Target = [I];
#[inline]
fn deref(&self) -> &[I] {
&self.buffer[self.used.get()..self.populated]
}
}
impl<I: Copy + PartialEq> ops::DerefMut for FixedSizeBuffer<I> {
#[inline]
fn deref_mut(&mut self) -> &mut [I] {
&mut self.buffer[self.used.get()..self.populated]
}
}
impl<I: Copy + PartialEq> Buffer<I> for FixedSizeBuffer<I> {
#[inline]
fn fill<S: DataSource<Item=I>>(&mut self, s: &mut S) -> io::Result<usize> {
s.read(&mut self.buffer[self.populated..]).map(|n| {
debug_assert!(self.populated + n <= self.buffer.len());
self.populated += n;
n
})
}
#[inline]
fn request_space(&mut self, items: usize) {
use std::ptr;
assert!(self.populated >= self.used.get());
if self.buffer.len() - self.populated < items {
unsafe {
ptr::copy(self.buffer.as_ptr().offset(self.used.get() as isize), self.buffer.as_mut_ptr(), self.populated - self.used.get());
}
self.populated -= self.used.get();
self.used.set(0);
}
}
#[inline]
fn consume(&self, items: usize) {
debug_assert!(self.used.get() + items <= self.populated);
self.used.set(self.used.get() + items)
}
#[inline]
fn len(&self) -> usize {
self.populated - self.used.get()
}
#[inline]
fn capacity(&self) -> usize {
self.buffer.len()
}
}
#[derive(Debug)]
pub struct GrowingBuffer<I: Copy + PartialEq> {
buffer: Vec<I>,
populated: usize,
limit: usize,
used: Cell<usize>,
}
impl<I: Copy + PartialEq> GrowingBuffer<I> {
#[inline]
pub fn new() -> Self {
Self::with_limit(0)
}
#[inline]
pub fn with_limit(limit: usize) -> Self {
GrowingBuffer {
buffer: Vec::new(),
populated: 0,
limit: limit,
used: Cell::new(0),
}
}
}
impl<I: Copy + PartialEq> ops::Deref for GrowingBuffer<I> {
type Target = [I];
#[inline]
fn deref(&self) -> &[I] {
&self.buffer[self.used.get()..self.populated]
}
}
impl<I: Copy + PartialEq> ops::DerefMut for GrowingBuffer<I> {
#[inline]
fn deref_mut(&mut self) -> &mut [I] {
&mut self.buffer[self.used.get()..self.populated]
}
}
impl<I: Copy + PartialEq> Buffer<I> for GrowingBuffer<I> {
#[inline]
fn fill<S: DataSource<Item=I>>(&mut self, s: &mut S) -> io::Result<usize> {
s.read(&mut self.buffer[self.populated..]).map(|n| {
debug_assert!(self.populated + n <= self.buffer.len());
self.populated += n;
n
})
}
#[inline]
fn request_space(&mut self, items: usize) {
if self.limit != 0 && self.buffer.capacity() > self.limit {
return;
}
if items + self.len() > self.buffer.capacity() {
self.buffer.reserve(items);
let cap = self.buffer.capacity();
unsafe {
self.buffer.set_len(cap);
}
}
if self.buffer.len() - self.populated < items {
unsafe {
ptr::copy(self.buffer.as_ptr().offset(self.used.get() as isize), self.buffer.as_mut_ptr(), self.populated - self.used.get());
}
self.populated -= self.used.get();
self.used.set(0);
}
}
#[inline]
fn consume(&self, items: usize) {
debug_assert!(self.used.get() + items <= self.populated);
self.used.set(self.used.get() + items)
}
#[inline]
fn len(&self) -> usize {
self.populated - self.used.get()
}
#[inline]
fn capacity(&self) -> usize {
self.buffer.len()
}
}
#[cfg(test)]
mod test {
use super::InputBuf;
use types::{Input, ParseResult};
use primitives::{IntoInner, Primitives};
use types::test::run_primitives_test;
#[test]
fn ret() {
let i1: InputBuf<u8> = InputBuf::new(b"in1");
let i2: InputBuf<u8> = InputBuf::new(b"in2");
let r1: ParseResult<_, u32, ()> = i1.ret::<_, ()>(23u32);
let r2: ParseResult<_, i32, &str> = i2.ret::<_, &str>(23i32);
assert_eq!(r1.into_inner(), (InputBuf::new(b"in1"), Ok(23u32)));
assert_eq!(r2.into_inner(), (InputBuf::new(b"in2"), Ok(23i32)));
}
#[test]
fn err() {
let i1: InputBuf<u8> = InputBuf::new(b"in1");
let i2: InputBuf<u8> = InputBuf::new(b"in2");
let r1: ParseResult<_, (), u32> = i1.err::<(), _>(23u32);
let r2: ParseResult<_, &str, i32> = i2.err::<&str, _>(23i32);
assert_eq!(r1.into_inner(), (InputBuf::new(b"in1"), Err(23u32)));
assert_eq!(r2.into_inner(), (InputBuf::new(b"in2"), Err(23i32)));
}
#[test]
fn test_input_buf() {
run_primitives_test(InputBuf::new(b"abc"), |x| x);
let mut b = InputBuf::new(b"a");
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 1);
assert_eq!(b.is_empty(), false);
b.peek();
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 1);
assert_eq!(b.is_empty(), false);
b.pop();
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 0);
assert_eq!(b.is_empty(), true);
assert_eq!(b.peek(), None);
assert_eq!(b.is_incomplete(), true);
assert_eq!(b.len(), 0);
assert_eq!(b.is_empty(), true);
assert_eq!(b.pop(), None);
assert_eq!(b.is_incomplete(), true);
assert_eq!(b.len(), 0);
assert_eq!(b.is_empty(), true);
let mut b = InputBuf::new(b"ab");
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 2);
assert_eq!(b.is_empty(), false);
b.consume(1);
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 1);
assert_eq!(b.is_empty(), false);
b.consume(1);
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 0);
assert_eq!(b.is_empty(), true);
assert_eq!(b.consume(1), None);
assert_eq!(b.is_incomplete(), true);
assert_eq!(b.len(), 0);
assert_eq!(b.is_empty(), true);
let mut b = InputBuf::new(b"ab");
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 2);
assert_eq!(b.is_empty(), false);
assert_eq!(b.consume(3), None);
assert_eq!(b.is_incomplete(), true);
assert_eq!(b.len(), 2);
assert_eq!(b.is_empty(), false);
let mut b = InputBuf::new(b"ab");
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 2);
assert_eq!(b.is_empty(), false);
assert_eq!(b.consume_while(|_| true), &b"ab"[..]);
assert_eq!(b.is_incomplete(), true);
assert_eq!(b.len(), 0);
assert_eq!(b.is_empty(), true);
let mut b = InputBuf::new(b"ab");
assert_eq!(b.consume_while(|c| c == b'a'), &b"a"[..]);
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 1);
assert_eq!(b.is_empty(), false);
assert_eq!(b.consume_while(|c| c == b'b'), &b"b"[..]);
assert_eq!(b.is_incomplete(), true);
assert_eq!(b.len(), 0);
assert_eq!(b.is_empty(), true);
assert_eq!(b.consume_while(|c| c == b'b'), &b""[..]);
assert_eq!(b.is_incomplete(), true);
assert_eq!(b.len(), 0);
assert_eq!(b.is_empty(), true);
let mut b = InputBuf::new(b"abc");
let m = b.mark();
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 3);
assert_eq!(b.is_empty(), false);
b.consume(3);
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 0);
assert_eq!(b.is_empty(), true);
assert_eq!(b.consume_from(m), &b"abc"[..]);
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 0);
assert_eq!(b.is_empty(), true);
let mut b = InputBuf::new(b"abc");
let m = b.mark();
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 3);
assert_eq!(b.is_empty(), false);
b.consume(2);
b.consume(2);
assert_eq!(b.is_incomplete(), true);
assert_eq!(b.len(), 1);
assert_eq!(b.is_empty(), false);
let b = b.restore(m);
assert_eq!(b.is_incomplete(), true);
assert_eq!(b.len(), 3);
assert_eq!(b.is_empty(), false);
let mut b = InputBuf::new(b"abc");
assert_eq!(b.is_incomplete(), false);
assert_eq!(b.len(), 3);
assert_eq!(b.is_empty(), false);
b.consume_remaining();
assert_eq!(b.is_incomplete(), true);
assert_eq!(b.len(), 0);
assert_eq!(b.is_empty(), true);
}
}