ssh_packet/crypto/
lengthed.rs

1use std::{io, ops::Deref};
2
3use binrw::{
4    meta::{ReadEndian, WriteEndian},
5    BinRead, BinWrite,
6};
7
8/// An helper to prefix a serializable value with it's `size`.
9#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
10pub struct Lengthed<T>(pub T);
11
12impl<T> Deref for Lengthed<T> {
13    type Target = T;
14
15    fn deref(&self) -> &Self::Target {
16        &self.0
17    }
18}
19
20impl<T> From<T> for Lengthed<T> {
21    fn from(value: T) -> Self {
22        Self(value)
23    }
24}
25
26impl<T> BinRead for Lengthed<T>
27where
28    T: BinRead,
29{
30    type Args<'a> = T::Args<'a>;
31
32    fn read_options<R: std::io::Read + std::io::Seek>(
33        reader: &mut R,
34        endian: binrw::Endian,
35        args: Self::Args<'_>,
36    ) -> binrw::BinResult<Self> {
37        let size = u32::read_be(reader)?;
38        let len = (size as usize).min(crate::PACKET_MAX_SIZE);
39
40        let mut buf = Vec::with_capacity(len);
41        reader.read_exact(&mut buf[..len])?;
42
43        T::read_options(&mut io::Cursor::new(&buf), endian, args).map(Self)
44    }
45}
46
47impl<T> ReadEndian for Lengthed<T>
48where
49    T: ReadEndian,
50{
51    const ENDIAN: binrw::meta::EndianKind = T::ENDIAN;
52}
53
54impl<T> BinWrite for Lengthed<T>
55where
56    T: BinWrite,
57{
58    type Args<'a> = T::Args<'a>;
59
60    fn write_options<W: std::io::Write + std::io::Seek>(
61        &self,
62        writer: &mut W,
63        endian: binrw::Endian,
64        args: Self::Args<'_>,
65    ) -> binrw::BinResult<()> {
66        let mut buf = Vec::with_capacity(crate::PACKET_MAX_SIZE);
67        self.0
68            .write_options(&mut io::Cursor::new(&mut buf), endian, args)?;
69
70        let len = buf.len();
71        let size: u32 = len.min(crate::PACKET_MAX_SIZE) as u32;
72
73        size.write_be(writer)?;
74        Ok(writer.write_all(&buf)?)
75    }
76}
77
78impl<T> WriteEndian for Lengthed<T>
79where
80    T: WriteEndian,
81{
82    const ENDIAN: binrw::meta::EndianKind = T::ENDIAN;
83}