use alloc::{
rc::Rc,
vec::Vec,
};
use core::{
cell::UnsafeCell,
fmt::Debug,
slice::from_raw_parts_mut,
};
use std::io::{
self,
Read,
};
use binator_core::{
Split,
Streaming,
Success,
};
use crate::Position;
#[derive(Debug)]
struct Buf<Reader: Read, const N: usize> {
buf: Vec<u8>,
reader: Reader,
}
impl<Reader: Read, const N: usize> Buf<Reader, N> {
fn new(reader: Reader) -> Self {
Self {
buf: Vec::new(),
reader,
}
}
fn read_all(&mut self) -> Result<usize, io::Error> {
while self.read()? == 0 {}
Ok(self.buf.len())
}
fn read(&mut self) -> Result<usize, io::Error> {
unsafe {
self.buf.reserve(N);
let len = self.buf.len();
let ptr = self.buf.as_mut_ptr();
match self.reader.read(from_raw_parts_mut(ptr.add(len), N)) {
Ok(n) => {
self.buf.set_len(len + n);
Ok(n)
}
Err(error) => Err(error),
}
}
}
fn get(&mut self, i: usize) -> Option<Result<u8, io::Error>> {
loop {
if let Some(o) = self.buf.get(i) {
break Some(Ok(*o));
}
match self.read() {
Ok(n) => {
if n == 0 {
break None;
}
}
Err(error) => break Some(Err(error)),
}
}
}
}
#[derive(Debug)]
pub struct ReaderStream<Reader: Read, const N: usize> {
buf: Rc<UnsafeCell<Buf<Reader, N>>>,
position: Position,
}
impl<Reader: Read, const N: usize> Clone for ReaderStream<Reader, N> {
fn clone(&self) -> Self {
Self {
buf: self.buf.clone(),
position: self.position.clone(),
}
}
}
impl<Reader: Read, const N: usize> ReaderStream<Reader, N> {
pub fn new(reader: Reader) -> Self {
Self {
buf: Rc::new(UnsafeCell::new(Buf::new(reader))),
position: Position::RangeFrom(0..),
}
}
}
impl<Reader: Read + Debug, const N: usize> Streaming for ReaderStream<Reader, N> {
type Error = io::Error;
type Item = u8;
type Span = Self;
fn split_first(self) -> Split<Self::Item, Self, Self::Error> {
unsafe {
let (i, position) = self.position.next();
match i.and_then(|i| (*self.buf.get()).get(i)) {
Some(Ok(o)) => Split::Success {
item: o,
stream: Self {
buf: self.buf,
position,
},
},
None => Split::NotEnoughItem(self),
Some(Err(error)) => Split::Error(error),
}
}
}
fn all(self) -> Result<Success<Self::Span, Self>, Self::Error> {
unsafe {
match self.position {
Position::RangeFrom(range) => {
let ret = (*self.buf.get()).read_all();
match ret {
Ok(end) => {
let empty = Self {
buf: self.buf.clone(),
position: Position::Range(end..end),
};
Ok(Success {
token: Self {
buf: self.buf,
position: Position::Range(range.start..end),
},
stream: empty,
})
}
Err(error) => Err(error),
}
}
Position::Range(range) => {
let empty = Self {
buf: self.buf.clone(),
position: Position::Range(range.end..range.end),
};
Ok(Success {
token: Self {
buf: self.buf,
position: Position::Range(range),
},
stream: empty,
})
}
}
}
}
fn split_at(self, _mid: usize) -> Split<Self::Span, Self, Self::Error> {
todo!()
}
fn split_last(self) -> Split<Self::Item, Self, Self::Error> {
todo!()
}
fn diff(self, other: &Self) -> Result<Self::Span, Self> {
match self.position.range(&other.position) {
Some(range) => Ok(Self {
buf: self.buf,
position: Position::Range(range),
}),
None => Err(self),
}
}
}
impl<Reader: Read, const N: usize> PartialEq for ReaderStream<Reader, N> {
fn eq(&self, other: &Self) -> bool {
Rc::ptr_eq(&self.buf, &other.buf) && self.position == other.position
}
}
impl<Reader: Read, const N: usize> Eq for ReaderStream<Reader, N> {}