1use std::any::Any;
2use std::fmt;
3
4use bytes::{Buf, BufMut, Bytes, BytesMut};
5use util::marshal::{Marshal, MarshalSize, Unmarshal};
6
7use crate::error::Error;
8use crate::header::*;
9use crate::packet::Packet;
10use crate::util::*;
11
12#[derive(Debug, PartialEq, Eq, Default, Clone)]
15pub struct RawPacket(pub Bytes);
16
17impl fmt::Display for RawPacket {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 write!(f, "RawPacket: {self:?}")
20 }
21}
22
23impl Packet for RawPacket {
24 fn header(&self) -> Header {
26 Header::unmarshal(&mut self.0.clone()).unwrap_or_default()
27 }
28
29 fn destination_ssrc(&self) -> Vec<u32> {
31 vec![]
32 }
33
34 fn raw_size(&self) -> usize {
35 self.0.len()
36 }
37
38 fn as_any(&self) -> &(dyn Any + Send + Sync) {
39 self
40 }
41
42 fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool {
43 other.as_any().downcast_ref::<RawPacket>() == Some(self)
44 }
45
46 fn cloned(&self) -> Box<dyn Packet + Send + Sync> {
47 Box::new(self.clone())
48 }
49}
50
51impl MarshalSize for RawPacket {
52 fn marshal_size(&self) -> usize {
53 let l = self.raw_size();
54 l + get_padding_size(l)
56 }
57}
58
59impl Marshal for RawPacket {
60 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize, util::Error> {
62 let h = Header::unmarshal(&mut self.0.clone())?;
63 buf.put(self.0.clone());
64 if h.padding {
65 put_padding(buf, self.raw_size());
66 }
67 Ok(self.marshal_size())
68 }
69}
70
71impl Unmarshal for RawPacket {
72 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self, util::Error>
74 where
75 Self: Sized,
76 B: Buf,
77 {
78 let raw_packet_len = raw_packet.remaining();
79 if raw_packet_len < HEADER_LENGTH {
80 return Err(Error::PacketTooShort.into());
81 }
82
83 let h = Header::unmarshal(raw_packet)?;
84
85 let raw_hdr = h.marshal()?;
86 let raw_body = raw_packet.copy_to_bytes(raw_packet.remaining());
87 let mut raw = BytesMut::new();
88 raw.extend(raw_hdr);
89 raw.extend(raw_body);
90
91 Ok(RawPacket(raw.freeze()))
92 }
93}
94
95#[cfg(test)]
96mod test {
97 use super::*;
98
99 #[test]
100 fn test_raw_packet_roundtrip() -> Result<(), Error> {
101 let tests: Vec<(&str, RawPacket, Option<Error>)> = vec![
102 (
103 "valid",
104 RawPacket(Bytes::from_static(&[
105 0x81, 0xcb, 0x00, 0x0c, 0x90, 0x2f, 0x9e, 0x2e, 0x03, 0x46, 0x4f, 0x4f, ])),
109 None,
110 ),
111 (
112 "short header",
113 RawPacket(Bytes::from_static(&[0x80])),
114 Some(Error::PacketTooShort),
115 ),
116 (
117 "invalid header",
118 RawPacket(
119 Bytes::from_static(&[0x00, 0xc9, 0x00, 0x04]),
121 ),
122 Some(Error::BadVersion),
123 ),
124 ];
125
126 for (name, pkt, unmarshal_error) in tests {
127 let result = pkt.marshal();
128 assert_eq!(
129 result.is_err(),
130 unmarshal_error.is_some(),
131 "Unmarshal {name}: err = {result:?}, want {unmarshal_error:?}"
132 );
133
134 if result.is_err() {
135 continue;
136 }
137
138 let mut data = result.unwrap();
139
140 let result = RawPacket::unmarshal(&mut data);
141
142 assert_eq!(
143 result.is_err(),
144 unmarshal_error.is_some(),
145 "Unmarshal {name}: err = {result:?}, want {unmarshal_error:?}"
146 );
147
148 if result.is_err() {
149 continue;
150 }
151
152 let decoded = result.unwrap();
153
154 assert_eq!(
155 decoded, pkt,
156 "{name} raw round trip: got {decoded:?}, want {pkt:?}"
157 )
158 }
159
160 Ok(())
161 }
162}