mod slice;
mod stateful;
pub mod data_source;
use std::cell::Cell;
use std::io;
use std::ops;
use std::ptr;
pub use self::data_source::{DataSource, RWDataSource};
pub use self::slice::SliceStream;
pub use self::stateful::Source;
use crate::primitives::Guard;
use crate::types::Buffer as InputBuffer;
use crate::types::{Input, ParseResult};
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(b1, e1), StreamError::ParseError(b2, 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;
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>(
/// 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 Buffer = &'a [I];
type Marker = &'a [I];
type Token = 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[b.len()..];
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]> {
fn fill<S: DataSource<Item = I>>(&mut self, _: &mut S) -> io::Result<usize>;
fn request_space(&mut self, _: usize);
fn consume(&self, items: usize);
fn len(&self) -> usize;
#[inline]
fn is_empty(&self) -> bool {
self.len() == 0
}
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) {
assert!(self.populated >= self.used.get());
if self.buffer.len() - self.populated < items {
unsafe {
ptr::copy(
self.buffer.as_ptr().add(self.used.get()),
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,
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().add(self.used.get()),
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 crate::primitives::{IntoInner, Primitives};
use crate::types::test::run_primitives_test;
use crate::types::{Input, ParseResult};
#[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!(!b.is_incomplete());
assert_eq!(b.len(), 1);
assert!(!b.is_empty());
b.peek();
assert!(!b.is_incomplete());
assert_eq!(b.len(), 1);
assert!(!b.is_empty());
b.pop();
assert!(!b.is_incomplete());
assert_eq!(b.len(), 0);
assert!(b.is_empty());
assert_eq!(b.peek(), None);
assert!(b.is_incomplete());
assert_eq!(b.len(), 0);
assert!(b.is_empty());
assert_eq!(b.pop(), None);
assert!(b.is_incomplete());
assert_eq!(b.len(), 0);
assert!(b.is_empty());
let mut b = InputBuf::new(b"ab");
assert!(!b.is_incomplete());
assert_eq!(b.len(), 2);
assert!(!b.is_empty());
b.consume(1);
assert!(!b.is_incomplete());
assert_eq!(b.len(), 1);
assert!(!b.is_empty());
b.consume(1);
assert!(!b.is_incomplete());
assert_eq!(b.len(), 0);
assert!(b.is_empty());
assert_eq!(b.consume(1), None);
assert!(b.is_incomplete());
assert_eq!(b.len(), 0);
assert!(b.is_empty());
let mut b = InputBuf::new(b"ab");
assert!(!b.is_incomplete());
assert_eq!(b.len(), 2);
assert!(!b.is_empty());
assert_eq!(b.consume(3), None);
assert!(b.is_incomplete());
assert_eq!(b.len(), 2);
assert!(!b.is_empty());
let mut b = InputBuf::new(b"ab");
assert!(!b.is_incomplete());
assert_eq!(b.len(), 2);
assert!(!b.is_empty());
assert_eq!(b.consume_while(|_| true), &b"ab"[..]);
assert!(b.is_incomplete());
assert_eq!(b.len(), 0);
assert!(b.is_empty());
let mut b = InputBuf::new(b"ab");
assert_eq!(b.consume_while(|c| c == b'a'), &b"a"[..]);
assert!(!b.is_incomplete());
assert_eq!(b.len(), 1);
assert!(!b.is_empty());
assert_eq!(b.consume_while(|c| c == b'b'), &b"b"[..]);
assert!(b.is_incomplete());
assert_eq!(b.len(), 0);
assert!(b.is_empty());
assert_eq!(b.consume_while(|c| c == b'b'), &b""[..]);
assert!(b.is_incomplete());
assert_eq!(b.len(), 0);
assert!(b.is_empty());
let mut b = InputBuf::new(b"abc");
let m = b.mark();
assert!(!b.is_incomplete());
assert_eq!(b.len(), 3);
assert!(!b.is_empty());
b.consume(3);
assert!(!b.is_incomplete());
assert_eq!(b.len(), 0);
assert!(b.is_empty());
assert_eq!(b.consume_from(m), &b"abc"[..]);
assert!(!b.is_incomplete());
assert_eq!(b.len(), 0);
assert!(b.is_empty());
let mut b = InputBuf::new(b"abc");
let m = b.mark();
assert!(!b.is_incomplete());
assert_eq!(b.len(), 3);
assert!(!b.is_empty());
b.consume(2);
b.consume(2);
assert!(b.is_incomplete());
assert_eq!(b.len(), 1);
assert!(!b.is_empty());
let b = b.restore(m);
assert!(b.is_incomplete());
assert_eq!(b.len(), 3);
assert!(!b.is_empty());
let mut b = InputBuf::new(b"abc");
assert!(!b.is_incomplete());
assert_eq!(b.len(), 3);
assert!(!b.is_empty());
b.consume_remaining();
assert!(b.is_incomplete());
assert_eq!(b.len(), 0);
assert!(b.is_empty());
}
#[test]
fn test_consuming_whole_buffer_does_not_reset_the_pointer() {
let slice = b"abc";
let mut b = InputBuf::new(slice);
b.consume(1);
b.consume_while(|_| true);
let consumed = b.1.as_ptr() as usize - slice.as_ptr() as usize;
assert_eq!(consumed, 3);
}
}