1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use std::io::{self, Write};
use byteorder::{WriteBytesExt, LittleEndian};
pub struct Deflater<W> where W: Write {
writer: Option<W>,
buf: Vec<u8>,
}
impl<W> Deflater<W> where W: Write {
pub fn new(writer: W) -> Deflater<W> {
Deflater {
writer: Some(writer),
buf: Vec::with_capacity(65535),
}
}
pub fn into_inner(mut self) -> io::Result<W> {
try!(self.flush_buf(true));
Ok(self.writer.take().unwrap())
}
fn flush_buf(&mut self, last: bool) -> io::Result<()> {
if self.buf.len() == 0 {
return Ok(());
}
assert!(self.buf.len() <= u16::max_value() as usize);
let len = self.buf.len() as u16;
let nlen = !len;
let writer = self.writer.as_mut().unwrap();
try!(writer.write_u8(if last { 1 } else { 0 }));
try!(writer.write_u16::<LittleEndian>(len));
try!(writer.write_u16::<LittleEndian>(nlen));
try!(writer.write_all(&self.buf));
self.buf.clear();
Ok(())
}
}
impl<W> Write for Deflater<W> where W: Write {
fn write(&mut self, mut buf: &[u8]) -> io::Result<usize> {
let total_written = buf.len();
loop {
if self.buf.len() + buf.len() >= u16::max_value() as usize {
let rest = u16::max_value() as usize - self.buf.len();
self.buf.extend(buf.iter().take(rest).cloned());
buf = &buf[rest..];
try!(self.flush_buf(false));
continue;
} else {
self.buf.extend(buf.iter().cloned());
break;
}
}
Ok(total_written)
}
fn flush(&mut self) -> io::Result<()> {
try!(self.flush_buf(false));
self.writer.as_mut().unwrap().flush()
}
}
impl<W> Drop for Deflater<W> where W: Write {
fn drop(&mut self) {
if self.writer.is_some() {
let _ = self.flush_buf(true);
let _ = self.writer.as_mut().unwrap().flush();
}
}
}