rtc_stun/
uattrs.rs

1#[cfg(test)]
2mod uattrs_test;
3
4use crate::attributes::*;
5use crate::message::*;
6use shared::error::*;
7
8use std::fmt;
9
10// UnknownAttributes represents UNKNOWN-ATTRIBUTES attribute.
11//
12// RFC 5389 Section 15.9
13pub struct UnknownAttributes(pub Vec<AttrType>);
14
15impl fmt::Display for UnknownAttributes {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        if self.0.is_empty() {
18            write!(f, "<nil>")
19        } else {
20            let s = self
21                .0
22                .iter()
23                .map(|t| t.to_string())
24                .collect::<Vec<_>>()
25                .join(", ");
26            write!(f, "{s}")
27        }
28    }
29}
30
31// type size is 16 bit.
32const ATTR_TYPE_SIZE: usize = 2;
33
34impl Setter for UnknownAttributes {
35    // add_to adds UNKNOWN-ATTRIBUTES attribute to message.
36    fn add_to(&self, m: &mut Message) -> Result<()> {
37        let mut v = Vec::with_capacity(ATTR_TYPE_SIZE * 20); // 20 should be enough
38        // If len(a.Types) > 20, there will be allocations.
39        for t in &self.0 {
40            v.extend_from_slice(&t.value().to_be_bytes());
41        }
42        m.add(ATTR_UNKNOWN_ATTRIBUTES, &v);
43        Ok(())
44    }
45}
46
47impl Getter for UnknownAttributes {
48    // GetFrom parses UNKNOWN-ATTRIBUTES from message.
49    fn get_from(&mut self, m: &Message) -> Result<()> {
50        let v = m.get(ATTR_UNKNOWN_ATTRIBUTES)?;
51        if v.len() % ATTR_TYPE_SIZE != 0 {
52            return Err(Error::ErrBadUnknownAttrsSize);
53        }
54        self.0.clear();
55        let mut first = 0usize;
56        while first < v.len() {
57            let last = first + ATTR_TYPE_SIZE;
58            self.0
59                .push(AttrType(u16::from_be_bytes([v[first], v[first + 1]])));
60            first = last;
61        }
62        Ok(())
63    }
64}