1 use crate::frame::{self, Error, Head, Kind, StreamId};
2 
3 use bytes::BufMut;
4 
5 const SIZE_INCREMENT_MASK: u32 = 1 << 31;
6 
7 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
8 pub struct WindowUpdate {
9     stream_id: StreamId,
10     size_increment: u32,
11 }
12 
13 impl WindowUpdate {
new(stream_id: StreamId, size_increment: u32) -> WindowUpdate14     pub fn new(stream_id: StreamId, size_increment: u32) -> WindowUpdate {
15         WindowUpdate {
16             stream_id,
17             size_increment,
18         }
19     }
20 
stream_id(&self) -> StreamId21     pub fn stream_id(&self) -> StreamId {
22         self.stream_id
23     }
24 
size_increment(&self) -> u3225     pub fn size_increment(&self) -> u32 {
26         self.size_increment
27     }
28 
29     /// Builds a `WindowUpdate` frame from a raw frame.
load(head: Head, payload: &[u8]) -> Result<WindowUpdate, Error>30     pub fn load(head: Head, payload: &[u8]) -> Result<WindowUpdate, Error> {
31         debug_assert_eq!(head.kind(), crate::frame::Kind::WindowUpdate);
32         if payload.len() != 4 {
33             return Err(Error::BadFrameSize);
34         }
35 
36         // Clear the most significant bit, as that is reserved and MUST be ignored
37         // when received.
38         let size_increment = unpack_octets_4!(payload, 0, u32) & !SIZE_INCREMENT_MASK;
39 
40         if size_increment == 0 {
41             return Err(Error::InvalidWindowUpdateValue);
42         }
43 
44         Ok(WindowUpdate {
45             stream_id: head.stream_id(),
46             size_increment,
47         })
48     }
49 
encode<B: BufMut>(&self, dst: &mut B)50     pub fn encode<B: BufMut>(&self, dst: &mut B) {
51         tracing::trace!("encoding WINDOW_UPDATE; id={:?}", self.stream_id);
52         let head = Head::new(Kind::WindowUpdate, 0, self.stream_id);
53         head.encode(4, dst);
54         dst.put_u32(self.size_increment);
55     }
56 }
57 
58 impl<B> From<WindowUpdate> for frame::Frame<B> {
from(src: WindowUpdate) -> Self59     fn from(src: WindowUpdate) -> Self {
60         frame::Frame::WindowUpdate(src)
61     }
62 }
63