use std::io::{Result, Write};
use crate::{copier::Copier, ring::RingBuf};
#[derive(Debug)]
pub struct EncodeWriter<W: Write> {
writer: W,
copier: Copier,
ring: RingBuf<1024>,
}
impl<W: Write> EncodeWriter<W> {
pub const fn new(writer: W) -> Self {
Self {
writer,
copier: Copier::new_encode(),
ring: RingBuf::new(),
}
}
pub fn finalize(&mut self) -> Result<()> {
while !self.ring.is_empty() {
if !self.copier.write() && self.copier.copy_from(&mut self.ring)? {
self.copier.encode();
}
if self.copier.write() && self.copier.copy_to(&mut self.writer)? {
self.copier = Copier::new_encode()
}
}
if self.copier.write() {
while !self.copier.copy_to(&mut self.writer)? {}
} else {
let tail = self.copier.encode_tail();
std::io::copy(&mut tail.as_slice(), &mut self.writer)?;
}
Ok(())
}
}
impl<W: Write> Write for EncodeWriter<W> {
fn write(&mut self, mut buf: &[u8]) -> Result<usize> {
let n = self.ring.copy_from_reader(&mut buf)?;
if n == 0 {
self.finalize()?;
return Ok(0);
}
if !self.copier.write() && self.copier.copy_from(&mut self.ring)? {
self.copier.encode();
}
if self.copier.write() && self.copier.copy_to(&mut self.writer)? {
self.copier = Copier::new_encode()
}
Ok(n)
}
fn flush(&mut self) -> Result<()> {
while !self.ring.is_empty() {
if !self.copier.write() && self.copier.copy_from(&mut self.ring)? {
self.copier.encode();
}
if self.copier.write() && self.copier.copy_to(&mut self.writer)? {
self.copier = Copier::new_encode()
}
}
if self.copier.write() {
while !self.copier.copy_to(&mut self.writer)? {}
}
self.writer.flush()?;
Ok(())
}
}
impl<W: Write> Drop for EncodeWriter<W> {
fn drop(&mut self) {
let _ = self.finalize();
}
}