zip_core/raw/parse/
extensible_data.rs1use crate::raw::{ExtensibleData, ExtensibleDataFixed};
2
3use super::{
4 preview_u16_from_buf, validate_length, validate_length_fixed, DynamicSizeError, FixedSizeError, Parse, ParseExtend,
5};
6
7extern crate alloc;
8use alloc::vec;
9
10impl Parse for ExtensibleDataFixed {
11 type Error = FixedSizeError;
12
13 fn from_buf<T: bytes::Buf>(buf: &mut T) -> Result<Self, Self::Error>
14 where
15 Self: Sized,
16 {
17 let remaining = buf.remaining();
18 validate_length(remaining, Self::SIZE_IN_BYTES, FixedSizeError::UnsufficientExactBytes)?;
19 Ok(Self {
20 header_id: buf.get_u16_le(),
21 data_size: buf.get_u16_le(),
22 })
23 }
24
25 fn to_buf<T: bytes::BufMut>(&self, buf: &mut T) -> Result<(), Self::Error> {
26 let remaining = buf.remaining_mut();
27 validate_length(remaining, Self::SIZE_IN_BYTES, FixedSizeError::UnsufficientExactBytes)?;
28 buf.put_u16_le(self.header_id);
29 buf.put_u16_le(self.data_size);
30 Ok(())
31 }
32}
33
34impl ParseExtend for ExtensibleData {
35 type Error = DynamicSizeError;
36 type Fixed = ExtensibleDataFixed;
37
38 fn from_buf_fixed<T: bytes::Buf>(buf: &mut T, fixed: Self::Fixed) -> Result<Self, (Self::Error, Self::Fixed)>
39 where
40 Self: Sized,
41 {
42 let total = fixed.data_size as usize;
43 let fixed = validate_length_fixed(buf.remaining(), total, fixed, DynamicSizeError::UnsufficientExactBytes)?;
44
45 let mut data = vec![0; fixed.data_size as usize];
46 buf.copy_to_slice(&mut data);
47
48 Ok(Self { fixed, data })
49 }
50}
51
52impl Parse for ExtensibleData {
53 type Error = DynamicSizeError;
54
55 fn from_buf<T: bytes::Buf>(buf: &mut T) -> Result<Self, Self::Error>
56 where
57 Self: Sized,
58 {
59 let remaining = buf.remaining();
60 const SIZE: usize = ExtensibleDataFixed::SIZE_IN_BYTES;
61 validate_length(remaining, SIZE, DynamicSizeError::UnsufficientAtLeastBytes)?;
62 const PEEK_START: usize = SIZE - 2;
63 let chunk = buf.chunk();
64 let data_length: u16 = preview_u16_from_buf(chunk, PEEK_START).ok_or(DynamicSizeError::NotContiguous(SIZE))?;
65 let total = SIZE + data_length as usize;
66 validate_length(remaining, total, DynamicSizeError::UnsufficientExactBytes)?;
67
68 let fixed = ExtensibleDataFixed::from_buf(buf).map_err(FixedSizeError::in_dynamic)?;
69 Self::from_buf_fixed(buf, fixed).map_err(|e| e.0)
70 }
71
72 fn to_buf<T: bytes::BufMut>(&self, buf: &mut T) -> Result<(), Self::Error> {
73 let remaining = buf.remaining_mut();
74 let total = ExtensibleDataFixed::SIZE_IN_BYTES + self.data.len();
75 validate_length(remaining, total, DynamicSizeError::UnsufficientExactBytes)?;
76 self.fixed.to_buf(buf).map_err(FixedSizeError::in_dynamic)?;
77 buf.put_slice(&self.data);
78 Ok(())
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::{super::*, *};
85
86 #[test]
87 fn cycle_extensible_data() {
88 let data = vec![48, 49, 32];
89 let ed = ExtensibleData {
90 fixed: ExtensibleDataFixed {
91 header_id: 0x0001,
92 data_size: data.len() as u16,
93 },
94 data: data.clone(),
95 };
96 let mut buf = vec![];
97 ed.to_buf(&mut buf).unwrap();
98 assert_eq!(buf.len(), ExtensibleDataFixed::SIZE_IN_BYTES + data.len());
99 let mut readbuf = buf.as_slice();
100 let ed2 = ExtensibleData::from_buf(&mut readbuf).unwrap();
101 assert_eq!(ed, ed2);
102 assert_eq!(ed2.data, data);
103 }
104
105 #[test]
106 fn parseextend_extensible_data() {
107 let buf: Vec<u8> = vec![48, 49, 32, 50];
108 let mut fixed = ExtensibleDataFixed {
109 header_id: 0x0001,
110 data_size: buf.len() as u16,
111 };
112 assert!(ExtensibleData::from_buf_fixed(&mut buf.as_slice(), fixed.clone()).is_ok());
113 fixed.data_size += 1;
114 assert!(ExtensibleData::from_buf_fixed(&mut buf.as_slice(), fixed).is_err());
115 }
116}