Skip to content

Commit dd487a9

Browse files
author
Rain
authored
Merge pull request #8 from webrtc-rs/marshal
Marshal
2 parents 041a43f + f63a26f commit dd487a9

File tree

31 files changed

+1414
-988
lines changed

31 files changed

+1414
-988
lines changed

crates/rtcp/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rtcp"
3-
version = "0.2.2"
3+
version = "0.2.3"
44
authors = ["Rain Liu <[email protected]>", "Michael Uti <[email protected]>"]
55
edition = "2018"
66
description = "A pure Rust implementation of RTCP"
@@ -12,7 +12,7 @@ repository = "https://github.com/webrtc-rs/rtcp"
1212
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1313

1414
[dependencies]
15-
util = { package = "webrtc-util", version = "0.2.1", default-features = false, features = ["marshal"] }
15+
util = { package = "webrtc-util", version = "0.2.3", default-features = false, features = ["marshal"] }
1616
bytes = "1"
1717
thiserror = "1.0.25"
1818
anyhow = "1.0.41"

crates/rtcp/src/compound_packet/compound_packet_test.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,21 @@ const REAL_PACKET: [u8; 116] = [
3434

3535
#[test]
3636
fn test_read_eof() {
37-
let short_header = Bytes::from_static(&[
37+
let mut short_header = Bytes::from_static(&[
3838
0x81, 0xc9, // missing type & len
3939
]);
40-
41-
let result = unmarshal(&short_header);
40+
let result = unmarshal(&mut short_header);
4241
assert!(result.is_err(), "missing type & len");
4342
}
4443

4544
#[test]
4645
fn test_bad_compound() {
47-
let bad_compound = Bytes::copy_from_slice(&REAL_PACKET[..34]);
48-
let result = unmarshal(&bad_compound);
46+
let mut bad_compound = Bytes::copy_from_slice(&REAL_PACKET[..34]);
47+
let result = unmarshal(&mut bad_compound);
4948
assert!(result.is_err(), "trailing data!");
5049

51-
let bad_compound = Bytes::copy_from_slice(&REAL_PACKET[84..104]);
52-
53-
let p = unmarshal(&bad_compound).expect("Error unmarshalling packet");
50+
let mut bad_compound = Bytes::copy_from_slice(&REAL_PACKET[84..104]);
51+
let p = unmarshal(&mut bad_compound).expect("Error unmarshalling packet");
5452
let compound = p.as_any().downcast_ref::<CompoundPacket>().unwrap();
5553

5654
// this should return an error,
@@ -340,10 +338,12 @@ fn test_compound_packet_roundtrip() {
340338
}
341339

342340
let data1 = result.unwrap();
341+
let c = CompoundPacket::unmarshal(&mut data1.clone())
342+
.expect(format!("unmarshal {} error", name).as_str());
343343

344-
let c = CompoundPacket::unmarshal(&data1).expect("Unmarshall should be nil");
345-
346-
let data2 = c.marshal().expect("Marshal should be nil");
344+
let data2 = c
345+
.marshal()
346+
.expect(format!("marshal {} error", name).as_str());
347347

348348
assert_eq!(
349349
data1, data2,

crates/rtcp/src/compound_packet/mod.rs

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
#[cfg(test)]
22
mod compound_packet_test;
33

4-
use crate::{error::Error, packet::*, receiver_report::*, sender_report::*, source_description::*};
4+
use crate::{
5+
error::Error, header::*, packet::*, receiver_report::*, sender_report::*,
6+
source_description::*, util::*,
7+
};
8+
use util::marshal::{Marshal, MarshalSize, Unmarshal};
59

610
use anyhow::Result;
7-
use bytes::{Bytes, BytesMut};
11+
use bytes::{Buf, Bytes};
812
use std::any::Any;
13+
use std::fmt;
914

1015
/// A CompoundPacket is a collection of RTCP packets transmitted as a single packet with
1116
/// the underlying protocol (for example UDP).
@@ -19,10 +24,20 @@ use std::any::Any;
1924
/// to identify the source and to begin associating media for purposes such as lip-sync.
2025
///
2126
/// Other RTCP packet types may follow in any order. Packet types may appear more than once.
22-
#[derive(PartialEq, Default, Clone)]
27+
#[derive(Debug, Default, PartialEq, Clone)]
2328
pub struct CompoundPacket(pub Vec<Box<dyn Packet>>);
2429

30+
impl fmt::Display for CompoundPacket {
31+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32+
write!(f, "{:?}", self)
33+
}
34+
}
35+
2536
impl Packet for CompoundPacket {
37+
fn header(&self) -> Header {
38+
Header::default()
39+
}
40+
2641
/// destination_ssrc returns the synchronization sources associated with this
2742
/// CompoundPacket's reception report.
2843
fn destination_ssrc(&self) -> Vec<u32> {
@@ -33,56 +48,70 @@ impl Packet for CompoundPacket {
3348
}
3449
}
3550

36-
fn size(&self) -> usize {
51+
fn raw_size(&self) -> usize {
3752
let mut l = 0;
3853
for packet in &self.0 {
3954
l += packet.marshal_size();
4055
}
4156
l
4257
}
4358

59+
fn as_any(&self) -> &dyn Any {
60+
self
61+
}
62+
63+
fn equal(&self, other: &dyn Packet) -> bool {
64+
other
65+
.as_any()
66+
.downcast_ref::<CompoundPacket>()
67+
.map_or(false, |a| self == a)
68+
}
69+
70+
fn cloned(&self) -> Box<dyn Packet> {
71+
Box::new(self.clone())
72+
}
73+
}
74+
75+
impl MarshalSize for CompoundPacket {
76+
fn marshal_size(&self) -> usize {
77+
let l = self.raw_size();
78+
// align to 32-bit boundary
79+
l + get_padding_size(l)
80+
}
81+
}
82+
83+
impl Marshal for CompoundPacket {
4484
/// Marshal encodes the CompoundPacket as binary.
45-
fn marshal(&self) -> Result<Bytes> {
85+
fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
4686
self.validate()?;
4787

48-
let mut out = BytesMut::new();
4988
for packet in &self.0 {
50-
let a = packet.marshal()?;
51-
out.extend(a);
89+
let n = packet.marshal_to(buf)?;
90+
buf = &mut buf[n..];
5291
}
53-
Ok(out.freeze())
92+
93+
Ok(self.marshal_size())
5494
}
95+
}
5596

56-
fn unmarshal(raw_data: &Bytes) -> Result<Self> {
97+
impl Unmarshal for CompoundPacket {
98+
fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
99+
where
100+
Self: Sized,
101+
B: Buf,
102+
{
57103
let mut packets = vec![];
58104

59-
let mut raw_data = raw_data.clone();
60-
while !raw_data.is_empty() {
61-
let (p, processed) = unmarshaller(&raw_data)?;
105+
while raw_packet.has_remaining() {
106+
let p = unmarshaller(raw_packet)?;
62107
packets.push(p);
63-
raw_data = raw_data.split_off(processed);
64108
}
65109

66110
let c = CompoundPacket(packets);
67111
c.validate()?;
68112

69113
Ok(c)
70114
}
71-
72-
fn equal_to(&self, other: &dyn Packet) -> bool {
73-
other
74-
.as_any()
75-
.downcast_ref::<CompoundPacket>()
76-
.map_or(false, |a| self == a)
77-
}
78-
79-
fn clone_to(&self) -> Box<dyn Packet> {
80-
Box::new(self.clone())
81-
}
82-
83-
fn as_any(&self) -> &dyn Any {
84-
self
85-
}
86115
}
87116

88117
impl CompoundPacket {

crates/rtcp/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ pub enum Error {
3737
/// Packet received is too short.
3838
#[error("Packet status chunk must be 2 bytes")]
3939
PacketTooShort,
40+
/// Buffer is too short.
41+
#[error("Buffer too short to be written")]
42+
BufferTooShort,
4043
/// Wrong packet type.
4144
#[error("Wrong packet type")]
4245
WrongType,

crates/rtcp/src/goodbye/goodbye_test.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ fn test_goodbye_unmarshal() {
103103
),
104104
];
105105

106-
for (name, data, want, want_error) in tests {
107-
let got = Goodbye::unmarshal(&data);
106+
for (name, mut data, want, want_error) in tests {
107+
let got = Goodbye::unmarshal(&mut data);
108108

109109
assert_eq!(
110110
got.is_err(),
@@ -225,8 +225,9 @@ fn test_goodbye_round_trip() {
225225
err,
226226
);
227227
} else {
228-
let data = got.ok().unwrap();
229-
let actual = Goodbye::unmarshal(&data).expect(format!("Unmarshal {}", name).as_str());
228+
let mut data = got.ok().unwrap();
229+
let actual =
230+
Goodbye::unmarshal(&mut data).expect(format!("Unmarshal {}", name).as_str());
230231

231232
assert_eq!(
232233
actual, want,

0 commit comments

Comments
 (0)