streaming_crypto/core_api/stream_v2/framing/
encode.rs1use byteorder::{LittleEndian, WriteBytesExt};
2use bytes::{BytesMut, BufMut};
3
4use crate::stream_v2::framing::types::{FRAME_VERSION, FRAME_MAGIC};
5use crate::stream_v2::framing::types::{FrameHeader, FrameError};
6
7pub fn encode_frame(
22 header: &FrameHeader,
23 ciphertext: &[u8],
24) -> Result<Vec<u8>, FrameError> {
25 let expected = FrameHeader::LEN + header.ciphertext_len() as usize;
26
27 if ciphertext.len() != header.ciphertext_len() as usize {
28 return Err(FrameError::LengthMismatch {
29 expected,
30 actual: ciphertext.len(),
31 });
32 }
33
34 let mut wire = Vec::with_capacity(expected);
35
36 wire.extend_from_slice(&FRAME_MAGIC);
38 wire.push(FRAME_VERSION);
39 wire.push(header.frame_type().try_to_u8()?);
40
41 wire.write_u32::<LittleEndian>(header.segment_index()).unwrap();
42 wire.write_u32::<LittleEndian>(header.frame_index()).unwrap();
43 wire.write_u32::<LittleEndian>(header.plaintext_len()).unwrap();
44 wire.write_u32::<LittleEndian>(header.ciphertext_len()).unwrap();
45
46 wire.extend_from_slice(ciphertext);
48
49 debug_assert_eq!(wire.len(), expected);
51
52 Ok(wire)
53
54 }
64
65#[inline]
68pub fn encode_in_place(
69 header: &FrameHeader,
70 ciphertext: &[u8],
71 buf: &mut BytesMut, ) -> Result<(), FrameError> {
73 let expected = FrameHeader::LEN + header.ciphertext_len() as usize;
74
75 if ciphertext.len() != header.ciphertext_len() as usize {
76 return Err(FrameError::LengthMismatch {
77 expected,
78 actual: ciphertext.len(),
79 });
80 }
81
82 buf.clear();
83 buf.reserve(expected);
84
85 buf.put_slice(&FRAME_MAGIC);
87 buf.put_u8(FRAME_VERSION);
88 buf.put_u8(header.frame_type().try_to_u8()?);
89
90 buf.put_u32_le(header.segment_index());
91 buf.put_u32_le(header.frame_index());
92 buf.put_u32_le(header.plaintext_len());
93 buf.put_u32_le(header.ciphertext_len());
94
95 buf.put_slice(ciphertext);
97
98 debug_assert_eq!(buf.len(), expected);
99
100 Ok(())
101}
102
103