|
|
|
@ -32,11 +32,58 @@ pub struct Buffered<T: ?Sized, const SIZE: usize>
|
|
|
|
|
#[pin] stream: T
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<T: ?Sized + AsyncWrite, const SIZE: usize> AsyncWrite for Buffered<T, SIZE>
|
|
|
|
|
#[inline] fn div_mod<V>(a: V, b: V) -> (V, <V as std::ops::Div>::Output, <V as std::ops::Rem>::Output)
|
|
|
|
|
where V: std::ops::Div + std::ops::Rem + Clone
|
|
|
|
|
{
|
|
|
|
|
(a.clone(), a.clone() / b.clone(), a % b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<T: ?Sized, const SIZE: usize> AsyncWrite for Buffered<T, SIZE>
|
|
|
|
|
where T: AsyncWrite
|
|
|
|
|
{
|
|
|
|
|
fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize, io::Error>> {
|
|
|
|
|
|
|
|
|
|
let this = self.project();
|
|
|
|
|
let w = if buf.len() + this.buffer.len() > SIZE {
|
|
|
|
|
// `buf` cannot fit into buffer, push the bytes that can fit.
|
|
|
|
|
let buf = &buf[..(this.buffer.len()-SIZE)];
|
|
|
|
|
this.buffer.extend_from_slice(buf);
|
|
|
|
|
buf.len()
|
|
|
|
|
} else {
|
|
|
|
|
// `buf` can fit into buffer.
|
|
|
|
|
this.buffer.extend_from_slice(&buf[..]);
|
|
|
|
|
buf.len()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Push `SIZE` bytes from buffer,
|
|
|
|
|
loop {
|
|
|
|
|
if this.buffer.len() >= SIZE {
|
|
|
|
|
use futures::ready;
|
|
|
|
|
|
|
|
|
|
match ready!(this.stream.poll_write(cx, &this.buffer[..SIZE])) {
|
|
|
|
|
Ok(n) => {
|
|
|
|
|
this.buffer.drain(0..n);
|
|
|
|
|
},
|
|
|
|
|
x => return Poll::Ready(x),
|
|
|
|
|
//TODO: How to break after this?
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// TODO: How to re-queue for polling?
|
|
|
|
|
todo!()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Poll::Ready(Ok(w))
|
|
|
|
|
/*
|
|
|
|
|
match div_mod(buf.len(), SIZE) {
|
|
|
|
|
// Buffer is equal to `SIZE`
|
|
|
|
|
(sz, _, _) if sz == SIZE => (),
|
|
|
|
|
// Buffer is smaller than `SIZE`
|
|
|
|
|
(sz, 0, x) => (),
|
|
|
|
|
// Buffer is a multiple of SIZE,
|
|
|
|
|
(sz, x, 0) => (),
|
|
|
|
|
}*/
|
|
|
|
|
// TODO: Push `buf` into `self.buffer`. When `self.buffer` is full, write to `self.stream` and clear what's been written.
|
|
|
|
|
todo!()
|
|
|
|
|
}
|
|
|
|
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
|
|
|
|
todo!("Flush any remaining bytes in the buffer to `stream`")
|
|
|
|
@ -53,4 +100,4 @@ impl<T: ?Sized + AsyncWrite, const SIZE: usize> AsyncWrite for Buffered<T, SIZE>
|
|
|
|
|
todo!("How to do the above?")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|