sheave_core/messages/
chunk_size.rs

1mod negative_chunk_size;
2
3use std::io::Result as IOResult;
4use super::{
5    Channel,
6    ChunkData,
7    headers::MessageType
8};
9use crate::{
10    Decoder,
11    Encoder,
12    ByteBuffer
13};
14pub use self::negative_chunk_size::*;
15
16/// Tells a size to chunk its stream to the partner.
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub struct ChunkSize(u32);
19
20impl ChunkSize {
21    const NEGATIVE_FLAG: u32 = 0x80000000;
22    const DEFAULT: u32 = 128;
23
24    /// Constructs a chunk size.
25    pub fn new(chunk_size: u32) -> Self {
26        Self(chunk_size)
27    }
28
29    /// Gets an internal value.
30    pub fn get_chunk_size(&self) -> u32 {
31        self.0
32    }
33}
34
35impl Default for ChunkSize {
36    /// Constructs a ChunkSize with its default value.
37    /// In RTMP, the default value of chunking size is defined to be 128.
38    ///
39    /// # Examples
40    ///
41    /// ```rust
42    /// use sheave_core::messages::ChunkSize;
43    ///
44    /// let chunk_size = ChunkSize::default();
45    /// assert_eq!(128, chunk_size)
46    /// ```
47    fn default() -> Self {
48        Self(Self::DEFAULT)
49    }
50}
51
52impl PartialEq<u32> for ChunkSize {
53    fn eq(&self, other: &u32) -> bool {
54        self.0.eq(other)
55    }
56}
57
58impl PartialEq<ChunkSize> for u32 {
59    fn eq(&self, other: &ChunkSize) -> bool {
60        self.eq(&other.0)
61    }
62}
63
64impl ChunkData for ChunkSize {
65    const CHANNEL: Channel = Channel::Network;
66    const MESSAGE_TYPE: MessageType = MessageType::ChunkSize;
67}
68
69impl Decoder<ChunkSize> for ByteBuffer {
70    /// Decodes bytes into a ChunkSize.
71    ///
72    /// # Errors
73    ///
74    /// * [`Insufficientbufferlength`]
75    ///
76    /// When chunk data didn't remain at least 4 bytes.
77    ///
78    /// * [`NegativeChunkSize`]
79    ///
80    /// When its received chunk size's most significant bit is 1.
81    /// Chunking size is required that its bit is 0 in the specification.
82    /// This is probably considered of programs which has no unsigned type.
83    ///
84    /// # Examples
85    ///
86    /// ```rust
87    /// use sheave_core::{
88    ///     ByteBuffer,
89    ///     Decoder,
90    ///     messages::ChunkSize
91    /// };
92    ///
93    /// let mut buffer = ByteBuffer::default();
94    /// buffer.put_u32_be(128);
95    /// assert!(Decoder::<ChunkSize>::decode(&mut buffer).is_ok());
96    ///
97    /// let mut buffer = ByteBuffer::default();
98    /// buffer.put_u32_be(0x80000000);
99    /// assert!(Decoder::<ChunkSize>::decode(&mut buffer).is_err());
100    ///
101    /// let mut buffer = ByteBuffer::default();
102    /// assert!(Decoder::<ChunkSize>::decode(&mut buffer).is_err());
103    /// ```
104    ///
105    /// [`Insufficientbufferlength`]: crate::byte_buffer::InsufficientBufferLength
106    /// [`NegativeChunkSize`]: NegativeChunkSize
107    fn decode(&mut self) -> IOResult<ChunkSize> {
108        let chunk_size = self.get_u32_be()?;
109
110        if chunk_size & ChunkSize::NEGATIVE_FLAG != 0 {
111            Err(negative_chunk_size(chunk_size))
112        } else {
113            Ok(ChunkSize(chunk_size))
114        }
115    }
116}
117
118impl Encoder<ChunkSize> for ByteBuffer {
119    /// Encodes a ChunkSize into bytes.
120    fn encode(&mut self, chunk_size: &ChunkSize) {
121        self.put_u32_be(chunk_size.0);
122    }
123}
124
125#[cfg(test)]
126mod tests {
127    use super::*;
128
129    #[test]
130    fn decode_chunk_size() {
131        let mut buffer = ByteBuffer::default();
132        buffer.put_u32_be(128);
133        assert!(Decoder::<ChunkSize>::decode(&mut buffer).is_ok());
134
135        let mut buffer = ByteBuffer::default();
136        buffer.put_u32_be(0x80000000);
137        assert!(Decoder::<ChunkSize>::decode(&mut buffer).is_err())
138    }
139
140    #[test]
141    fn encode_chunk_size() {
142        let mut buffer = ByteBuffer::default();
143        buffer.encode(&ChunkSize::default());
144        let chunk_size = buffer.get_u32_be().unwrap();
145        assert_eq!(128, chunk_size)
146    }
147}