sheave_core/messages/
chunk_size.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
mod negative_chunk_size;

use std::io::Result as IOResult;
use super::{
    Channel,
    ChunkData,
    headers::MessageType
};
use crate::{
    Decoder,
    Encoder,
    ByteBuffer
};
pub use self::negative_chunk_size::*;

/// Tells a size to chunk its stream to the partner.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ChunkSize(u32);

impl ChunkSize {
    const NEGATIVE_FLAG: u32 = 0x80000000;
    const DEFAULT: u32 = 128;

    /// Constructs a chunk size.
    pub fn new(chunk_size: u32) -> Self {
        Self(chunk_size)
    }

    /// Gets an internal value.
    pub fn get_chunk_size(&self) -> u32 {
        self.0
    }
}

impl Default for ChunkSize {
    /// Constructs a ChunkSize with its default value.
    /// In RTMP, the default value of chunking size is defined to be 128.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use sheave_core::messages::ChunkSize;
    ///
    /// let chunk_size = ChunkSize::default();
    /// assert_eq!(128, chunk_size)
    /// ```
    fn default() -> Self {
        Self(Self::DEFAULT)
    }
}

impl PartialEq<u32> for ChunkSize {
    fn eq(&self, other: &u32) -> bool {
        self.0.eq(other)
    }
}

impl PartialEq<ChunkSize> for u32 {
    fn eq(&self, other: &ChunkSize) -> bool {
        self.eq(&other.0)
    }
}

impl ChunkData for ChunkSize {
    const CHANNEL: Channel = Channel::Network;
    const MESSAGE_TYPE: MessageType = MessageType::ChunkSize;
}

impl Decoder<ChunkSize> for ByteBuffer {
    /// Decodes bytes into a ChunkSize.
    ///
    /// # Errors
    ///
    /// * [`Insufficientbufferlength`]
    ///
    /// When chunk data didn't remain at least 4 bytes.
    ///
    /// * [`NegativeChunkSize`]
    ///
    /// When its received chunk size's most significant bit is 1.
    /// Chunking size is required that its bit is 0 in the specification.
    /// This is probably considered of programs which has no unsigned type.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use sheave_core::{
    ///     ByteBuffer,
    ///     Decoder,
    ///     messages::ChunkSize
    /// };
    ///
    /// let mut buffer = ByteBuffer::default();
    /// buffer.put_u32_be(128);
    /// assert!(Decoder::<ChunkSize>::decode(&mut buffer).is_ok());
    ///
    /// let mut buffer = ByteBuffer::default();
    /// buffer.put_u32_be(0x80000000);
    /// assert!(Decoder::<ChunkSize>::decode(&mut buffer).is_err());
    ///
    /// let mut buffer = ByteBuffer::default();
    /// assert!(Decoder::<ChunkSize>::decode(&mut buffer).is_err());
    /// ```
    ///
    /// [`Insufficientbufferlength`]: crate::byte_buffer::InsufficientBufferLength
    /// [`NegativeChunkSize`]: NegativeChunkSize
    fn decode(&mut self) -> IOResult<ChunkSize> {
        let chunk_size = self.get_u32_be()?;

        if chunk_size & ChunkSize::NEGATIVE_FLAG != 0 {
            Err(negative_chunk_size(chunk_size))
        } else {
            Ok(ChunkSize(chunk_size))
        }
    }
}

impl Encoder<ChunkSize> for ByteBuffer {
    /// Encodes a ChunkSize into bytes.
    fn encode(&mut self, chunk_size: &ChunkSize) {
        self.put_u32_be(chunk_size.0);
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn decode_chunk_size() {
        let mut buffer = ByteBuffer::default();
        buffer.put_u32_be(128);
        assert!(Decoder::<ChunkSize>::decode(&mut buffer).is_ok());

        let mut buffer = ByteBuffer::default();
        buffer.put_u32_be(0x80000000);
        assert!(Decoder::<ChunkSize>::decode(&mut buffer).is_err())
    }

    #[test]
    fn encode_chunk_size() {
        let mut buffer = ByteBuffer::default();
        buffer.encode(&ChunkSize::default());
        let chunk_size = buffer.get_u32_be().unwrap();
        assert_eq!(128, chunk_size)
    }
}