| 1 | use std::fmt; |
| 2 | |
| 3 | use super::Error; |
| 4 | use bytes::{Buf, Bytes}; |
| 5 | |
| 6 | /// Strip padding from the given payload. |
| 7 | /// |
| 8 | /// It is assumed that the frame had the padded flag set. This means that the |
| 9 | /// first byte is the length of the padding with that many |
| 10 | /// 0 bytes expected to follow the actual payload. |
| 11 | /// |
| 12 | /// # Returns |
| 13 | /// |
| 14 | /// A slice of the given payload where the actual one is found and the length |
| 15 | /// of the padding. |
| 16 | /// |
| 17 | /// If the padded payload is invalid (e.g. the length of the padding is equal |
| 18 | /// to the total length), returns `None`. |
| 19 | pub fn strip_padding(payload: &mut Bytes) -> Result<u8, Error> { |
| 20 | let payload_len: usize = payload.len(); |
| 21 | if payload_len == 0 { |
| 22 | // If this is the case, the frame is invalid as no padding length can be |
| 23 | // extracted, even though the frame should be padded. |
| 24 | return Err(Error::TooMuchPadding); |
| 25 | } |
| 26 | |
| 27 | let pad_len: usize = payload[0] as usize; |
| 28 | |
| 29 | if pad_len >= payload_len { |
| 30 | // This is invalid: the padding length MUST be less than the |
| 31 | // total frame size. |
| 32 | return Err(Error::TooMuchPadding); |
| 33 | } |
| 34 | |
| 35 | payload.advance(cnt:1); |
| 36 | payload.truncate(len:payload_len - pad_len - 1); |
| 37 | |
| 38 | Ok(pad_len as u8) |
| 39 | } |
| 40 | |
| 41 | pub(super) fn debug_flags<'a, 'f: 'a>( |
| 42 | fmt: &'a mut fmt::Formatter<'f>, |
| 43 | bits: u8, |
| 44 | ) -> DebugFlags<'a, 'f> { |
| 45 | let result: Result<(), Error> = write!(fmt, "( {:#x}" , bits); |
| 46 | DebugFlags { |
| 47 | fmt, |
| 48 | result, |
| 49 | started: false, |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | pub(super) struct DebugFlags<'a, 'f: 'a> { |
| 54 | fmt: &'a mut fmt::Formatter<'f>, |
| 55 | result: fmt::Result, |
| 56 | started: bool, |
| 57 | } |
| 58 | |
| 59 | impl<'a, 'f: 'a> DebugFlags<'a, 'f> { |
| 60 | pub(super) fn flag_if(&mut self, enabled: bool, name: &str) -> &mut Self { |
| 61 | if enabled { |
| 62 | self.result = self.result.and_then(|()| { |
| 63 | let prefix: &'static str = if self.started { |
| 64 | " | " |
| 65 | } else { |
| 66 | self.started = true; |
| 67 | ": " |
| 68 | }; |
| 69 | |
| 70 | write!(self.fmt, " {}{}" , prefix, name) |
| 71 | }); |
| 72 | } |
| 73 | self |
| 74 | } |
| 75 | |
| 76 | pub(super) fn finish(&mut self) -> fmt::Result { |
| 77 | self.result.and_then(|()| write!(self.fmt, ")" )) |
| 78 | } |
| 79 | } |
| 80 | |