1 use crate::frame::{util, Error, Frame, Head, Kind, StreamId};
2 use bytes::{Buf, BufMut, Bytes};
3 
4 use std::fmt;
5 
6 /// Data frame
7 ///
8 /// Data frames convey arbitrary, variable-length sequences of octets associated
9 /// with a stream. One or more DATA frames are used, for instance, to carry HTTP
10 /// request or response payloads.
11 #[derive(Eq, PartialEq)]
12 pub struct Data<T = Bytes> {
13     stream_id: StreamId,
14     data: T,
15     flags: DataFlags,
16     pad_len: Option<u8>,
17 }
18 
19 #[derive(Copy, Clone, Eq, PartialEq)]
20 struct DataFlags(u8);
21 
22 const END_STREAM: u8 = 0x1;
23 const PADDED: u8 = 0x8;
24 const ALL: u8 = END_STREAM | PADDED;
25 
26 impl<T> Data<T> {
27     /// Creates a new DATA frame.
new(stream_id: StreamId, payload: T) -> Self28     pub fn new(stream_id: StreamId, payload: T) -> Self {
29         assert!(!stream_id.is_zero());
30 
31         Data {
32             stream_id,
33             data: payload,
34             flags: DataFlags::default(),
35             pad_len: None,
36         }
37     }
38 
39     /// Returns the stream identifier that this frame is associated with.
40     ///
41     /// This cannot be a zero stream identifier.
stream_id(&self) -> StreamId42     pub fn stream_id(&self) -> StreamId {
43         self.stream_id
44     }
45 
46     /// Gets the value of the `END_STREAM` flag for this frame.
47     ///
48     /// If true, this frame is the last that the endpoint will send for the
49     /// identified stream.
50     ///
51     /// Setting this flag causes the stream to enter one of the "half-closed"
52     /// states or the "closed" state (Section 5.1).
is_end_stream(&self) -> bool53     pub fn is_end_stream(&self) -> bool {
54         self.flags.is_end_stream()
55     }
56 
57     /// Sets the value for the `END_STREAM` flag on this frame.
set_end_stream(&mut self, val: bool)58     pub fn set_end_stream(&mut self, val: bool) {
59         if val {
60             self.flags.set_end_stream();
61         } else {
62             self.flags.unset_end_stream();
63         }
64     }
65 
66     /// Returns whether the `PADDED` flag is set on this frame.
67     #[cfg(feature = "unstable")]
is_padded(&self) -> bool68     pub fn is_padded(&self) -> bool {
69         self.flags.is_padded()
70     }
71 
72     /// Sets the value for the `PADDED` flag on this frame.
73     #[cfg(feature = "unstable")]
set_padded(&mut self)74     pub fn set_padded(&mut self) {
75         self.flags.set_padded();
76     }
77 
78     /// Returns a reference to this frame's payload.
79     ///
80     /// This does **not** include any padding that might have been originally
81     /// included.
payload(&self) -> &T82     pub fn payload(&self) -> &T {
83         &self.data
84     }
85 
86     /// Returns a mutable reference to this frame's payload.
87     ///
88     /// This does **not** include any padding that might have been originally
89     /// included.
payload_mut(&mut self) -> &mut T90     pub fn payload_mut(&mut self) -> &mut T {
91         &mut self.data
92     }
93 
94     /// Consumes `self` and returns the frame's payload.
95     ///
96     /// This does **not** include any padding that might have been originally
97     /// included.
into_payload(self) -> T98     pub fn into_payload(self) -> T {
99         self.data
100     }
101 
head(&self) -> Head102     pub(crate) fn head(&self) -> Head {
103         Head::new(Kind::Data, self.flags.into(), self.stream_id)
104     }
105 
map<F, U>(self, f: F) -> Data<U> where F: FnOnce(T) -> U,106     pub(crate) fn map<F, U>(self, f: F) -> Data<U>
107     where
108         F: FnOnce(T) -> U,
109     {
110         Data {
111             stream_id: self.stream_id,
112             data: f(self.data),
113             flags: self.flags,
114             pad_len: self.pad_len,
115         }
116     }
117 }
118 
119 impl Data<Bytes> {
load(head: Head, mut payload: Bytes) -> Result<Self, Error>120     pub(crate) fn load(head: Head, mut payload: Bytes) -> Result<Self, Error> {
121         let flags = DataFlags::load(head.flag());
122 
123         // The stream identifier must not be zero
124         if head.stream_id().is_zero() {
125             return Err(Error::InvalidStreamId);
126         }
127 
128         let pad_len = if flags.is_padded() {
129             let len = util::strip_padding(&mut payload)?;
130             Some(len)
131         } else {
132             None
133         };
134 
135         Ok(Data {
136             stream_id: head.stream_id(),
137             data: payload,
138             flags,
139             pad_len,
140         })
141     }
142 }
143 
144 impl<T: Buf> Data<T> {
145     /// Encode the data frame into the `dst` buffer.
146     ///
147     /// # Panics
148     ///
149     /// Panics if `dst` cannot contain the data frame.
encode_chunk<U: BufMut>(&mut self, dst: &mut U)150     pub(crate) fn encode_chunk<U: BufMut>(&mut self, dst: &mut U) {
151         let len = self.data.remaining() as usize;
152 
153         assert!(dst.remaining_mut() >= len);
154 
155         self.head().encode(len, dst);
156         dst.put(&mut self.data);
157     }
158 }
159 
160 impl<T> From<Data<T>> for Frame<T> {
from(src: Data<T>) -> Self161     fn from(src: Data<T>) -> Self {
162         Frame::Data(src)
163     }
164 }
165 
166 impl<T> fmt::Debug for Data<T> {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result167     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
168         let mut f = fmt.debug_struct("Data");
169         f.field("stream_id", &self.stream_id);
170         if !self.flags.is_empty() {
171             f.field("flags", &self.flags);
172         }
173         if let Some(ref pad_len) = self.pad_len {
174             f.field("pad_len", pad_len);
175         }
176         // `data` bytes purposefully excluded
177         f.finish()
178     }
179 }
180 
181 // ===== impl DataFlags =====
182 
183 impl DataFlags {
load(bits: u8) -> DataFlags184     fn load(bits: u8) -> DataFlags {
185         DataFlags(bits & ALL)
186     }
187 
is_empty(&self) -> bool188     fn is_empty(&self) -> bool {
189         self.0 == 0
190     }
191 
is_end_stream(&self) -> bool192     fn is_end_stream(&self) -> bool {
193         self.0 & END_STREAM == END_STREAM
194     }
195 
set_end_stream(&mut self)196     fn set_end_stream(&mut self) {
197         self.0 |= END_STREAM
198     }
199 
unset_end_stream(&mut self)200     fn unset_end_stream(&mut self) {
201         self.0 &= !END_STREAM
202     }
203 
is_padded(&self) -> bool204     fn is_padded(&self) -> bool {
205         self.0 & PADDED == PADDED
206     }
207 
208     #[cfg(feature = "unstable")]
set_padded(&mut self)209     fn set_padded(&mut self) {
210         self.0 |= PADDED
211     }
212 }
213 
214 impl Default for DataFlags {
default() -> Self215     fn default() -> Self {
216         DataFlags(0)
217     }
218 }
219 
220 impl From<DataFlags> for u8 {
from(src: DataFlags) -> u8221     fn from(src: DataFlags) -> u8 {
222         src.0
223     }
224 }
225 
226 impl fmt::Debug for DataFlags {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result227     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
228         util::debug_flags(fmt, self.0)
229             .flag_if(self.is_end_stream(), "END_STREAM")
230             .flag_if(self.is_padded(), "PADDED")
231             .finish()
232     }
233 }
234