use crate::compat;
use crate::errors;
use crate::io as ggio;
pub struct Reader<'a> {
s: &'a [u8],
i: u64, }
impl<'a> Reader<'a> {
pub fn new(b: &'a [u8]) -> Self {
Self {
s: b,
i: 0,
}
}
pub fn len(&self) -> usize {
if self.i >= self.s.len() as u64 {
return 0;
}
(self.s.len() as u64 - self.i) as usize
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn size(&mut self) -> usize {
self.s.len()
}
}
impl std::io::Read for Reader<'_> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
if self.i >= self.s.len() as u64 {
return Ok(0);
}
let n = compat::copy(buf, &self.s[self.i as usize..]);
self.i += n as u64;
Ok(n)
}
}
impl Reader<'_> {
pub fn read_at(&mut self, b: &mut [u8], off: u64) -> std::io::Result<usize> {
if off >= self.s.len() as u64 {
return Ok(0);
}
let n = compat::copy(b, &self.s[off as usize..]);
Ok(n)
}
}
impl ggio::ByteReader for Reader<'_> {
fn read_byte(&mut self) -> std::io::Result<u8> {
if self.i >= self.s.len() as u64 {
return Err(std::io::Error::from(std::io::ErrorKind::UnexpectedEof));
}
let b = self.s[self.i as usize];
self.i += 1;
Ok(b)
}
}
impl<'a> Reader<'a> {
pub fn unread_byte(&mut self) -> std::io::Result<()> {
if self.i == 0 {
return Err(errors::new_stdio_other_error(
"bytes::Reader::unread_byte: at beginning of slice".to_string(),
));
}
self.i -= 1;
Ok(())
}
pub fn seek(&mut self, offset: i64, whence: ggio::Seek) -> std::io::Result<u64> {
let abs = match whence {
ggio::Seek::Start => offset,
ggio::Seek::Current => self.i as i64 + offset,
ggio::Seek::End => self.s.len() as i64 + offset,
};
if abs < 0 {
return Err(errors::new_stdio_other_error(
"bytes::Reader::seek: negative position".to_string(),
));
}
self.i = abs as u64;
Ok(self.i)
}
pub fn write_to(&mut self, w: &mut dyn std::io::Write) -> std::io::Result<usize> {
if self.i >= self.s.len() as u64 {
return Ok(0);
}
let b = &self.s[self.i as usize..];
match w.write(b) {
Ok(m) => {
if m > b.len() {
panic!("bytes::Reader::write_to: invalid Write count");
}
self.i += m as u64;
if m != b.len() {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"short write",
));
}
Ok(m)
}
Err(err) => Err(err),
}
}
pub fn reset(&mut self, b: &'a [u8]) {
self.s = b;
self.i = 0;
}
}
impl std::io::BufRead for Reader<'_> {
fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
Ok(&self.s[self.i as usize..])
}
fn consume(&mut self, amt: usize) {
self.i += amt.min(self.len()) as u64;
}
}