Skip to main content

rtc_dtls/
application_data.rs

1use bytes::{Bytes, BytesMut};
2use std::io::{Read, Write};
3
4use super::content::*;
5use shared::error::Result;
6
7// Application data messages are carried by the record layer and are
8// fragmented, compressed, and encrypted based on the current connection
9// state.  The messages are treated as transparent data to the record
10// layer.
11/// ## Specifications
12///
13/// * [RFC 5246 §10]
14///
15/// [RFC 5246 §10]: https://tools.ietf.org/html/rfc5246#section-10
16#[derive(Clone, PartialEq, Eq, Debug)]
17pub struct ApplicationData {
18    /// The application payload.
19    pub data: BytesMut,
20}
21
22impl ApplicationData {
23    /// The record content type this message is carried in.
24    pub fn content_type(&self) -> ContentType {
25        ContentType::ApplicationData
26    }
27
28    /// The encoded size of this message in bytes.
29    pub fn size(&self) -> usize {
30        self.data.len()
31    }
32
33    /// Encodes this message to `writer`.
34    ///
35    /// # Errors
36    ///
37    /// Fails on a write error, or if a field exceeds the length its wire format allows.
38    pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
39        writer.write_all(&self.data)?;
40
41        Ok(writer.flush()?)
42    }
43
44    /// Decodes one of these messages from `reader`.
45    ///
46    /// # Errors
47    ///
48    /// Fails if `reader` is truncated or its contents are not a valid encoding.
49    pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
50        // Read straight into the BytesMut-backed Vec instead of staging in a
51        // temporary Vec and copying the whole payload a second time.
52        let mut data: Vec<u8> = vec![];
53        reader.read_to_end(&mut data)?;
54
55        // `Bytes::from(Vec)` is zero-copy and the buffer is uniquely owned
56        // here, so `try_into_mut` succeeds without the second full-payload
57        // copy the old `BytesMut::from(&data[..])` performed.
58        Ok(ApplicationData {
59            data: Bytes::from(data)
60                .try_into_mut()
61                .unwrap_or_else(|b| BytesMut::from(&b[..])),
62        })
63    }
64}