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)
}
}