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}