git_zero_core/zlib/
encode.rs1use super::adler::Adler32;
3use crate::{Error, ObjectReader, Repository, Result, io::Write};
4
5pub fn write_parts(output: &mut impl Write, parts: &[&[u8]]) -> Result<()> {
6 let mut encoder = Encoder::new(output)?;
7 for part in parts {
8 encoder.write_part(part)?;
9 }
10 encoder.finish()
11}
12
13pub(crate) fn write_reader<R: Repository + ?Sized>(
16 output: &mut impl Write,
17 header: &[u8],
18 reader: &mut ObjectReader<'_, R>,
19 scratch: &mut [u8],
20) -> Result<()> {
21 if reader.remaining() != 0 && scratch.is_empty() {
22 return Err(Error::BufferTooSmall);
23 }
24 let mut encoder = Encoder::new(output)?;
25 encoder.write_part(header)?;
26 while reader.remaining() != 0 {
27 let length = reader.remaining().min(u64::from(u16::MAX)) as u16;
28 encoder.block_header(length)?;
29 let mut remaining = usize::from(length);
30 while remaining != 0 {
31 let capacity = remaining.min(scratch.len());
32 let length = reader.read(&mut scratch[..capacity])?;
33 encoder.write_bytes(&scratch[..length])?;
34 remaining -= length;
35 }
36 }
37 encoder.finish()
38}
39
40struct Encoder<'a, W> {
41 output: &'a mut W,
42 adler: Adler32,
43}
44
45impl<'a, W: Write> Encoder<'a, W> {
46 fn new(output: &'a mut W) -> Result<Self> {
47 output.write_all(&[0x78, 0x01])?;
48 Ok(Self {
49 output,
50 adler: Adler32::new(),
51 })
52 }
53
54 fn block_header(&mut self, length: u16) -> Result<()> {
55 self.output.write_all(&[0])?; self.output.write_all(&length.to_le_bytes())?;
57 self.output.write_all(&(!length).to_le_bytes())
58 }
59
60 fn write_bytes(&mut self, bytes: &[u8]) -> Result<()> {
61 self.output.write_all(bytes)?;
62 self.adler.update(bytes);
63 Ok(())
64 }
65
66 fn write_part(&mut self, bytes: &[u8]) -> Result<()> {
67 for block in bytes.chunks(u16::MAX as usize) {
68 self.block_header(block.len() as u16)?;
69 self.write_bytes(block)?;
70 }
71 Ok(())
72 }
73
74 fn finish(self) -> Result<()> {
75 self.output.write_all(&[1, 0, 0, 0xff, 0xff])?;
77 self.output.write_all(&self.adler.value().to_be_bytes())
78 }
79}