zardzewialy-dekoder-cif/src/unsafe_std/bufreader.rs

76 lines
2 KiB
Rust

// https://doc.rust-lang.org/src/std/io/buffered/bufreader.rs.html
use crate::unsafe_std::bufread::UnsafeBufRead;
use std::io::Read;
pub struct UnsafeBufReader<R> {
inner: R,
buf: Box<[u8]>,
pos: usize,
cap: usize,
}
impl<R: Read> UnsafeBufReader<R> {
pub fn new(inner: R) -> UnsafeBufReader<R> {
UnsafeBufReader::with_capacity(8192, inner)
}
pub fn with_capacity(capacity: usize, inner: R) -> UnsafeBufReader<R> {
unsafe {
let mut buf = Box::new_uninit_slice(capacity).assume_init();
inner.initializer().initialize(&mut buf);
UnsafeBufReader { inner, buf, pos: 0, cap: 0 }
}
}
}
impl<R> UnsafeBufReader<R> {
#[inline]
fn discard_buffer(&mut self) {
self.pos = 0;
self.cap = 0;
}
}
impl<R: Read> Read for UnsafeBufReader<R> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
if self.pos == self.cap && buf.len() >= self.buf.len() {
self.discard_buffer();
return self.inner.read(buf)
}
let nread = {
let mut rem = self.fill_buf()?;
rem.read(buf)?
};
self.consume(nread);
Ok(nread)
}
}
impl<R: Read> UnsafeBufRead for UnsafeBufReader<R> {
fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
if self.pos >= self.cap {
debug_assert!(self.pos == self.cap);
self.cap = self.inner.read(&mut self.buf)?;
self.pos = 0;
}
Ok(&self.buf[self.pos..self.cap])
}
fn consume(&mut self, amt: usize) {
self.pos = std::cmp::min(self.pos + amt, self.cap);
}
}
impl<R> std::fmt::Debug for UnsafeBufReader<R>
where
R: std::fmt::Debug,
{
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("BufReader")
.field("reader", &self.inner)
.field("buffer", &format_args!("{}/{}", self.cap - self.pos, self.buf.len()))
.finish()
}
}