#![cfg(all(feature = "std", feature = "gzip"))]
use std::io::{Cursor, Read, Write};
use compcol::Algorithm;
use compcol::gzip::Gzip;
use compcol::io::{DecoderReader, DecoderWriter, EncoderReader, EncoderWriter};
fn payload(n: usize) -> Vec<u8> {
let mut out = Vec::with_capacity(n);
let phrase = b"The_quick_brown_fox_jumps_over_the_lazy_dog. ";
let mut state: u32 = 0xC0FFEE_u32;
while out.len() < n {
for _ in 0..32 {
state = state.wrapping_mul(1_664_525).wrapping_add(1_013_904_223);
out.push(b"abcdef"[(state as usize) % 6]);
}
out.extend_from_slice(phrase);
}
out.truncate(n);
out
}
#[test]
fn encoder_writer_paired_with_decoder_reader() {
let input = payload(96 * 1024);
let mut w = EncoderWriter::new(Vec::<u8>::new(), Gzip::encoder());
w.write_all(&input).unwrap();
let compressed = w.finish().unwrap();
assert!(compressed.len() < input.len());
let mut r = DecoderReader::new(Cursor::new(&compressed), Gzip::decoder());
let mut decoded = Vec::new();
r.read_to_end(&mut decoded).unwrap();
assert_eq!(decoded, input);
}
#[test]
fn encoder_reader_paired_with_decoder_writer() {
let input = payload(96 * 1024);
let mut r = EncoderReader::new(Cursor::new(input.clone()), Gzip::encoder());
let mut compressed = Vec::new();
r.read_to_end(&mut compressed).unwrap();
let mut w = DecoderWriter::new(Vec::<u8>::new(), Gzip::decoder());
w.write_all(&compressed).unwrap();
let decoded = w.finish().unwrap();
assert_eq!(decoded, input);
}
#[test]
fn encoder_writer_drop_runs_finish() {
let input = b"hello, drop\n";
use std::cell::RefCell;
use std::rc::Rc;
struct SharedSink(Rc<RefCell<Vec<u8>>>);
impl Write for SharedSink {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.0.borrow_mut().extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
let sink = Rc::new(RefCell::new(Vec::new()));
{
let mut w = EncoderWriter::new(SharedSink(sink.clone()), Gzip::encoder());
w.write_all(input).unwrap();
}
let compressed = sink.borrow().clone();
assert!(!compressed.is_empty(), "Drop did not finish encoder");
let mut r = DecoderReader::new(Cursor::new(&compressed), Gzip::decoder());
let mut decoded = Vec::new();
r.read_to_end(&mut decoded).unwrap();
assert_eq!(decoded, input);
}
#[test]
fn decoder_writer_drop_does_not_panic_on_partial_input() {
let _w = DecoderWriter::new(Vec::<u8>::new(), Gzip::decoder());
}
#[cfg(feature = "brotli")]
#[test]
fn brotli_above_old_buggy_size_via_io_adapters() {
use compcol::brotli::Brotli;
let input = payload(1_000_000);
let mut w = EncoderWriter::new(Vec::<u8>::new(), Brotli::encoder());
w.write_all(&input).unwrap();
let compressed = w.finish().unwrap();
let mut r = DecoderReader::new(Cursor::new(&compressed), Brotli::decoder());
let mut decoded = Vec::new();
r.read_to_end(&mut decoded).unwrap();
assert_eq!(decoded.len(), input.len());
assert_eq!(decoded, input);
}
#[test]
fn decoder_reader_handles_small_read_buffers() {
let input = payload(64 * 1024);
let mut w = EncoderWriter::new(Vec::<u8>::new(), Gzip::encoder());
w.write_all(&input).unwrap();
let compressed = w.finish().unwrap();
let mut r = DecoderReader::new(Cursor::new(&compressed), Gzip::decoder());
let mut decoded = Vec::new();
let mut buf = [0u8; 17];
loop {
let n = r.read(&mut buf).unwrap();
if n == 0 {
break;
}
decoded.extend_from_slice(&buf[..n]);
}
assert_eq!(decoded, input);
}
#[cfg(feature = "zlib")]
#[test]
fn decoder_reader_drains_pending_output_when_input_exhausted_zlib() {
use compcol::zlib::Zlib;
let input = b"hello hfsplus decmpfs world!".repeat(8); let compressed = compcol::vec::compress_to_vec::<Zlib>(&input).unwrap();
assert!(compressed.len() < 64);
let mut r = DecoderReader::new(Cursor::new(&compressed), Zlib::decoder());
let mut decoded = Vec::new();
let mut buf = [0u8; 32];
loop {
let n = r.read(&mut buf).unwrap();
if n == 0 {
break;
}
decoded.extend_from_slice(&buf[..n]);
}
assert_eq!(decoded, input);
}
#[cfg(feature = "deflate")]
#[test]
fn decoder_reader_drains_pending_output_when_input_exhausted_deflate() {
use compcol::deflate::Deflate;
let input = b"hello hfsplus decmpfs world!".repeat(8);
let compressed = compcol::vec::compress_to_vec::<Deflate>(&input).unwrap();
let mut r = DecoderReader::new(Cursor::new(&compressed), Deflate::decoder());
let mut decoded = Vec::new();
let mut buf = [0u8; 32];
loop {
let n = r.read(&mut buf).unwrap();
if n == 0 {
break;
}
decoded.extend_from_slice(&buf[..n]);
}
assert_eq!(decoded, input);
}