use alloc::boxed::Box;
use alloc::string::String;
use core::fmt;
pub type Result<T> = core::result::Result<T, Error>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ErrorKind {
AlreadyExists,
BrokenPipe,
CrossesDevices,
Interrupted,
InvalidData,
InvalidInput,
NotFound,
Other,
PermissionDenied,
UnexpectedEof,
Unsupported,
WouldBlock,
WriteZero,
}
impl ErrorKind {
fn as_str(self) -> &'static str {
match self {
Self::AlreadyExists => "entity already exists",
Self::BrokenPipe => "broken pipe",
Self::CrossesDevices => "cross-device link or rename",
Self::Interrupted => "operation interrupted",
Self::InvalidData => "invalid data",
Self::InvalidInput => "invalid input parameter",
Self::NotFound => "entity not found",
Self::Other => "other error",
Self::PermissionDenied => "permission denied",
Self::UnexpectedEof => "unexpected end of file",
Self::Unsupported => "unsupported",
Self::WouldBlock => "operation would block",
Self::WriteZero => "write returned 0 bytes",
}
}
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
pub struct Error {
kind: ErrorKind,
message: Option<Box<str>>,
}
impl Error {
pub fn new<M: Into<String>>(kind: ErrorKind, message: M) -> Self {
Self {
kind,
message: Some(message.into().into_boxed_str()),
}
}
#[must_use]
pub const fn from_kind(kind: ErrorKind) -> Self {
Self {
kind,
message: None,
}
}
#[must_use]
pub const fn kind(&self) -> ErrorKind {
self.kind
}
pub fn other<M: Into<String>>(message: M) -> Self {
Self::new(ErrorKind::Other, message)
}
}
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Self {
Self::from_kind(kind)
}
}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut dbg = f.debug_struct("Error");
dbg.field("kind", &self.kind);
if let Some(msg) = &self.message {
dbg.field("message", msg);
}
dbg.finish()
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.message {
Some(msg) => write!(f, "{}: {msg}", self.kind.as_str()),
None => f.write_str(self.kind.as_str()),
}
}
}
impl core::error::Error for Error {}
#[cfg(feature = "std")]
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
let std_kind = err.kind();
let (kind, kind_is_mapped) = match std_kind {
std::io::ErrorKind::AlreadyExists => (ErrorKind::AlreadyExists, true),
std::io::ErrorKind::BrokenPipe => (ErrorKind::BrokenPipe, true),
std::io::ErrorKind::CrossesDevices => (ErrorKind::CrossesDevices, true),
std::io::ErrorKind::Interrupted => (ErrorKind::Interrupted, true),
std::io::ErrorKind::InvalidData => (ErrorKind::InvalidData, true),
std::io::ErrorKind::InvalidInput => (ErrorKind::InvalidInput, true),
std::io::ErrorKind::NotFound => (ErrorKind::NotFound, true),
std::io::ErrorKind::PermissionDenied => (ErrorKind::PermissionDenied, true),
std::io::ErrorKind::UnexpectedEof => (ErrorKind::UnexpectedEof, true),
std::io::ErrorKind::Unsupported => (ErrorKind::Unsupported, true),
std::io::ErrorKind::WouldBlock => (ErrorKind::WouldBlock, true),
std::io::ErrorKind::WriteZero => (ErrorKind::WriteZero, true),
std::io::ErrorKind::Other => (ErrorKind::Other, true),
_ => (ErrorKind::Other, false),
};
if err.raw_os_error().is_some() || err.get_ref().is_some() {
Self::new(kind, alloc::format!("{err}"))
} else if kind_is_mapped {
Self::from_kind(kind)
} else {
Self::new(kind, alloc::format!("{err}"))
}
}
}
#[cfg(feature = "std")]
impl From<Error> for std::io::Error {
fn from(err: Error) -> Self {
let kind = match err.kind {
ErrorKind::AlreadyExists => std::io::ErrorKind::AlreadyExists,
ErrorKind::BrokenPipe => std::io::ErrorKind::BrokenPipe,
ErrorKind::CrossesDevices => std::io::ErrorKind::CrossesDevices,
ErrorKind::Interrupted => std::io::ErrorKind::Interrupted,
ErrorKind::InvalidData => std::io::ErrorKind::InvalidData,
ErrorKind::InvalidInput => std::io::ErrorKind::InvalidInput,
ErrorKind::NotFound => std::io::ErrorKind::NotFound,
ErrorKind::Other => std::io::ErrorKind::Other,
ErrorKind::PermissionDenied => std::io::ErrorKind::PermissionDenied,
ErrorKind::UnexpectedEof => std::io::ErrorKind::UnexpectedEof,
ErrorKind::Unsupported => std::io::ErrorKind::Unsupported,
ErrorKind::WouldBlock => std::io::ErrorKind::WouldBlock,
ErrorKind::WriteZero => std::io::ErrorKind::WriteZero,
};
match err.message {
Some(msg) => Self::new(kind, msg.into_string()),
None => Self::from(kind),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SeekFrom {
Start(u64),
End(i64),
Current(i64),
}
#[cfg(feature = "std")]
impl From<SeekFrom> for std::io::SeekFrom {
fn from(s: SeekFrom) -> Self {
match s {
SeekFrom::Start(n) => Self::Start(n),
SeekFrom::End(n) => Self::End(n),
SeekFrom::Current(n) => Self::Current(n),
}
}
}
#[cfg(feature = "std")]
impl From<std::io::SeekFrom> for SeekFrom {
fn from(s: std::io::SeekFrom) -> Self {
match s {
std::io::SeekFrom::Start(n) => Self::Start(n),
std::io::SeekFrom::End(n) => Self::End(n),
std::io::SeekFrom::Current(n) => Self::Current(n),
}
}
}
#[cfg(feature = "std")]
pub trait Read: std::io::Read {}
#[cfg(feature = "std")]
impl<R: std::io::Read + ?Sized> Read for R {}
#[cfg(feature = "std")]
pub trait Write: std::io::Write {}
#[cfg(feature = "std")]
impl<W: std::io::Write + ?Sized> Write for W {}
#[cfg(feature = "std")]
pub trait Seek: std::io::Seek {}
#[cfg(feature = "std")]
impl<S: std::io::Seek + ?Sized> Seek for S {}
#[cfg(feature = "std")]
pub trait BufRead: std::io::BufRead {}
#[cfg(feature = "std")]
impl<B: std::io::BufRead + ?Sized> BufRead for B {}
#[cfg(not(feature = "std"))]
pub trait Read {
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
while !buf.is_empty() {
match self.read(buf) {
Ok(0) => break,
Ok(n) => {
let (_, rest) = buf.split_at_mut(n);
buf = rest;
}
Err(e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
if buf.is_empty() {
Ok(())
} else {
Err(Error::new(
ErrorKind::UnexpectedEof,
"failed to fill whole buffer",
))
}
}
fn take(self, limit: u64) -> Take<Self>
where
Self: Sized,
{
Take { inner: self, limit }
}
}
#[cfg(not(feature = "std"))]
pub struct Take<R> {
inner: R,
limit: u64,
}
#[cfg(not(feature = "std"))]
impl<R: Read> Read for Take<R> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
if self.limit == 0 {
return Ok(0);
}
let max = (buf.len() as u64).min(self.limit) as usize;
let (head, _) = buf.split_at_mut(max);
let n = self.inner.read(head)?;
self.limit -= n as u64;
Ok(n)
}
}
#[cfg(not(feature = "std"))]
pub trait BufRead: Read {
fn fill_buf(&mut self) -> Result<&[u8]>;
fn consume(&mut self, amt: usize);
}
#[cfg(not(feature = "std"))]
pub trait Write {
fn write(&mut self, buf: &[u8]) -> Result<usize>;
fn flush(&mut self) -> Result<()>;
fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
while !buf.is_empty() {
match self.write(buf) {
Ok(0) => {
return Err(Error::new(
ErrorKind::WriteZero,
"failed to write whole buffer",
));
}
Ok(n) => {
let (_, rest) = buf.split_at(n);
buf = rest;
}
Err(e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}
}
#[cfg(not(feature = "std"))]
pub trait Seek {
fn seek(&mut self, pos: SeekFrom) -> Result<u64>;
fn stream_position(&mut self) -> Result<u64> {
self.seek(SeekFrom::Current(0))
}
fn seek_relative(&mut self, offset: i64) -> Result<()> {
self.seek(SeekFrom::Current(offset))?;
Ok(())
}
}
#[cfg(not(feature = "std"))]
impl<R: Read + ?Sized> Read for &mut R {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
(**self).read(buf)
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
(**self).read_exact(buf)
}
}
#[cfg(not(feature = "std"))]
impl<R: Read + ?Sized> Read for alloc::boxed::Box<R> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
(**self).read(buf)
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
(**self).read_exact(buf)
}
}
#[cfg(not(feature = "std"))]
impl<W: Write + ?Sized> Write for &mut W {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
(**self).write(buf)
}
fn flush(&mut self) -> Result<()> {
(**self).flush()
}
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
(**self).write_all(buf)
}
}
#[cfg(not(feature = "std"))]
impl<W: Write + ?Sized> Write for alloc::boxed::Box<W> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
(**self).write(buf)
}
fn flush(&mut self) -> Result<()> {
(**self).flush()
}
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
(**self).write_all(buf)
}
}
#[cfg(not(feature = "std"))]
impl<S: Seek + ?Sized> Seek for &mut S {
fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
(**self).seek(pos)
}
fn stream_position(&mut self) -> Result<u64> {
(**self).stream_position()
}
fn seek_relative(&mut self, offset: i64) -> Result<()> {
(**self).seek_relative(offset)
}
}
#[cfg(not(feature = "std"))]
impl<S: Seek + ?Sized> Seek for alloc::boxed::Box<S> {
fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
(**self).seek(pos)
}
fn stream_position(&mut self) -> Result<u64> {
(**self).stream_position()
}
fn seek_relative(&mut self, offset: i64) -> Result<()> {
(**self).seek_relative(offset)
}
}
#[cfg(not(feature = "std"))]
impl<B: BufRead + ?Sized> BufRead for &mut B {
fn fill_buf(&mut self) -> Result<&[u8]> {
(**self).fill_buf()
}
fn consume(&mut self, amt: usize) {
(**self).consume(amt);
}
}
#[cfg(not(feature = "std"))]
impl<B: BufRead + ?Sized> BufRead for alloc::boxed::Box<B> {
fn fill_buf(&mut self) -> Result<&[u8]> {
(**self).fill_buf()
}
fn consume(&mut self, amt: usize) {
(**self).consume(amt);
}
}
#[cfg(not(feature = "std"))]
pub trait VarintWriter: Write {
fn write_u64_varint(&mut self, mut value: u64) -> Result<()> {
loop {
let mut byte = (value & 0x7f) as u8;
value >>= 7;
if value != 0 {
byte |= 0x80;
}
self.write_all(&[byte])?;
if value == 0 {
return Ok(());
}
}
}
fn write_u32_varint(&mut self, value: u32) -> Result<()> {
self.write_u64_varint(u64::from(value))
}
fn write_u16_varint(&mut self, value: u16) -> Result<()> {
self.write_u64_varint(u64::from(value))
}
}
#[cfg(not(feature = "std"))]
impl<W: Write + ?Sized> VarintWriter for W {}
#[cfg(not(feature = "std"))]
pub trait VarintReader: Read {
fn read_u64_varint(&mut self) -> Result<u64> {
let mut result: u64 = 0;
let mut shift: u32 = 0;
loop {
let mut byte = [0u8; 1];
self.read_exact(&mut byte)?;
if shift >= 64 {
return Err(Error::new(ErrorKind::InvalidData, "varint overflows u64"));
}
if shift == 63 && byte[0] & 0xFE != 0 {
return Err(Error::new(
ErrorKind::InvalidData,
"non-canonical varint overflow",
));
}
result |= (u64::from(byte[0] & 0x7f)) << shift;
if byte[0] & 0x80 == 0 {
return Ok(result);
}
shift += 7;
}
}
fn read_u32_varint(&mut self) -> Result<u32> {
let v = self.read_u64_varint()?;
u32::try_from(v).map_err(|_| Error::new(ErrorKind::InvalidData, "varint exceeds u32"))
}
fn read_u16_varint(&mut self) -> Result<u16> {
let v = self.read_u64_varint()?;
u16::try_from(v).map_err(|_| Error::new(ErrorKind::InvalidData, "varint exceeds u16"))
}
}
#[cfg(not(feature = "std"))]
impl<R: Read + ?Sized> VarintReader for R {}
pub trait ByteOrder {
fn u16_from(b: [u8; 2]) -> u16;
fn u32_from(b: [u8; 4]) -> u32;
fn u64_from(b: [u8; 8]) -> u64;
fn u128_from(b: [u8; 16]) -> u128;
fn u16_to(n: u16) -> [u8; 2];
fn u32_to(n: u32) -> [u8; 4];
fn u64_to(n: u64) -> [u8; 8];
fn u128_to(n: u128) -> [u8; 16];
#[must_use]
fn read_u16(buf: &[u8]) -> u16 {
let (head, _) = buf.split_at(2);
let mut a = [0u8; 2];
a.copy_from_slice(head);
Self::u16_from(a)
}
#[must_use]
fn read_u32(buf: &[u8]) -> u32 {
let (head, _) = buf.split_at(4);
let mut a = [0u8; 4];
a.copy_from_slice(head);
Self::u32_from(a)
}
#[must_use]
fn read_u64(buf: &[u8]) -> u64 {
let (head, _) = buf.split_at(8);
let mut a = [0u8; 8];
a.copy_from_slice(head);
Self::u64_from(a)
}
fn write_u16(buf: &mut [u8], n: u16) {
let (head, _) = buf.split_at_mut(2);
head.copy_from_slice(&Self::u16_to(n));
}
fn write_u32(buf: &mut [u8], n: u32) {
let (head, _) = buf.split_at_mut(4);
head.copy_from_slice(&Self::u32_to(n));
}
fn write_u64(buf: &mut [u8], n: u64) {
let (head, _) = buf.split_at_mut(8);
head.copy_from_slice(&Self::u64_to(n));
}
}
#[derive(Clone, Copy, Debug)]
pub enum LittleEndian {}
#[derive(Clone, Copy, Debug)]
pub enum BigEndian {}
pub type LE = LittleEndian;
pub type BE = BigEndian;
impl ByteOrder for LittleEndian {
fn u16_from(b: [u8; 2]) -> u16 {
u16::from_le_bytes(b)
}
fn u32_from(b: [u8; 4]) -> u32 {
u32::from_le_bytes(b)
}
fn u64_from(b: [u8; 8]) -> u64 {
u64::from_le_bytes(b)
}
fn u128_from(b: [u8; 16]) -> u128 {
u128::from_le_bytes(b)
}
fn u16_to(n: u16) -> [u8; 2] {
n.to_le_bytes()
}
fn u32_to(n: u32) -> [u8; 4] {
n.to_le_bytes()
}
fn u64_to(n: u64) -> [u8; 8] {
n.to_le_bytes()
}
fn u128_to(n: u128) -> [u8; 16] {
n.to_le_bytes()
}
}
impl ByteOrder for BigEndian {
fn u16_from(b: [u8; 2]) -> u16 {
u16::from_be_bytes(b)
}
fn u32_from(b: [u8; 4]) -> u32 {
u32::from_be_bytes(b)
}
fn u64_from(b: [u8; 8]) -> u64 {
u64::from_be_bytes(b)
}
fn u128_from(b: [u8; 16]) -> u128 {
u128::from_be_bytes(b)
}
fn u16_to(n: u16) -> [u8; 2] {
n.to_be_bytes()
}
fn u32_to(n: u32) -> [u8; 4] {
n.to_be_bytes()
}
fn u64_to(n: u64) -> [u8; 8] {
n.to_be_bytes()
}
fn u128_to(n: u128) -> [u8; 16] {
n.to_be_bytes()
}
}
pub trait WriteBytesExt: Write {
fn write_u8(&mut self, n: u8) -> Result<()> {
self.write_all(&[n])?;
Ok(())
}
fn write_i8(&mut self, n: i8) -> Result<()> {
self.write_all(&n.to_le_bytes())?;
Ok(())
}
fn write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()> {
self.write_all(&T::u16_to(n))?;
Ok(())
}
fn write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
self.write_all(&T::u32_to(n))?;
Ok(())
}
fn write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
self.write_all(&T::u64_to(n))?;
Ok(())
}
fn write_u128<T: ByteOrder>(&mut self, n: u128) -> Result<()> {
self.write_all(&T::u128_to(n))?;
Ok(())
}
fn write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()> {
self.write_u32::<T>(n.to_bits())
}
fn write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()> {
self.write_u64::<T>(n.to_bits())
}
}
impl<W: Write + ?Sized> WriteBytesExt for W {}
pub trait ReadBytesExt: Read {
fn read_u8(&mut self) -> Result<u8> {
let mut b = [0u8; 1];
self.read_exact(&mut b)?;
Ok(u8::from_le_bytes(b))
}
fn read_i8(&mut self) -> Result<i8> {
let mut b = [0u8; 1];
self.read_exact(&mut b)?;
Ok(i8::from_le_bytes(b))
}
fn read_u16<T: ByteOrder>(&mut self) -> Result<u16> {
let mut b = [0u8; 2];
self.read_exact(&mut b)?;
Ok(T::u16_from(b))
}
fn read_u32<T: ByteOrder>(&mut self) -> Result<u32> {
let mut b = [0u8; 4];
self.read_exact(&mut b)?;
Ok(T::u32_from(b))
}
fn read_u64<T: ByteOrder>(&mut self) -> Result<u64> {
let mut b = [0u8; 8];
self.read_exact(&mut b)?;
Ok(T::u64_from(b))
}
fn read_u128<T: ByteOrder>(&mut self) -> Result<u128> {
let mut b = [0u8; 16];
self.read_exact(&mut b)?;
Ok(T::u128_from(b))
}
fn read_f32<T: ByteOrder>(&mut self) -> Result<f32> {
Ok(f32::from_bits(self.read_u32::<T>()?))
}
fn read_f64<T: ByteOrder>(&mut self) -> Result<f64> {
Ok(f64::from_bits(self.read_u64::<T>()?))
}
}
impl<R: Read + ?Sized> ReadBytesExt for R {}
#[cfg(not(feature = "std"))]
impl Write for alloc::vec::Vec<u8> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
self.extend_from_slice(buf);
Ok(())
}
}
#[cfg(not(feature = "std"))]
impl Read for &[u8] {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let n = buf.len().min(self.len());
let (head, rest) = self.split_at(n);
let (dst, _) = buf.split_at_mut(n);
dst.copy_from_slice(head);
*self = rest;
Ok(n)
}
}
#[cfg(feature = "std")]
pub use std::io::Cursor;
#[cfg(not(feature = "std"))]
pub struct Cursor<T> {
inner: T,
pos: u64,
}
#[cfg(not(feature = "std"))]
impl<T> Cursor<T> {
pub const fn new(inner: T) -> Self {
Self { inner, pos: 0 }
}
#[must_use]
pub const fn position(&self) -> u64 {
self.pos
}
pub const fn set_position(&mut self, pos: u64) {
self.pos = pos;
}
pub fn into_inner(self) -> T {
self.inner
}
pub const fn get_ref(&self) -> &T {
&self.inner
}
pub const fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
}
#[cfg(not(feature = "std"))]
impl<T: AsRef<[u8]>> Read for Cursor<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let inner = self.inner.as_ref();
let start = (self.pos as usize).min(inner.len());
let (_, remaining) = inner.split_at(start);
let n = buf.len().min(remaining.len());
let (src, _) = remaining.split_at(n);
let (dst, _) = buf.split_at_mut(n);
dst.copy_from_slice(src);
self.pos += n as u64;
Ok(n)
}
}
#[cfg(not(feature = "std"))]
impl<T: AsRef<[u8]>> Seek for Cursor<T> {
fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
let len = self.inner.as_ref().len() as u64;
let new = match pos {
SeekFrom::Start(n) => n,
SeekFrom::End(off) => len.saturating_add_signed(off),
SeekFrom::Current(off) => self.pos.saturating_add_signed(off),
};
self.pos = new;
Ok(new)
}
}
#[cfg(not(feature = "std"))]
impl Write for Cursor<alloc::vec::Vec<u8>> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let pos = self.pos as usize;
if pos > self.inner.len() {
self.inner.resize(pos, 0);
}
let end = pos + buf.len();
if end > self.inner.len() {
self.inner.resize(end, 0);
}
let (_, tail) = self.inner.split_at_mut(pos);
let (dst, _) = tail.split_at_mut(buf.len());
dst.copy_from_slice(buf);
self.pos = end as u64;
Ok(buf.len())
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
#[cfg(feature = "std")]
pub use std::io::BufReader;
#[cfg(not(feature = "std"))]
pub struct BufReader<R: Read> {
inner: R,
buf: alloc::vec::Vec<u8>,
pos: usize,
cap: usize,
}
#[cfg(not(feature = "std"))]
impl<R: Read> BufReader<R> {
pub fn new(inner: R) -> Self {
Self::with_capacity(8 * 1024, inner)
}
pub fn with_capacity(capacity: usize, inner: R) -> Self {
Self {
inner,
buf: alloc::vec![0u8; capacity],
pos: 0,
cap: 0,
}
}
pub fn get_mut(&mut self) -> &mut R {
&mut self.inner
}
pub fn get_ref(&self) -> &R {
&self.inner
}
}
#[cfg(not(feature = "std"))]
impl<R: Read> Read for BufReader<R> {
fn read(&mut self, dest: &mut [u8]) -> Result<usize> {
if self.pos >= self.cap && dest.len() >= self.buf.len() {
return self.inner.read(dest);
}
let n = {
let available = self.fill_buf()?;
let n = available.len().min(dest.len());
let (src, _) = available.split_at(n);
let (dst, _) = dest.split_at_mut(n);
dst.copy_from_slice(src);
n
};
self.consume(n);
Ok(n)
}
}
#[cfg(not(feature = "std"))]
impl<R: Read> BufRead for BufReader<R> {
fn fill_buf(&mut self) -> Result<&[u8]> {
if self.pos >= self.cap {
self.cap = self.inner.read(&mut self.buf)?;
self.pos = 0;
}
let (_, rest) = self.buf.split_at(self.pos);
let (out, _) = rest.split_at(self.cap - self.pos);
Ok(out)
}
fn consume(&mut self, amt: usize) {
self.pos = (self.pos + amt).min(self.cap);
}
}
#[cfg(not(feature = "std"))]
impl<R: Read + Seek> Seek for BufReader<R> {
fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
self.pos = 0;
self.cap = 0;
self.inner.seek(pos)
}
}
#[cfg(feature = "std")]
pub use std::io::BufWriter;
#[cfg(not(feature = "std"))]
pub struct BufWriter<W: Write> {
inner: W,
buf: alloc::vec::Vec<u8>,
}
#[cfg(not(feature = "std"))]
impl<W: Write> BufWriter<W> {
pub fn new(inner: W) -> Self {
Self::with_capacity(8 * 1024, inner)
}
pub fn with_capacity(capacity: usize, inner: W) -> Self {
Self {
inner,
buf: alloc::vec::Vec::with_capacity(capacity),
}
}
pub fn get_mut(&mut self) -> &mut W {
&mut self.inner
}
pub fn get_ref(&self) -> &W {
&self.inner
}
fn flush_buf(&mut self) -> Result<()> {
if !self.buf.is_empty() {
self.inner.write_all(&self.buf)?;
self.buf.clear();
}
Ok(())
}
}
#[cfg(not(feature = "std"))]
impl<W: Write> Write for BufWriter<W> {
fn write(&mut self, data: &[u8]) -> Result<usize> {
if self.buf.len() + data.len() > self.buf.capacity() {
self.flush_buf()?;
}
if data.len() >= self.buf.capacity() {
self.inner.write(data)
} else {
self.buf.extend_from_slice(data);
Ok(data.len())
}
}
fn flush(&mut self) -> Result<()> {
self.flush_buf()?;
self.inner.flush()
}
}
#[cfg(not(feature = "std"))]
impl<W: Write + Seek> Seek for BufWriter<W> {
fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
self.flush_buf()?;
self.inner.seek(pos)
}
}
#[cfg(not(feature = "std"))]
impl<W: Write> Drop for BufWriter<W> {
fn drop(&mut self) {
let _ = self.flush_buf();
}
}
#[cfg(test)]
mod tests;