flash_lso/packet/
write.rs1use crate::amf0;
4use crate::errors::Error;
5use crate::packet::{Header, Message, Packet};
6use crate::types::AMFVersion;
7
8fn write_header(
9 header: &Header,
10 out: &mut Vec<u8>,
11 exact_lengths: bool,
12) -> Result<(), Error<'static>> {
13 let name_length = u16::try_from(header.name.len()).map_err(|_| Error::PacketTooLarge)?;
15 out.extend(name_length.to_be_bytes());
16 out.extend(header.name.as_bytes());
17
18 if header.must_understand {
20 out.push(1);
21 } else {
22 out.push(0);
23 }
24
25 let mut value = Vec::new();
27 amf0::write::write_value(&mut value, &header.value)
28 .map_err(|e| Error::IoError(e.to_string(), e.kind()))?;
29 if exact_lengths {
30 let value_length = u32::try_from(value.len()).map_err(|_| Error::PacketTooLarge)?;
31 out.extend(value_length.to_be_bytes());
32 } else {
33 out.extend(u32::MAX.to_be_bytes());
34 }
35 out.append(&mut value);
36
37 Ok(())
38}
39
40fn write_message(
41 message: &Message,
42 out: &mut Vec<u8>,
43 exact_lengths: bool,
44) -> Result<(), Error<'static>> {
45 let target_length =
47 u16::try_from(message.target_uri.len()).map_err(|_| Error::PacketTooLarge)?;
48 out.extend(target_length.to_be_bytes());
49 out.extend(message.target_uri.as_bytes());
50
51 let response_length =
53 u16::try_from(message.response_uri.len()).map_err(|_| Error::PacketTooLarge)?;
54 out.extend(response_length.to_be_bytes());
55 out.extend(message.response_uri.as_bytes());
56
57 let mut contents = Vec::new();
59 amf0::write::write_value(&mut contents, &message.contents)
60 .map_err(|e| Error::IoError(e.to_string(), e.kind()))?;
61 if exact_lengths {
62 let contents_length = u32::try_from(contents.len()).map_err(|_| Error::PacketTooLarge)?;
63 out.extend(contents_length.to_be_bytes());
64 } else {
65 out.extend(u32::MAX.to_be_bytes());
66 }
67 out.append(&mut contents);
68
69 Ok(())
70}
71
72pub fn write_to_bytes(packet: &Packet, exact_lengths: bool) -> Result<Vec<u8>, Error<'static>> {
74 let mut buffer = Vec::new();
75
76 buffer.push(0);
78 match packet.version {
79 AMFVersion::AMF0 => buffer.push(0),
80 #[cfg(feature = "amf3")]
81 AMFVersion::AMF3 => buffer.push(3),
82 }
83
84 let header_count = u16::try_from(packet.headers.len()).map_err(|_| Error::PacketTooLarge)?;
86 buffer.extend(header_count.to_be_bytes());
87 for header in &packet.headers {
88 write_header(header, &mut buffer, exact_lengths)?;
89 }
90
91 let message_count = u16::try_from(packet.messages.len()).map_err(|_| Error::PacketTooLarge)?;
93 buffer.extend(message_count.to_be_bytes());
94 for message in &packet.messages {
95 write_message(message, &mut buffer, exact_lengths)?;
96 }
97
98 Ok(buffer)
99}