Fixed unsafe bufread (still cringe)
This commit is contained in:
parent
7dd830c7c8
commit
68d63901d6
|
@ -233,8 +233,6 @@ fn decoder(inputfile: &str) -> Result<(u32, u32, ColorType, ArrayVec<String, 124
|
|||
let infile = File::open(inputfile)?;
|
||||
let mut lines = UnsafeBufReader::new(infile).lines();
|
||||
|
||||
println!("{:?}", lines);
|
||||
|
||||
// "CIF: <flags>"
|
||||
if !lines.next().transpose()?.ok_or(InvalidHeaderError)?.starts_with("CIF:") {
|
||||
return Err(InvalidHeaderError)
|
||||
|
|
|
@ -17,21 +17,6 @@ impl Drop for Guard<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn append_to_string_unchecked<F>(buf: &mut ArrayString<8192>, f: F) -> usize
|
||||
where
|
||||
F: FnOnce(&mut ArrayVec<u8, 8192>) -> usize,
|
||||
{
|
||||
let mut buf_vec = ArrayVec::<u8, 8192>::new();
|
||||
for u in buf.as_bytes() {
|
||||
buf_vec.push(*u);
|
||||
}
|
||||
let mut g = Guard { len: buf.len(), buf: &mut buf_vec };
|
||||
let ret = f(g.buf);
|
||||
//std::str::from_utf8_unchecked(&g.buf[g.len..]); // Do we need it? (https://doc.rust-lang.org/src/std/io/mod.rs.html#342-349)
|
||||
g.len = g.buf.len();
|
||||
ret
|
||||
}
|
||||
|
||||
pub trait UnsafeBufRead: Read {
|
||||
fn consume(&mut self, amt: usize);
|
||||
fn fill_buf(&mut self) -> Result<&[u8], Error>;
|
||||
|
@ -39,8 +24,14 @@ pub trait UnsafeBufRead: Read {
|
|||
read_until(self, byte, buf)
|
||||
}
|
||||
|
||||
fn read_line(&mut self, buf: &mut ArrayString<8192>) -> Result<usize, Error> {
|
||||
unsafe { Ok(append_to_string_unchecked(buf, |b| read_until(self, b'\n', b).unwrap())) }
|
||||
fn read_line(&mut self, buf: &mut ArrayString<8192>) -> usize {
|
||||
let mut buf_vec = ArrayVec::<u8, 8192>::new();
|
||||
for u in buf.as_bytes() {
|
||||
buf_vec.push(*u);
|
||||
}
|
||||
let return_val = read_until(self, b'\n', &mut buf_vec).unwrap();
|
||||
unsafe { buf.push_str(std::str::from_utf8_unchecked(buf_vec.as_slice())) };
|
||||
return_val
|
||||
}
|
||||
|
||||
fn lines(self) -> UnsafeLines<Self>
|
||||
|
@ -62,17 +53,13 @@ impl<B: UnsafeBufRead> Iterator for UnsafeLines<B> {
|
|||
fn next(&mut self) -> Option<Result<ArrayString<8192>, CifError>> {
|
||||
let mut buf = ArrayString::<8192>::new();
|
||||
match self.buf.read_line(&mut buf) {
|
||||
Ok(0) => None,
|
||||
Ok(_n) => {
|
||||
0 => None,
|
||||
_n => {
|
||||
if buf.ends_with('\n') {
|
||||
buf.pop();
|
||||
if buf.ends_with('\r') {
|
||||
buf.pop();
|
||||
}
|
||||
}
|
||||
Some(Ok(buf))
|
||||
}
|
||||
Err(e) => Some(Err(CifError::IoError(e))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
// https://doc.rust-lang.org/src/std/io/buffered/bufreader.rs.html
|
||||
|
||||
use crate::unsafe_std::bufread::UnsafeBufRead;
|
||||
use crate::CifError;
|
||||
use arrayvec::{ArrayString, ArrayVec};
|
||||
use std::io::{Error, Read};
|
||||
use std::io::Read;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnsafeBufReader<R> {
|
||||
inner: R,
|
||||
buf: Box<[u8]>,
|
||||
|
@ -15,8 +12,12 @@ pub struct UnsafeBufReader<R> {
|
|||
|
||||
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 = std::boxed::Box::new_uninit_slice(8192).assume_init();
|
||||
let mut buf = Box::new_uninit_slice(capacity).assume_init();
|
||||
inner.initializer().initialize(&mut buf);
|
||||
UnsafeBufReader { inner, buf, pos: 0, cap: 0 }
|
||||
}
|
||||
|
@ -33,9 +34,6 @@ impl<R> UnsafeBufReader<R> {
|
|||
|
||||
impl<R: Read> Read for UnsafeBufReader<R> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
// If we don't have any buffered data and we're doing a massive read
|
||||
// (larger than our internal buffer), bypass our internal buffer
|
||||
// entirely.
|
||||
if self.pos == self.cap && buf.len() >= self.buf.len() {
|
||||
self.discard_buffer();
|
||||
return self.inner.read(buf)
|
||||
|
@ -63,3 +61,15 @@ impl<R: Read> UnsafeBufRead for UnsafeBufReader<R> {
|
|||
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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue