zip/extra_fields/
data_stream_alignment.rs1use core::mem;
4use std::io::Write;
5
6use crate::extra_fields::UsedExtraField;
7
8#[derive(Debug, Clone, PartialEq)]
10pub struct DataStreamAlignment {
11 alignment: u16,
13 pad_len: u16,
15}
16
17impl DataStreamAlignment {
18 #[must_use]
20 pub fn new(padding_len: u16, alignment: u16) -> Option<Self> {
21 if padding_len >= 6 {
22 Some(Self {
23 alignment,
24 pad_len: padding_len.saturating_sub(4),
25 })
26 } else {
27 None
28 }
29 }
30
31 pub(crate) fn full_size(&self, is_local_header: bool) -> usize {
32 if is_local_header {
33 mem::size_of::<u16>() + mem::size_of::<u16>() + self.pad_len as usize
34 } else {
35 0
37 }
38 }
39
40 pub(crate) fn write<W: Write>(
41 &self,
42 writer: &mut W,
43 is_local_header: bool,
44 ) -> std::io::Result<()> {
45 if !is_local_header {
46 return Ok(());
48 }
49 let magic = UsedExtraField::DataStreamAlignment.as_u16();
50 writer.write_all(&magic.to_le_bytes())?;
51 writer.write_all(&self.pad_len.to_le_bytes())?;
52 writer.write_all(&self.alignment.to_le_bytes())?;
53 let pad_len = self.pad_len.saturating_sub(2);
54 let zeros = [0u8; 1024];
55 let mut remaining = pad_len as usize;
56 while remaining > 0 {
57 let n = remaining.min(zeros.len());
58 writer.write_all(&zeros[..n])?;
59 remaining -= n;
60 }
61 Ok(())
62 }
63}