wtx 0.28.0

A collection of different transport implementations and related tools focused primarily on web technologies.
#[doc = _internal_doc!()]
#[inline]
pub(crate) fn unmask(bytes: &mut [u8], mask: [u8; 4]) {
  _simd_bytes!(
    (align_to_mut, bytes),
    |bytes| {
      #[allow(clippy::indexing_slicing, reason = "index will never be out-of-bounds")]
      for (idx, elem) in bytes.iter_mut().enumerate() {
        *elem ^= mask[idx & 3];
      }
    },
    |prefix| {
      let mut local_mask = mask;
      local_mask.rotate_left(prefix.len() % 4);
    },
    |_16| {
      let [a, b, c, d] = mask;
      _do_unmask(&[a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d], _16);
    },
    |_32| {
      let [a, b, c, d] = mask;
      _do_unmask(
        &[
          a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d, a, b,
          c, d,
        ],
        _32,
      );
    },
    |_64| {
      let [a, b, c, d] = mask;
      _do_unmask(
        &[
          a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d, a, b,
          c, d, a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d, a, b, c, d,
          a, b, c, d,
        ],
        _64,
      );
    },
    |_suffix| {}
  );
}

#[inline]
fn _do_unmask<const N: usize>(mask: &[u8], slice: &mut [[u8; N]]) {
  for array in slice {
    for (array_elem, mask_elem) in array.iter_mut().zip(mask) {
      *array_elem ^= mask_elem;
    }
  }
}

#[cfg(all(feature = "_bench", test))]
mod bench {
  use crate::bench::_data;

  #[bench]
  fn unmask(b: &mut test::Bencher) {
    let mut data = _data(1024 * 1024 * 8);
    b.iter(|| crate::web_socket::unmask::unmask(&mut data, [3, 5, 7, 11]));
  }
}

#[cfg(kani)]
mod kani {
  use crate::misc::Vector;

  #[kani::proof]
  fn unmask() {
    let mask = kani::any();
    let mut payload = Vector::from(kani::vec::any_vec::<u8, 128>());
    payload.fill(0);
    crate::web_socket::unmask::unmask(&mut payload, mask);
    let expected = Vector::from_iter((0..payload.len()).map(|idx| mask[idx & 3])).unwrap();
    assert_eq!(payload, expected);
  }
}

#[cfg(test)]
mod tests {
  use crate::{misc::Vector, web_socket::unmask::unmask};

  #[test]
  fn length_variation_unmask() {
    for len in [0, 2, 3, 8, 16, 18, 31, 32, 40, 63, 100, 125, 256] {
      let mut payload = Vector::from_cloneable_elem(len, 0).unwrap();
      let mask = [1, 2, 3, 4];
      unmask(&mut payload, mask);
      let expected = Vector::from_iter((0..len).map(|idx| mask[idx & 3])).unwrap();
      assert_eq!(payload, expected);
    }
  }

  #[test]
  fn unmask_has_correct_output() {
    let mut payload = [0u8; 33];
    let mask = [1, 2, 3, 4];
    unmask(&mut payload, mask);
    assert_eq!(
      &payload,
      &[
        1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2,
        3, 4, 1
      ]
    );
  }
}