use std::cell::RefCell;
use std::io::{BufRead, BufReader, BufWriter, Cursor, IoSlice, IoSliceMut, Read, Result, Write};
use foundation_nostd::comp::basic::{Mutex, RwLock};
use std::rc::Rc;
use std::sync::atomic::AtomicPtr;
use std::sync::Arc;
use crate::err;
use derive_more::derive::From;
pub trait ReadTimeoutOperations: Read {
fn read_timeout_into(
&mut self,
buf: &mut [u8],
timeout: std::time::Duration,
) -> std::result::Result<usize, std::io::Error>;
fn set_read_timeout_as(
&mut self,
timeout: std::time::Duration,
) -> std::result::Result<(), std::io::Error>;
fn get_current_read_timeout(
&self,
) -> std::result::Result<Option<std::time::Duration>, std::io::Error>;
}
pub trait BufferCapacity {
fn read_buffer(&self) -> &[u8];
fn read_capacity(&self) -> usize;
fn buffer_length(&self) -> usize {
self.read_buffer().len()
}
}
pub struct BufferedReader<T: ?Sized> {
inner: BufReader<T>,
}
impl<T: Read> BufferedReader<T> {
pub fn with_capacity(capacity: usize, inner: T) -> Self {
Self {
inner: BufReader::with_capacity(capacity, inner),
}
}
pub fn new(inner: T) -> Self {
Self {
inner: BufReader::new(inner),
}
}
}
impl<T: Read + Write> BufferedReader<BufferedWriter<T>> {
pub fn get_core_ref(&self) -> &T {
self.inner.get_ref().get_inner_ref()
}
pub fn get_core_mut(&mut self) -> &mut T {
self.inner.get_mut().get_inner_mut()
}
}
impl<T: ReadTimeoutOperations> ReadTimeoutOperations for BufferedReader<T> {
fn read_timeout_into(
&mut self,
buf: &mut [u8],
timeout: std::time::Duration,
) -> std::result::Result<usize, std::io::Error> {
self.inner.get_mut().read_timeout_into(buf, timeout)
}
fn set_read_timeout_as(
&mut self,
timeout: std::time::Duration,
) -> std::result::Result<(), std::io::Error> {
self.inner.get_mut().set_read_timeout_as(timeout)
}
fn get_current_read_timeout(
&self,
) -> std::result::Result<Option<std::time::Duration>, std::io::Error> {
self.inner.get_ref().get_current_read_timeout()
}
}
impl<T: Read> BufferedReader<T> {
pub fn get_ref(&self) -> &BufReader<T> {
&self.inner
}
pub fn get_mut(&mut self) -> &mut BufReader<T> {
&mut self.inner
}
pub fn get_inner_ref(&self) -> &T {
self.inner.get_ref()
}
pub fn get_inner_mut(&mut self) -> &mut T {
self.inner.get_mut()
}
pub fn capacity(&mut self) -> usize {
self.inner.capacity()
}
pub fn buffer(&self) -> &[u8] {
self.inner.buffer()
}
pub fn buffer_len(&self) -> usize {
self.inner.buffer().len()
}
pub fn consume(&mut self, amount: usize) {
self.inner.consume(amount);
}
}
impl<T: BufferCapacity> BufferCapacity for BufferedReader<T> {
fn read_buffer(&self) -> &[u8] {
self.inner.buffer()
}
fn read_capacity(&self) -> usize {
self.inner.capacity()
}
}
impl<T: Read + ?Sized> BufRead for BufferedReader<T> {
fn fill_buf(&mut self) -> Result<&[u8]> {
self.inner.fill_buf()
}
fn consume(&mut self, amt: usize) {
self.inner.consume(amt);
}
}
impl<T: Read + ?Sized> Read for BufferedReader<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
self.inner.read(buf)
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
self.inner.read_vectored(bufs)
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
self.inner.read_exact(buf)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
self.inner.read_to_end(buf)
}
fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
self.inner.read_to_string(buf)
}
}
impl<T: Write + ?Sized> Write for BufferedReader<T> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.inner.get_mut().write(buf)
}
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
self.inner.get_mut().write_all(buf)
}
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
self.inner.get_mut().write_vectored(bufs)
}
fn flush(&mut self) -> Result<()> {
self.inner.get_mut().flush()
}
}
pub struct BufferedWriter<T: ?Sized + Write> {
inner: BufWriter<T>,
}
impl<T: Write> BufferedWriter<T> {
pub fn new(inner: T) -> Self {
Self {
inner: BufWriter::new(inner),
}
}
pub fn with_capacity(capacity: usize, inner: T) -> Self {
Self {
inner: BufWriter::with_capacity(capacity, inner),
}
}
}
impl<T: ReadTimeoutOperations + Write> ReadTimeoutOperations for BufferedWriter<T> {
fn read_timeout_into(
&mut self,
buf: &mut [u8],
timeout: std::time::Duration,
) -> std::result::Result<usize, std::io::Error> {
self.inner.get_mut().read_timeout_into(buf, timeout)
}
fn set_read_timeout_as(
&mut self,
timeout: std::time::Duration,
) -> std::result::Result<(), std::io::Error> {
self.inner.get_mut().set_read_timeout_as(timeout)
}
fn get_current_read_timeout(
&self,
) -> std::result::Result<Option<std::time::Duration>, std::io::Error> {
self.inner.get_ref().get_current_read_timeout()
}
}
impl<T: Read + Write + BufferCapacity> BufferedWriter<T> {
pub fn read_capacity(&mut self) -> usize {
self.inner.get_ref().read_capacity()
}
pub fn read_buffer(&self) -> &[u8] {
self.inner.get_ref().read_buffer()
}
}
impl<T: Read + Write> BufferedWriter<BufferedReader<T>> {
pub fn get_core_ref(&self) -> &T {
self.inner.get_ref().get_inner_ref()
}
pub fn get_core_mut(&mut self) -> &mut T {
self.inner.get_mut().get_inner_mut()
}
}
impl<T: Write> BufferedWriter<T> {
pub fn get_ref(&self) -> &BufWriter<T> {
&self.inner
}
pub fn get_mut(&mut self) -> &mut BufWriter<T> {
&mut self.inner
}
pub fn get_inner_ref(&self) -> &T {
self.inner.get_ref()
}
pub fn get_inner_mut(&mut self) -> &mut T {
self.inner.get_mut()
}
pub fn capacity(&mut self) -> usize {
self.inner.capacity()
}
pub fn buffer(&self) -> &[u8] {
self.inner.buffer()
}
}
impl<T: Write + ?Sized> Write for BufferedWriter<T> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.inner.write(buf)
}
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
self.inner.write_all(buf)
}
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
self.inner.write_vectored(bufs)
}
fn flush(&mut self) -> Result<()> {
self.inner.flush()
}
}
impl<T: Write + Read + ?Sized> Read for BufferedWriter<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
self.inner.get_mut().read(buf)
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
self.inner.get_mut().read_vectored(bufs)
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
self.inner.get_mut().read_exact(buf)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
self.inner.get_mut().read_to_end(buf)
}
fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
self.inner.get_mut().read_to_string(buf)
}
}
impl<T: Write + BufRead + ?Sized> BufRead for BufferedWriter<T> {
fn fill_buf(&mut self) -> Result<&[u8]> {
self.inner.get_mut().fill_buf()
}
fn consume(&mut self, amt: usize) {
self.inner.get_mut().consume(amt);
}
}
impl<T: Write + BufRead + BufferCapacity> PeekableReadStream for BufferedWriter<T> {
fn peek(&mut self, buf: &mut [u8]) -> std::result::Result<usize, PeekError> {
if buf.len() > self.get_inner_ref().read_capacity() {
return Err(PeekError::BiggerThanCapacity {
requested: buf.len(),
buffer_capacity: self.get_inner_ref().read_capacity(),
});
}
let mut last_len = 0;
while self.read_buffer().len() < buf.len() {
self.inner.get_mut().fill_buf()?;
let current_len = self.get_inner_ref().read_buffer().len();
if last_len == current_len {
break;
}
last_len = current_len;
}
let buffer = self.get_inner_ref().read_buffer();
let ending = if buffer.len() < buf.len() {
buffer.len()
} else {
buf.len()
};
for (index, elem) in buffer[0..ending].iter().enumerate() {
buf[index] = *elem;
}
Ok(ending)
}
}
pub type BufferedStream<T> = BufferedWriter<BufferedReader<T>>;
pub fn buffered_stream<T: Write + Read>(inner: T) -> BufferedStream<T> {
BufferedWriter::new(BufferedReader::new(inner))
}
pub fn buffered_stream_with_capacity<T: Write + Read>(
capacity: usize,
inner: T,
) -> BufferedStream<T> {
BufferedWriter::with_capacity(capacity, BufferedReader::with_capacity(capacity, inner))
}
#[derive(From, Debug)]
pub enum PeekError {
ZeroLengthNotAllowed,
NotSupported,
LockAcquisitionError,
BiggerThanCapacity {
requested: usize,
buffer_capacity: usize,
},
IOError(std::io::Error),
}
impl std::error::Error for PeekError {}
impl core::fmt::Display for PeekError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:?}")
}
}
pub trait PeekableReadStream: Read {
fn peek(&mut self, buf: &mut [u8]) -> std::result::Result<usize, PeekError>;
}
pub trait SplitReadStream: Read + Sized {
fn split_connection(&self) -> std::io::Result<Self>;
}
impl<T: Read> PeekableReadStream for BufferedReader<T> {
fn peek(&mut self, buf: &mut [u8]) -> std::result::Result<usize, PeekError> {
if buf.len() > self.inner.capacity() {
return Err(PeekError::BiggerThanCapacity {
requested: buf.len(),
buffer_capacity: self.inner.capacity(),
});
}
let mut last_len = 0;
while self.inner.buffer().len() < buf.len() {
self.inner.fill_buf()?;
let current_len = self.inner.buffer().len();
if last_len == current_len {
break;
}
last_len = current_len;
}
let buffer = self.inner.buffer();
let ending = if buffer.len() < buf.len() {
buffer.len()
} else {
buf.len()
};
for (index, elem) in buffer[0..ending].iter().enumerate() {
buf[index] = *elem;
}
Ok(ending)
}
}
pub enum OwnedReader<T: Read> {
RefCell(Rc<RefCell<T>>),
Atomic(Arc<AtomicPtr<T>>),
Sync(Arc<Mutex<T>>),
RWrite(Arc<RwLock<T>>),
}
impl<T: Read> OwnedReader<T> {
pub fn rwrite(reader: Arc<RwLock<T>>) -> Self {
Self::RWrite(reader)
}
pub fn sync(reader: Arc<Mutex<T>>) -> Self {
Self::Sync(reader)
}
pub fn atomic(reader: &mut T) -> Self {
Self::Atomic(Arc::new(AtomicPtr::new(reader)))
}
pub fn ref_cell(reader: Rc<RefCell<T>>) -> Self {
Self::RefCell(reader)
}
}
impl<T: Read> OwnedReader<T> {
pub fn do_ref<F, V>(&self, caller: F) -> V
where
F: Fn(&T) -> V,
{
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
(caller)(atomic_reader)
}
}
Self::Sync(core) => {
let guard = core.lock().expect("can acquire");
(caller)(&guard)
}
Self::RWrite(core) => {
let guard = core.read().expect("can acquire");
(caller)(&guard)
}
Self::RefCell(core) => {
let guard = core.borrow();
(caller)(&guard)
}
}
}
pub fn do_once<F, V>(&self, caller: F) -> V
where
F: FnOnce(&T) -> V,
{
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
(caller)(atomic_reader)
}
}
Self::Sync(core) => {
let guard = core.lock().expect("can acquire");
(caller)(&guard)
}
Self::RWrite(core) => {
let guard = core.read().expect("can acquire");
(caller)(&guard)
}
Self::RefCell(core) => {
let guard = core.borrow();
(caller)(&guard)
}
}
}
pub fn do_once_mut<F, V>(&self, caller: F) -> V
where
F: FnOnce(&mut T) -> V,
{
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
(caller)(atomic_reader)
}
}
Self::Sync(core) => {
let mut guard = core.lock().expect("can acquire");
(caller)(&mut *guard)
}
Self::RWrite(core) => {
let mut guard = core.write().expect("can acquire");
(caller)(&mut *guard)
}
Self::RefCell(core) => {
let mut guard = core.borrow_mut();
(caller)(&mut *guard)
}
}
}
pub fn do_mut<F, V>(&self, mut caller: F) -> V
where
F: FnMut(&mut T) -> V,
{
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
(caller)(atomic_reader)
}
}
Self::Sync(core) => {
let mut guard = core.lock().expect("can acquire");
(caller)(&mut guard)
}
Self::RWrite(core) => {
let mut guard = core.write().expect("can acquire");
(caller)(&mut guard)
}
Self::RefCell(core) => {
let mut guard = core.borrow_mut();
(caller)(&mut guard)
}
}
}
}
impl<T: Read> Clone for OwnedReader<T> {
fn clone(&self) -> Self {
match self {
Self::Atomic(core) => Self::Atomic(Arc::clone(core)),
Self::RWrite(core) => Self::RWrite(Arc::clone(core)),
Self::RefCell(core) => Self::RefCell(core.clone()),
Self::Sync(core) => Self::Sync(core.clone()),
}
}
}
impl<T: Read + Write> Write for OwnedReader<T> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
atomic_reader.write(buf)
}
}
Self::Sync(core) => {
let mut guard = core.lock().expect("can acquire");
guard.write(buf)
}
Self::RWrite(core) => {
let mut guard = core.write().expect("can acquire");
guard.write(buf)
}
Self::RefCell(core) => {
let mut guard = core.borrow_mut();
guard.write(buf)
}
}
}
fn flush(&mut self) -> Result<()> {
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
atomic_reader.flush()
}
}
Self::Sync(core) => {
let mut guard = core.lock().expect("can acquire");
guard.flush()
}
Self::RWrite(core) => {
let mut guard = core.write().expect("can acquire");
guard.flush()
}
Self::RefCell(core) => {
let mut guard = core.borrow_mut();
guard.flush()
}
}
}
}
impl<T: ReadTimeoutOperations> ReadTimeoutOperations for OwnedReader<T> {
fn read_timeout_into(
&mut self,
buf: &mut [u8],
timeout: std::time::Duration,
) -> std::result::Result<usize, std::io::Error> {
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
atomic_reader.read_timeout_into(buf, timeout)
}
}
Self::Sync(core) => {
let mut guard = core.lock().expect("can acquire");
guard.read_timeout_into(buf, timeout)
}
Self::RWrite(core) => {
let mut guard = core.write().expect("can acquire");
guard.read_timeout_into(buf, timeout)
}
Self::RefCell(core) => {
let mut guard = core.borrow_mut();
guard.read_timeout_into(buf, timeout)
}
}
}
fn set_read_timeout_as(
&mut self,
timeout: std::time::Duration,
) -> std::result::Result<(), std::io::Error> {
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
atomic_reader.set_read_timeout_as(timeout)
}
}
Self::Sync(core) => {
let mut guard = core.lock().expect("can acquire");
guard.set_read_timeout_as(timeout)
}
Self::RWrite(core) => {
let mut guard = core.write().expect("can acquire");
guard.set_read_timeout_as(timeout)
}
Self::RefCell(core) => {
let mut guard = core.borrow_mut();
guard.set_read_timeout_as(timeout)
}
}
}
fn get_current_read_timeout(
&self,
) -> std::result::Result<Option<std::time::Duration>, std::io::Error> {
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
atomic_reader.get_current_read_timeout()
}
}
Self::Sync(core) => {
let guard = core.lock().expect("can acquire");
guard.get_current_read_timeout()
}
Self::RWrite(core) => {
let guard = core.write().expect("can acquire");
guard.get_current_read_timeout()
}
Self::RefCell(core) => {
let guard = core.borrow_mut();
guard.get_current_read_timeout()
}
}
}
}
impl<T: Read> Read for OwnedReader<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
atomic_reader.read(buf)
}
}
Self::Sync(core) => {
let mut guard = core.lock().expect("can acquire");
guard.read(buf)
}
Self::RWrite(core) => {
let mut guard = core.write().expect("can acquire");
guard.read(buf)
}
Self::RefCell(core) => {
let mut guard = core.borrow_mut();
guard.read(buf)
}
}
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
atomic_reader.read_vectored(bufs)
}
}
Self::Sync(core) => {
let mut guard = core.lock().expect("can acquire");
guard.read_vectored(bufs)
}
Self::RWrite(core) => {
let mut guard = core.write().expect("can acquire");
guard.read_vectored(bufs)
}
Self::RefCell(core) => {
let mut guard = core.borrow_mut();
guard.read_vectored(bufs)
}
}
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
atomic_reader.read_exact(buf)
}
}
Self::Sync(core) => {
let mut guard = core.lock().expect("can acquire");
guard.read_exact(buf)
}
Self::RWrite(core) => {
let mut guard = core.write().expect("can acquire");
guard.read_exact(buf)
}
Self::RefCell(core) => {
let mut guard = core.borrow_mut();
guard.read_exact(buf)
}
}
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
atomic_reader.read_to_end(buf)
}
}
Self::Sync(core) => {
let mut guard = core.lock().expect("can acquire");
guard.read_to_end(buf)
}
Self::RWrite(core) => {
let mut guard = core.write().expect("can acquire");
guard.read_to_end(buf)
}
Self::RefCell(core) => {
let mut guard = core.borrow_mut();
guard.read_to_end(buf)
}
}
}
fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
match self {
Self::Atomic(core) => {
let ptr = core.load(std::sync::atomic::Ordering::Acquire);
unsafe {
let atomic_reader: &mut T = &mut *ptr;
atomic_reader.read_to_string(buf)
}
}
Self::Sync(core) => {
let mut guard = core.lock().expect("can acquire");
guard.read_to_string(buf)
}
Self::RWrite(core) => {
let mut guard = core.write().expect("can acquire");
guard.read_to_string(buf)
}
Self::RefCell(core) => {
let mut guard = core.borrow_mut();
guard.read_to_string(buf)
}
}
}
}
pub const DEFAULT_READ_SIZE: usize = if cfg!(target_os = "espidf") {
512
} else {
8 * 1024
};
pub trait IsUnixTransport {
fn is_unix(&self) -> bool;
fn should_pool(&self) -> bool {
!self.is_unix()
}
}
pub struct SharedByteBufferStream<T: Read>(OwnedReader<ByteBufferPointer<T>>);
impl<T: Read> core::fmt::Debug for SharedByteBufferStream<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.0.do_once_mut(|inner| {
f.debug_struct("SharedByteBufferStream")
.field("pull_amount", &inner.pull_amount)
.field("buffer_len", &inner.buffer.len())
.field("pos", &inner.pos)
.field("peek_pos", &inner.peek_pos)
.field("distance", &inner.distance())
.finish()
})
}
}
impl<T: Read> SharedByteBufferStream<T> {
pub fn do_ref<F, V>(&self, caller: F) -> V
where
F: Fn(&ByteBufferPointer<T>) -> V,
{
self.0.do_ref(caller)
}
pub fn do_once<F, V>(&self, caller: F) -> V
where
F: FnOnce(&ByteBufferPointer<T>) -> V,
{
self.0.do_once(caller)
}
pub fn do_once_mut<F, V>(&self, caller: F) -> V
where
F: FnOnce(&mut ByteBufferPointer<T>) -> V,
{
self.0.do_once_mut(caller)
}
pub fn do_mut<F, V>(&self, caller: F) -> V
where
F: FnMut(&mut ByteBufferPointer<T>) -> V,
{
self.0.do_mut(caller)
}
pub fn read_line(&mut self, buf: &mut String) -> std::io::Result<usize> {
self.0.do_once_mut(|inner| inner.read_line(buf))
}
pub fn probe(&mut self) -> std::io::Result<usize> {
self.0.do_once_mut(|inner| {
if inner.is_empty_or_consumed() {
let _ = inner.fill_up()?;
}
Ok(inner.remaining())
})
}
#[must_use]
pub fn is_unix(&self) -> bool
where
T: IsUnixTransport,
{
self.0.do_ref(|bbp| bbp.with_inner(|raw| raw.is_unix()))
}
#[must_use]
pub fn should_pool(&self) -> bool
where
T: IsUnixTransport,
{
self.0.do_ref(|bbp| bbp.with_inner(|raw| raw.should_pool()))
}
pub fn with_inner_ref<V>(&self, f: impl Fn(&T) -> V) -> V {
self.0.do_ref(|bbp| bbp.with_inner(|raw| f(raw)))
}
}
impl<T: Read> Clone for SharedByteBufferStream<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T: Read> SharedByteBufferStream<T> {
pub fn ref_cell(reader: T) -> Self {
let wrapped_reader = OwnedReader::ref_cell(Rc::new(RefCell::new(reader)));
let byte_reader = ByteBufferPointer::new(DEFAULT_READ_SIZE, wrapped_reader);
Self(OwnedReader::ref_cell(Rc::new(RefCell::new(byte_reader))))
}
pub fn ref_cell_with_capacity(capacity: usize, reader: T) -> Self {
let wrapped_reader = OwnedReader::ref_cell(Rc::new(RefCell::new(reader)));
let byte_reader = ByteBufferPointer::new(capacity, wrapped_reader);
Self(OwnedReader::ref_cell(Rc::new(RefCell::new(byte_reader))))
}
pub fn rwrite(reader: T) -> Self {
let wrapped_reader = OwnedReader::rwrite(Arc::new(RwLock::new(reader)));
let byte_reader = ByteBufferPointer::new(DEFAULT_READ_SIZE, wrapped_reader);
Self(OwnedReader::rwrite(Arc::new(RwLock::new(byte_reader))))
}
pub fn rwrite_with_capacity(capacity: usize, reader: T) -> Self {
let wrapped_reader = OwnedReader::rwrite(Arc::new(RwLock::new(reader)));
let byte_reader = ByteBufferPointer::new(capacity, wrapped_reader);
Self(OwnedReader::rwrite(Arc::new(RwLock::new(byte_reader))))
}
pub fn sync(reader: &Arc<Mutex<T>>) -> Self {
let wrapped_reader = OwnedReader::sync(Arc::clone(reader));
let byte_reader = ByteBufferPointer::new(DEFAULT_READ_SIZE, wrapped_reader);
Self(OwnedReader::sync(Arc::new(Mutex::new(byte_reader))))
}
}
impl<T: Read> SharedByteBufferStream<BufferedReader<T>> {
pub fn with_owned_reader(reader: T) -> Self {
let wrapped_reader = BufferedReader::new(reader);
Self::rwrite(wrapped_reader)
}
}
impl<T: Read> SharedByteBufferStream<BufferedReader<T>> {
pub fn with_buffered_owned_reader(reader: T) -> Self {
Self::rwrite(BufferedReader::new(reader))
}
}
impl<T: Read> PeekableReadStream for SharedByteBufferStream<T> {
fn peek(&mut self, buf: &mut [u8]) -> std::result::Result<usize, PeekError> {
self.0
.do_once_mut(|binding| match binding.peekby(buf.len()) {
Ok(state) => match state {
PeekState::Request(data) | PeekState::Stalled(data) => {
let ending = if buf.len() > data.len() {
data.len()
} else {
buf.len()
};
for (index, elem) in data[0..ending].iter().enumerate() {
buf[index] = *elem;
}
Ok(data.len())
}
PeekState::ZeroLengthInput
| PeekState::NoNext
| PeekState::LessThanRequested
| PeekState::EndOfBuffered
| PeekState::EndOfFile
| PeekState::Continue => Ok(0),
},
Err(err) => Err(PeekError::IOError(err)),
})
}
}
impl<T: Read + Write> std::io::Write for SharedByteBufferStream<T> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.0.do_once_mut(|binding| binding.write(buf))
}
fn flush(&mut self) -> Result<()> {
self.0.do_once_mut(Write::flush)
}
}
impl<T: ReadTimeoutOperations> ReadTimeoutOperations for SharedByteBufferStream<T> {
fn read_timeout_into(
&mut self,
buf: &mut [u8],
timeout: std::time::Duration,
) -> std::result::Result<usize, std::io::Error> {
self.0
.do_once_mut(|binding| binding.read_timeout_into(buf, timeout))
}
fn set_read_timeout_as(
&mut self,
timeout: std::time::Duration,
) -> std::result::Result<(), std::io::Error> {
self.0
.do_once_mut(|binding| binding.set_read_timeout_as(timeout))
}
fn get_current_read_timeout(
&self,
) -> std::result::Result<Option<std::time::Duration>, std::io::Error> {
self.0
.do_once_mut(|binding| binding.get_current_read_timeout())
}
}
impl<T: Read> std::io::Read for SharedByteBufferStream<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
self.0.do_once_mut(|binding| binding.read(buf))
}
fn read_vectored(&mut self, buf: &mut [IoSliceMut<'_>]) -> Result<usize> {
self.0.do_once_mut(|binding| binding.read_vectored(buf))
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
if buf.is_empty() {
return Ok(());
}
self.0.do_once_mut(|binding| {
let needed = buf.len();
match binding.peekby(needed) {
Ok(PeekState::Request(data)) if data.len() >= needed => binding.read_exact(buf),
Ok(PeekState::Stalled(_)) => Err(crate::err!(
WouldBlock,
"only part of the {needed} bytes have arrived; retry once the peer sends more"
)),
Ok(_) => Err(crate::err!(
UnexpectedEof,
"failed to fill whole buffer: stream ended before {needed} bytes arrived"
)),
Err(err) => Err(err),
}
})
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
self.0.do_once_mut(|binding| binding.read_to_end(buf))
}
fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
self.0.do_once_mut(|binding| binding.read_to_string(buf))
}
}
unsafe impl<T: Read + Send> Send for SharedByteBufferStream<T> {}
unsafe impl<T: Read + Send + Sync> Sync for SharedByteBufferStream<T> {}
pub struct ByteBufferPointer<T: Read> {
reader: OwnedReader<T>,
pull_amount: usize,
peek_pos: usize,
buffer: Vec<u8>,
pos: usize,
}
impl<T: Read> ByteBufferPointer<T> {
#[must_use]
pub fn new(pull_amount: usize, reader: OwnedReader<T>) -> Self {
Self {
buffer: Vec::with_capacity(pull_amount),
pull_amount,
peek_pos: 0,
reader,
pos: 0,
}
}
pub fn from_reader(pull_amount: usize, reader: T) -> Self {
let wrapped_reader = OwnedReader::rwrite(Arc::new(RwLock::new(reader)));
Self::new(pull_amount, wrapped_reader)
}
pub fn reader(reader: T) -> Self {
let wrapped_reader = OwnedReader::rwrite(Arc::new(RwLock::new(reader)));
Self::new(DEFAULT_READ_SIZE, wrapped_reader)
}
pub fn with_inner<F, V>(&self, f: F) -> V
where
F: Fn(&T) -> V,
{
self.reader.do_ref(|inner| f(inner))
}
}
impl<T: ReadTimeoutOperations> ReadTimeoutOperations for ByteBufferPointer<T> {
fn read_timeout_into(
&mut self,
buf: &mut [u8],
timeout: std::time::Duration,
) -> std::result::Result<usize, std::io::Error> {
self.reader.read_timeout_into(buf, timeout)
}
fn set_read_timeout_as(
&mut self,
timeout: std::time::Duration,
) -> std::result::Result<(), std::io::Error> {
self.reader.set_read_timeout_as(timeout)
}
fn get_current_read_timeout(
&self,
) -> std::result::Result<Option<std::time::Duration>, std::io::Error> {
self.reader.get_current_read_timeout()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Data<'a> {
Request(&'a [u8]), Consumed(Vec<u8>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PeekState<'a> {
Request(&'a [u8]), Stalled(&'a [u8]),
LessThanRequested, EndOfBuffered, EndOfFile, NoNext, Continue,
ZeroLengthInput, }
#[allow(unused)]
impl<T: Read> ByteBufferPointer<T> {
#[inline]
#[must_use]
pub fn distance(&self) -> usize {
self.peek_pos - self.pos
}
#[must_use]
pub fn peek_cursor(&self) -> usize {
self.peek_pos
}
#[must_use]
pub fn data_cursor(&self) -> usize {
self.pos
}
#[inline]
#[must_use]
pub fn len(&self) -> usize {
self.buffer.len()
}
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
self.buffer.len() == 0
}
#[inline]
#[must_use]
pub fn remaining(&self) -> usize {
self.buffer.len().saturating_sub(self.pos)
}
#[inline]
#[must_use]
pub fn is_empty_or_consumed(&self) -> bool {
self.remaining() == 0
}
#[inline]
pub fn uncapture(&mut self) {
self.uncapture_by(1);
}
#[inline]
pub fn uncapture_by(&mut self, by: usize) {
if (self.pos - by) > 0 {
self.pos -= by;
} else {
self.pos = 0;
}
}
#[inline]
#[must_use]
pub fn full_scan(&self) -> &[u8] {
&self.buffer[..]
}
#[inline]
#[must_use]
pub fn scan(&self) -> &[u8] {
&self.buffer[self.pos..self.peek_pos]
}
#[inline]
#[must_use]
pub fn greater_than_40_percent(&self) -> bool {
if self.pos == 0 {
return false;
}
let buffer_length = self.buffer.len();
#[allow(clippy::cast_precision_loss)]
let percentage = (buffer_length as f64 / self.pos as f64);
percentage > 0.4
}
#[inline]
pub fn truncate(&mut self, force: bool) {
if self.pos == 0 {
return;
}
let distance = self.peek_pos - self.pos;
let buffer_length = self.buffer.len();
#[allow(clippy::cast_precision_loss)]
let percentage = (buffer_length as f64 / self.pos as f64);
let should_truncate = percentage > 0.7 || force;
if !should_truncate {
return;
}
let slice = &self.buffer[self.pos..buffer_length];
let mut slice_copy = vec![0; slice.len()];
slice_copy.truncate(0);
slice_copy.extend_from_slice(slice);
let slice_length = slice_copy.len();
for (index, byte) in slice_copy.iter().enumerate() {
self.buffer[index] = *byte;
}
self.buffer.truncate(slice_length);
self.pos = 0;
self.peek_pos = self.pos + distance;
}
#[inline]
pub fn fill_up(&mut self) -> std::io::Result<usize> {
let force = self.greater_than_40_percent();
self.truncate(force);
let len = self.buffer.len();
let mut copied = vec![0; self.pull_amount];
let read = match self.reader.read(&mut copied) {
Ok(read_size) => read_size,
Err(err) => {
tracing::trace!("Failed to read data from reader due to: {:?}", &err);
return Err(err);
}
};
self.buffer.extend_from_slice(&copied[0..read]);
Ok(read)
}
#[inline]
pub fn fill_all(&mut self, read_limit: Option<usize>) -> std::io::Result<usize> {
let mut total_read = 0;
let mut copied = vec![0; self.pull_amount];
loop {
let read = self.reader.read(&mut copied)?;
if read == 0 {
break;
}
total_read += read;
if let Some(limited_val) = read_limit {
if limited_val < total_read {
return Err(crate::err!(
Interrupted,
"LimitReadTriggered",
"Crossed read limit {}",
limited_val,
));
}
}
self.buffer.extend_from_slice(&copied[0..read]);
}
Ok(total_read)
}
#[inline]
pub fn forward(&mut self) -> std::io::Result<PeekState<'_>> {
self.forward_by(1)
}
#[inline]
pub fn forward_by(&mut self, by: usize) -> std::io::Result<PeekState<'_>> {
let buffer_length = self.buffer.len();
let new_peek = self.peek_pos + by;
if new_peek > buffer_length {
self.peek_pos = buffer_length;
Ok(PeekState::EndOfBuffered)
} else {
self.peek_pos = new_peek;
Ok(PeekState::Continue)
}
}
#[inline]
pub fn unforward(&mut self) -> std::io::Result<PeekState<'_>> {
self.unforward_by(1)
}
#[inline]
pub fn unforward_by(&mut self, by: usize) -> std::io::Result<PeekState<'_>> {
let new_peek = self.peek_pos - by;
if new_peek <= self.pos {
self.peek_pos = self.pos;
Ok(PeekState::Continue)
} else {
self.peek_pos = new_peek;
Ok(PeekState::Continue)
}
}
pub fn consume_some(&mut self) -> Option<Vec<u8>> {
let from = self.pos;
let until_pos = self.peek_pos;
if from == until_pos {
return None;
}
let slice = &self.buffer[from..until_pos];
let slice_string = String::from_utf8(slice.to_vec());
self.pos = self.peek_pos;
let mut slice_copy = vec![0; slice.len()];
slice_copy.truncate(0);
slice_copy.extend_from_slice(slice);
Some(slice_copy)
}
pub fn consume(&mut self) -> std::io::Result<Vec<u8>> {
match self.consume_some() {
Some(item) => Ok(item),
None => Ok(vec![]),
}
}
pub fn skip(&mut self) {
let from = self.pos;
let until_pos = self.peek_pos;
if from == until_pos {
return;
}
self.pos = self.peek_pos;
}
#[inline]
pub fn peek(&self) -> std::io::Result<PeekState<'_>> {
self.peek_by(1)
}
#[inline]
pub fn peek_by(&self, by: usize) -> std::io::Result<PeekState<'_>> {
let until_pos = self.peek_pos + by;
let buffer_length = self.buffer.len();
if until_pos > buffer_length {
return Ok(PeekState::LessThanRequested);
}
let from = self.peek_pos;
Ok(PeekState::Request(&self.buffer[from..until_pos]))
}
#[inline]
pub fn peek_until<'a>(&'a mut self, signal: &[u8]) -> std::io::Result<PeekState<'a>> {
if signal.is_empty() {
return Ok(PeekState::ZeroLengthInput);
}
let current_peek_pos = self.peek_pos;
loop {
let state = self.peek_by(signal.len())?;
match state {
PeekState::Request(data) => {
if data == signal {
break;
}
}
PeekState::EndOfBuffered | PeekState::LessThanRequested => {
if self.fill_up()? == 0 {
return Ok(PeekState::EndOfFile);
}
continue;
}
PeekState::Continue => continue,
PeekState::EndOfFile => {
return Ok(PeekState::EndOfFile);
}
_ => {
unreachable!("Should never hit this types")
}
}
self.peek_pos += signal.len();
}
self.peek_pos += signal.len();
let slice = &self.buffer[self.pos..self.peek_pos];
self.peek_pos = current_peek_pos;
Ok(PeekState::Request(slice))
}
pub fn peekby2(&mut self, size: usize) -> std::io::Result<&[u8]> {
self.peekby(size).map(|item| match item {
PeekState::Request(inner) | PeekState::Stalled(inner) => Ok(inner),
PeekState::NoNext => Err(crate::err!(UnexpectedEof, "No more data to pull through")),
PeekState::ZeroLengthInput => Err(crate::err!(WriteZero, "Provided zero size request")),
_ => unreachable!("Should not trigger this stage"),
})?
}
#[inline]
pub fn peekby(&mut self, size: usize) -> std::io::Result<PeekState<'_>> {
if size == 0 {
return Ok(PeekState::ZeroLengthInput);
}
let mut stalled = false;
loop {
let available = self.buffer.len().cast_signed() - self.peek_pos.cast_signed();
let rem = size.cast_signed() - available;
if rem <= 0 {
break;
}
match self.fill_up() {
Ok(0) => break,
Ok(_) => {}
Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => {
if available > 0 {
stalled = true;
break;
}
return Err(err);
}
Err(err) => return Err(err),
}
}
let buffer_len = self.buffer.len();
let mut until_pos = self.peek_pos + size;
if until_pos > buffer_len {
until_pos = buffer_len;
}
let slice = &self.buffer[self.peek_pos..until_pos];
if slice.is_empty() {
return Ok(PeekState::NoNext);
}
if stalled && slice.len() < size {
return Ok(PeekState::Stalled(slice));
}
Ok(PeekState::Request(slice))
}
#[inline]
pub fn nextby(&mut self, size: usize) -> std::io::Result<PeekState<'_>> {
if size == 0 {
return Ok(PeekState::ZeroLengthInput);
}
let mut cached_error: Option<std::io::Error> = None;
loop {
let available = self.buffer.len().cast_signed() - self.peek_pos.cast_signed();
let rem = size.cast_signed() - available;
if rem <= 0 {
break;
}
match self.fill_up() {
Ok(fill_size) => {
if fill_size == 0 {
break;
}
}
Err(err) => {
cached_error = Some(err);
break;
}
}
}
let buffer_len = self.buffer.len();
let original_peek = self.peek_pos;
let total_data_left = buffer_len - original_peek;
if total_data_left <= size {
self.peek_pos = buffer_len;
} else {
self.peek_pos = original_peek + size;
}
let slice = &self.buffer[original_peek..self.peek_pos];
if self.peek_pos == original_peek {
if let Some(cached_error) = cached_error.take() {
return Err(cached_error);
}
return Ok(PeekState::NoNext);
}
Ok(PeekState::Request(slice))
}
pub fn read_size(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
if buf.is_empty() {
return Ok(0);
}
let mut cached_error: Option<std::io::Error> = None;
while self.remaining() < buf.len() {
match self.fill_up() {
Ok(0) => break,
Ok(_) => {}
Err(err) => {
cached_error = Some(err);
break;
}
}
}
let available = self.remaining();
if available == 0 {
return match cached_error {
Some(err) => Err(err),
None => Ok(0),
};
}
let copied = available.min(buf.len());
let from = self.pos;
buf[..copied].copy_from_slice(&self.buffer[from..from + copied]);
self.pos = from + copied;
if self.peek_pos < self.pos {
self.peek_pos = self.pos;
}
Ok(copied)
}
pub fn nextby2(&mut self, size: usize) -> std::io::Result<&[u8]> {
self.nextby(size).map(|item| match item {
PeekState::Request(inner) => Ok(inner),
PeekState::NoNext => Err(crate::err!(UnexpectedEof, "No more data to pull through")),
PeekState::ZeroLengthInput => Err(crate::err!(WriteZero, "Provided zero size request")),
_ => unreachable!("Should not trigger this stage"),
})?
}
#[inline]
pub fn next_until<'a>(&'a mut self, signal: &[u8]) -> std::io::Result<PeekState<'a>> {
if signal.is_empty() {
return Ok(PeekState::ZeroLengthInput);
}
loop {
let state = self.peek_by(signal.len())?;
match state {
PeekState::Request(data) => {
if data == signal {
break;
}
}
PeekState::EndOfBuffered | PeekState::LessThanRequested => {
if self.fill_up()? == 0 {
return Ok(PeekState::EndOfFile);
}
continue;
}
PeekState::Continue => continue,
PeekState::EndOfFile => {
return Ok(PeekState::EndOfFile);
}
_ => {
unreachable!("Should never hit this types")
}
}
self.peek_pos += signal.len();
}
self.peek_pos += signal.len();
Ok(PeekState::Request(&self.buffer[self.pos..self.peek_pos]))
}
pub fn next_line(&mut self, buf: &mut String) -> std::io::Result<usize> {
const NEWLINE_SLICE: &[u8] = b"\n";
let read = {
let inner = self.next_until(NEWLINE_SLICE)?;
match inner {
PeekState::Request(c) => {
unsafe {
let buf_vec = buf.as_mut_vec();
buf_vec.extend_from_slice(c);
};
Ok(c.len())
}
PeekState::EndOfFile => Ok(0),
PeekState::ZeroLengthInput => {
Err(crate::err!(WriteZero, "Provided zero size request"))
}
_ => unreachable!("Should never trigger"),
}
};
match read {
Ok(inner) => {
if inner == 0 {
let slice = &self.buffer[self.pos..self.peek_pos];
let slice_length = slice.len();
unsafe {
let mut buf_vec = buf.as_mut_vec();
buf_vec.extend_from_slice(slice);
};
return Ok(slice_length);
}
Ok(inner)
}
Err(err) => Err(err),
}
}
pub fn next_bytes_until(&mut self, target: &[u8], buf: &mut Vec<u8>) -> std::io::Result<usize> {
let read = {
let inner = self.next_until(target)?;
match inner {
PeekState::Request(c) => {
unsafe {
buf.extend_from_slice(c);
};
Ok(c.len())
}
PeekState::EndOfFile => Ok(0),
PeekState::ZeroLengthInput => {
Err(crate::err!(WriteZero, "Provided zero size request"))
}
_ => unreachable!("Should never trigger"),
}
};
match read {
Ok(inner) => {
if inner == 0 {
let slice = &self.buffer[self.pos..self.peek_pos];
let slice_length = slice.len();
unsafe {
buf.extend_from_slice(slice);
};
return Ok(slice_length);
}
Ok(inner)
}
Err(err) => Err(err),
}
}
pub fn read_bytes_until(&mut self, target: &[u8], buf: &mut Vec<u8>) -> std::io::Result<usize> {
let read = {
let inner = self.next_until(target)?;
match inner {
PeekState::Request(c) => {
unsafe {
buf.extend_from_slice(c);
};
Ok(c.len())
}
PeekState::EndOfFile => Ok(0),
PeekState::ZeroLengthInput => {
Err(crate::err!(WriteZero, "Provided zero size request"))
}
_ => unreachable!("Should never trigger"),
}
};
match read {
Ok(inner) => {
if inner == 0 {
let slice = &self.buffer[self.pos..self.peek_pos];
let slice_length = slice.len();
unsafe {
buf.extend_from_slice(slice);
};
self.skip();
return Ok(slice_length);
}
self.skip();
Ok(inner)
}
Err(err) => Err(err),
}
}
pub fn read_line(&mut self, buf: &mut String) -> std::io::Result<usize> {
const NEWLINE_SLICE: &[u8] = b"\n";
let read = {
let inner = self.next_until(NEWLINE_SLICE)?;
match inner {
PeekState::Request(c) => {
match String::from_utf8(c.to_vec()) {
Ok(inner) => {
buf.push_str(&inner);
Ok(inner.len())
}
Err(err) => {
tracing::error!(
"Received invalid utf8 data {:?} with error: {:?}",
&c,
err,
);
buf.extend(c.iter().map(|b| char::from(*b)));
Ok(c.len())
}
}
}
PeekState::EndOfFile => Ok(0),
PeekState::ZeroLengthInput => {
Err(err!(InvalidInput, "Zero length input not allowed"))
}
_ => unreachable!("Should never trigger"),
}
};
match read {
Ok(inner) => {
if inner == 0 {
let slice = &self.buffer[self.pos..self.peek_pos];
let slice_length = slice.len();
unsafe {
let mut buf_vec = buf.as_mut_vec();
buf_vec.extend_from_slice(slice);
};
self.skip();
return Ok(slice_length);
}
self.skip();
Ok(inner)
}
Err(err) => Err(err),
}
}
pub fn read_all(
&mut self,
buf: &mut Vec<u8>,
read_limit: Option<usize>,
) -> std::io::Result<usize> {
self.fill_all(read_limit)?;
let buffer_len = self.buffer.len();
let slice = &self.buffer[self.pos..buffer_len];
let slice_length = slice.len();
buf.extend_from_slice(slice);
self.peek_pos = buffer_len;
self.pos = buffer_len;
Ok(slice_length)
}
}
impl<T: Read + Write> Write for ByteBufferPointer<T> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.reader.write(buf)
}
fn flush(&mut self) -> Result<()> {
self.reader.flush()
}
}
impl<T: Read> Read for ByteBufferPointer<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
self.read_size(buf)
}
}
impl<T: Read> PeekableReadStream for ByteBufferPointer<T> {
fn peek(&mut self, buf: &mut [u8]) -> std::result::Result<usize, PeekError> {
match self.peekby(buf.len()) {
Ok(PeekState::Request(data) | PeekState::Stalled(data)) => {
let copied = data.len().min(buf.len());
buf[..copied].copy_from_slice(&data[..copied]);
Ok(copied)
}
Ok(PeekState::ZeroLengthInput) => Err(PeekError::ZeroLengthNotAllowed),
Ok(
PeekState::NoNext
| PeekState::LessThanRequested
| PeekState::EndOfBuffered
| PeekState::EndOfFile
| PeekState::Continue,
) => Ok(0),
Err(err) => Err(PeekError::IOError(err)),
}
}
}
impl<T: Read> BufferCapacity for ByteBufferPointer<T> {
fn read_buffer(&self) -> &[u8] {
&self.buffer
}
fn read_capacity(&self) -> usize {
self.pull_amount
}
}
pub struct BufferedCapacityCursor<T>(std::io::Cursor<T>);
impl BufferCapacity for BufferedCapacityCursor<&str> {
fn read_buffer(&self) -> &[u8] {
self.0.get_ref().as_bytes()
}
fn read_capacity(&self) -> usize {
self.0.get_ref().len()
}
}
impl BufferCapacity for BufferedCapacityCursor<String> {
fn read_buffer(&self) -> &[u8] {
self.0.get_ref().as_bytes()
}
fn read_capacity(&self) -> usize {
self.0.get_ref().len()
}
}
impl BufferCapacity for BufferedCapacityCursor<&[u8]> {
fn read_buffer(&self) -> &[u8] {
self.0.get_ref()
}
fn read_capacity(&self) -> usize {
self.0.get_ref().len()
}
}
impl BufferCapacity for BufferedCapacityCursor<Vec<u8>> {
fn read_buffer(&self) -> &[u8] {
self.0.get_ref()
}
fn read_capacity(&self) -> usize {
self.0.get_ref().len()
}
}
impl<T> BufferedCapacityCursor<T> {
pub fn new(cursor: std::io::Cursor<T>) -> Self {
Self(cursor)
}
pub fn get_ref(&self) -> &Cursor<T> {
&self.0
}
pub fn get_mut(&mut self) -> &mut Cursor<T> {
&mut self.0
}
pub fn get_inner_ref(&self) -> &T {
self.0.get_ref()
}
pub fn get_inner_mut(&mut self) -> &mut T {
self.0.get_mut()
}
}
#[derive(Clone)]
pub struct SharedBufferWriter {
inner: Arc<Mutex<Vec<u8>>>,
}
impl Write for SharedBufferWriter {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let mut guard = self.inner.lock().expect("SharedBufferWriter lock poisoned");
guard.extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
impl SharedBufferWriter {
pub fn new(inner: Arc<Mutex<Vec<u8>>>) -> Self {
Self { inner }
}
#[must_use]
pub fn clone_arc(&self) -> Arc<Mutex<Vec<u8>>> {
Arc::clone(&self.inner)
}
}
#[derive(Clone)]
pub struct SharedBufferReader {
inner: Arc<Mutex<Vec<u8>>>,
position: usize,
}
impl Read for SharedBufferReader {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let guard = self.inner.lock().expect("SharedBufferReader lock poisoned");
let available = guard.len().saturating_sub(self.position);
if available == 0 {
return Ok(0);
}
let to_read = buf.len().min(available);
buf[..to_read].copy_from_slice(&guard[self.position..self.position + to_read]);
drop(guard);
self.position += to_read;
Ok(to_read)
}
}
impl SharedBufferReader {
pub fn new(inner: Arc<Mutex<Vec<u8>>>) -> Self {
Self { inner, position: 0 }
}
pub fn with_position(inner: Arc<Mutex<Vec<u8>>>, position: usize) -> Self {
Self { inner, position }
}
#[must_use]
pub fn position(&self) -> usize {
self.position
}
#[must_use]
pub fn into_buffered_stream(self) -> SharedByteBufferStream<SharedBufferReadStream> {
SharedByteBufferStream::rwrite(SharedBufferReadStream::new(
Arc::clone(&self.inner),
self.position,
))
}
}
pub struct SharedBufferReadStream {
inner: Arc<Mutex<Vec<u8>>>,
position: usize,
}
impl SharedBufferReadStream {
pub fn new(inner: Arc<Mutex<Vec<u8>>>, position: usize) -> Self {
Self { inner, position }
}
}
impl std::io::Read for SharedBufferReadStream {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let guard = self.inner.lock().expect("SharedBuffer lock poisoned");
let available = guard.len().saturating_sub(self.position);
if available == 0 {
return Ok(0);
}
let to_read = buf.len().min(available);
buf[..to_read].copy_from_slice(&guard[self.position..self.position + to_read]);
drop(guard);
self.position += to_read;
Ok(to_read)
}
}
pub struct SharedBuffer {
inner: Arc<Mutex<Vec<u8>>>,
}
impl SharedBuffer {
#[must_use]
pub fn split() -> (SharedBufferWriter, SharedBufferReader) {
let inner = Arc::new(Mutex::new(Vec::new()));
let writer = SharedBufferWriter::new(Arc::clone(&inner));
let reader = SharedBufferReader::new(inner);
(writer, reader)
}
#[must_use]
pub fn with_initial(initial: &[u8]) -> Self {
let inner = Arc::new(Mutex::new(initial.to_vec()));
Self { inner }
}
#[must_use]
pub fn len(&self) -> usize {
let guard = self.inner.lock().expect("SharedBuffer lock poisoned");
guard.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[must_use]
pub fn clone_arc(&self) -> Arc<Mutex<Vec<u8>>> {
Arc::clone(&self.inner)
}
}
impl Default for SharedBuffer {
fn default() -> Self {
Self {
inner: Arc::new(Mutex::new(Vec::new())),
}
}
}
pub struct SharedWriteReader<T: Read + Write> {
inner: Arc<Mutex<T>>,
}
impl<T: Read + Write> Clone for SharedWriteReader<T> {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
impl<T: Read + Write> SharedWriteReader<T> {
pub fn new(inner: T) -> Self {
Self {
inner: Arc::new(Mutex::new(inner)),
}
}
pub fn from_arc(arc: Arc<Mutex<T>>) -> Self {
Self { inner: arc }
}
#[must_use]
pub fn clone_arc(&self) -> Arc<Mutex<T>> {
Arc::clone(&self.inner)
}
}
impl<T: Read + Write> Read for SharedWriteReader<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let mut guard = self.inner.lock().expect("SharedWriteReader lock poisoned");
guard.read(buf)
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
let mut guard = self.inner.lock().expect("SharedWriteReader lock poisoned");
guard.read_exact(buf)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
let mut guard = self.inner.lock().expect("SharedWriteReader lock poisoned");
guard.read_to_end(buf)
}
fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
let mut guard = self.inner.lock().expect("SharedWriteReader lock poisoned");
guard.read_to_string(buf)
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
let mut guard = self.inner.lock().expect("SharedWriteReader lock poisoned");
guard.read_vectored(bufs)
}
}
impl<T: Read + Write> Write for SharedWriteReader<T> {
fn write(&mut self, buf: &[u8]) -> Result<usize> {
let mut guard = self.inner.lock().expect("SharedWriteReader lock poisoned");
guard.write(buf)
}
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
let mut guard = self.inner.lock().expect("SharedWriteReader lock poisoned");
guard.write_all(buf)
}
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
let mut guard = self.inner.lock().expect("SharedWriteReader lock poisoned");
guard.write_vectored(bufs)
}
fn flush(&mut self) -> Result<()> {
let mut guard = self.inner.lock().expect("SharedWriteReader lock poisoned");
guard.flush()
}
}
unsafe impl<T: Read + Write + Send> Send for SharedWriteReader<T> {}
unsafe impl<T: Read + Write + Send + Sync> Sync for SharedWriteReader<T> {}