sark_core/http/
compress.rs1use std::cell::RefCell;
14
15use libdeflater::{CompressionLvl, Compressor};
16
17pub struct Gzip {
18 encoder: Compressor,
19 buf: Vec<u8>,
20}
21
22impl Gzip {
23 fn new(level: i32) -> Self {
24 let lvl = CompressionLvl::new(level).unwrap_or(CompressionLvl::fastest());
25 Self {
26 encoder: Compressor::new(lvl),
27 buf: Vec::with_capacity(64 * 1024),
28 }
29 }
30
31 pub fn encode(&mut self, src: &[u8]) -> &[u8] {
32 let cap = self.encoder.gzip_compress_bound(src.len());
33 if self.buf.capacity() < cap {
34 self.buf.reserve(cap - self.buf.capacity());
35 }
36 self.buf.resize(cap, 0);
37 let n = self
38 .encoder
39 .gzip_compress(src, &mut self.buf)
40 .expect("gzip_compress_bound undersized");
41 self.buf.truncate(n);
42 &self.buf
43 }
44
45 pub fn with_thread_local<R>(f: impl FnOnce(&mut Gzip) -> R) -> R {
46 thread_local! {
47 static SLOT: RefCell<Gzip> = RefCell::new(Gzip::new(3));
48 }
49 SLOT.with(|cell| f(&mut cell.borrow_mut()))
50 }
51}
52
53pub struct Brotli {
63 params: brotli::enc::BrotliEncoderParams,
64 buf: Vec<u8>,
65}
66
67impl Brotli {
68 fn new(quality: i32, lgwin: i32) -> Self {
69 let params = brotli::enc::BrotliEncoderParams {
70 quality,
71 lgwin,
72 ..Default::default()
73 };
74 Self {
75 params,
76 buf: Vec::with_capacity(64 * 1024),
77 }
78 }
79
80 pub fn encode(&mut self, src: &[u8]) -> &[u8] {
81 self.buf.clear();
82 let mut reader = src;
83 brotli::BrotliCompress(&mut reader, &mut self.buf, &self.params)
84 .expect("brotli compress into Vec is infallible");
85 &self.buf
86 }
87
88 pub fn with_thread_local<R>(f: impl FnOnce(&mut Brotli) -> R) -> R {
89 thread_local! {
91 static SLOT: RefCell<Brotli> = RefCell::new(Brotli::new(5, 22));
92 }
93 SLOT.with(|cell| f(&mut cell.borrow_mut()))
94 }
95}