use std::io::{Read, Write};
use bzip2::read::BzDecoder;
use bzip2::write::BzEncoder;
use bzip2::Compression;
use rusqlite::Error::UserFunctionError;
use crate::common::{register_compression, Encoder};
use crate::rusqlite::{Connection, Result};
pub fn register_bzip2_functions(conn: &Connection) -> Result<()> {
register_compression::<Bzip2Encoder>(conn)
}
pub struct Bzip2Encoder;
impl Encoder for Bzip2Encoder {
fn enc_name() -> &'static str {
"bzip2"
}
fn dec_name() -> &'static str {
"bzip2_decode"
}
fn test_name() -> &'static str {
"bzip2_test"
}
fn encode(data: &[u8], quality: Option<u32>) -> Result<Vec<u8>> {
let quality = if let Some(param) = quality {
if param < Compression::fast().level() || param > Compression::best().level() {
return Err(UserFunctionError(
format!(
"The optional second argument to bzip2() must be between {} and {}",
Compression::fast().level(),
Compression::best().level()
)
.into(),
));
}
Compression::new(param)
} else {
Compression::default()
};
let mut encoder = BzEncoder::new(Vec::new(), quality);
encoder
.write_all(data)
.map_err(|e| UserFunctionError(e.into()))?;
encoder.finish().map_err(|e| UserFunctionError(e.into()))
}
fn decode(data: &[u8]) -> Result<Vec<u8>> {
let mut decompressed = Vec::new();
BzDecoder::new(data)
.read_to_end(&mut decompressed)
.map_err(|e| UserFunctionError(e.into()))?;
Ok(decompressed)
}
fn test(data: &[u8]) -> bool {
let mut buffer = [0u8; 1024];
let mut decoder = BzDecoder::new(data);
while let Ok(len) = decoder.read(&mut buffer) {
if len == 0 {
return true;
}
}
false
}
}