diff --git a/src/main.rs b/src/main.rs index 7cb83be..66805d1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -233,8 +233,6 @@ fn decoder(inputfile: &str) -> Result<(u32, u32, ColorType, ArrayVec" if !lines.next().transpose()?.ok_or(InvalidHeaderError)?.starts_with("CIF:") { return Err(InvalidHeaderError) diff --git a/src/unsafe_std/bufread.rs b/src/unsafe_std/bufread.rs index 36c657e..9899ff2 100644 --- a/src/unsafe_std/bufread.rs +++ b/src/unsafe_std/bufread.rs @@ -17,21 +17,6 @@ impl Drop for Guard<'_> { } } -pub(crate) unsafe fn append_to_string_unchecked(buf: &mut ArrayString<8192>, f: F) -> usize -where - F: FnOnce(&mut ArrayVec) -> usize, -{ - let mut buf_vec = ArrayVec::::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 { - 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::::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 @@ -62,17 +53,13 @@ impl Iterator for UnsafeLines { fn next(&mut self) -> Option, 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))), } } } diff --git a/src/unsafe_std/bufreader.rs b/src/unsafe_std/bufreader.rs index b22a892..186f7bb 100644 --- a/src/unsafe_std/bufreader.rs +++ b/src/unsafe_std/bufreader.rs @@ -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 { inner: R, buf: Box<[u8]>, @@ -15,8 +12,12 @@ pub struct UnsafeBufReader { impl UnsafeBufReader { pub fn new(inner: R) -> UnsafeBufReader { + UnsafeBufReader::with_capacity(8192, inner) + } + + pub fn with_capacity(capacity: usize, inner: R) -> UnsafeBufReader { 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 UnsafeBufReader { impl Read for UnsafeBufReader { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - // 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 UnsafeBufRead for UnsafeBufReader { self.pos = std::cmp::min(self.pos + amt, self.cap); } } + +impl std::fmt::Debug for UnsafeBufReader +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() + } +}