netreplay/src/util.rs

130 lines
2.9 KiB
Rust

use std::iter::Peekable;
use crate::record::Direction;
fn hex_digit(c: u8) -> u32 {
((c & !(16 | 32 | 64)) + ((c & 64) >> 6) * 9) as _
}
pub fn parse_hex(s: &[u8]) -> u32 {
let mut r = 0;
for i in s.iter() {
r <<= 4;
r |= hex_digit(*i);
}
r
}
pub fn is_hex(s: &[u8]) -> bool {
s.iter().all(|c| {
let c = *c | 32;
(c >= b'a' && c <= b'f') || (c >= b'0' && c <= b'9')
})
}
/// Print ASCII if possible
pub fn print_bin(s: &[u8]) {
if let Ok(s) = str::from_utf8(s) {
println!("{s}");
} else {
let mut buf = String::new();
for c in s {
if c.is_ascii_control() && *c != b'\n' {
continue;
}
if let Some(c) = c.as_ascii() {
buf.push_str(c.as_str());
} else {
for c in std::ascii::escape_default(*c) {
buf.push(c.as_ascii().unwrap().into());
}
}
}
println!("{buf}");
}
}
pub struct ResponseStreamer<I: Iterator>(Peekable<I>);
impl<'a, I: Iterator> ResponseStreamer<I> {
pub fn new(inner: I) -> Self {
Self(inner.peekable())
}
}
impl<'a, I: Iterator<Item = &'a (Direction, Vec<u8>)>> Iterator for ResponseStreamer<I> {
type Item = (&'a Direction, Vec<&'a Vec<u8>>);
fn next(&mut self) -> Option<Self::Item> {
let (direction, first_item) = self.0.next()?;
let mut items = vec![first_item];
while let Some((item_direction, _item)) = self.0.peek()
&& item_direction == direction
{
items.push(&self.0.next().unwrap().1);
}
Some((direction, items))
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_hex_digit() {
assert_eq!(hex_digit(b'0'), 0);
assert_eq!(hex_digit(b'1'), 1);
assert_eq!(hex_digit(b'2'), 2);
assert_eq!(hex_digit(b'3'), 3);
assert_eq!(hex_digit(b'4'), 4);
assert_eq!(hex_digit(b'5'), 5);
assert_eq!(hex_digit(b'6'), 6);
assert_eq!(hex_digit(b'7'), 7);
assert_eq!(hex_digit(b'8'), 8);
assert_eq!(hex_digit(b'9'), 9);
assert_eq!(hex_digit(b'a'), 10);
assert_eq!(hex_digit(b'b'), 11);
assert_eq!(hex_digit(b'c'), 12);
assert_eq!(hex_digit(b'd'), 13);
assert_eq!(hex_digit(b'e'), 14);
assert_eq!(hex_digit(b'f'), 15);
assert_eq!(hex_digit(b'A'), 10);
assert_eq!(hex_digit(b'B'), 11);
assert_eq!(hex_digit(b'C'), 12);
assert_eq!(hex_digit(b'D'), 13);
assert_eq!(hex_digit(b'E'), 14);
assert_eq!(hex_digit(b'F'), 15);
}
#[test]
fn test_parse_hex() {
assert_eq!(parse_hex(b"abc123"), 0xabc123);
assert_eq!(parse_hex(b"1"), 1);
}
#[test]
fn test_is_hex() {
assert!(is_hex(b"0"));
assert!(is_hex(b"1"));
assert!(is_hex(b"2"));
assert!(is_hex(b"3"));
assert!(is_hex(b"4"));
assert!(is_hex(b"5"));
assert!(is_hex(b"6"));
assert!(is_hex(b"7"));
assert!(is_hex(b"8"));
assert!(is_hex(b"9"));
assert!(is_hex(b"a"));
assert!(is_hex(b"b"));
assert!(is_hex(b"c"));
assert!(is_hex(b"d"));
assert!(is_hex(b"e"));
assert!(is_hex(b"f"));
assert!(is_hex(b"A"));
assert!(is_hex(b"B"));
assert!(is_hex(b"C"));
assert!(is_hex(b"D"));
assert!(is_hex(b"E"));
assert!(is_hex(b"F"));
}
}