smdiff_encoder/
writer.rs

1//! A writer for an smdiff section.
2//! This handles writing the header and the operations, and optionally secondary compression.
3use std::io::Write;
4
5use crate::{encode, EncoderConfig, SecondaryCompression};
6
7use smdiff_common::AddOp;
8use smdiff_writer::{write_ops, write_section_header};
9
10
11/// Writes a section to a writer, with secondary compression if requested.
12pub fn section_writer<W:Write,A:AddOp>(
13    sec_comp: &Option<SecondaryCompression>,
14    mut header: smdiff_common::SectionHeader,
15    writer: &mut W,
16    seg_ops: &[smdiff_common::Op<A>],
17    mut sec_data_buffer: &mut Vec<u8>)
18-> std::io::Result<()> {
19    Ok(if sec_comp.is_some() {
20        let comp = sec_comp.clone().unwrap();
21        header.compression_algo = comp.algo_value();
22        //dbg!(&header);
23        write_section_header(&header, writer)?;
24        write_ops(seg_ops,&header,sec_data_buffer)?;
25        match comp{
26            SecondaryCompression::Smdiff (config) => {
27                let mut crsr = std::io::Cursor::new(sec_data_buffer);
28                let inner_config = EncoderConfig::default().no_match_src().set_match_target(config);
29                encode(None, &mut crsr, writer, &inner_config)?;
30                sec_data_buffer = crsr.into_inner();
31            },
32            SecondaryCompression::Zstd { level } => {
33                let mut a = ::zstd::Encoder::new(writer, level)?;
34                a.set_pledged_src_size(Some(sec_data_buffer.len() as u64))?;
35                a.include_contentsize(true)?;
36                a.write_all(&*sec_data_buffer)?;
37                a.finish()?;
38            },
39            SecondaryCompression::Brotli { mut options }=> {
40                options.size_hint(sec_data_buffer.len() as u32);
41                let mut a = ::brotlic::CompressorWriter::with_encoder(options.build().unwrap(), writer);
42                a.write_all(&*sec_data_buffer)?;
43                a.into_inner()?;
44            },
45        }
46        sec_data_buffer.clear();
47    }else{
48        write_section_header(&header, writer)?;
49        write_ops(seg_ops,&header,writer)?;
50    })
51}