Implement better heck encoding (not used yet)

This commit is contained in:
xenia 2020-03-13 20:28:33 -04:00
parent e042551263
commit a6d4af87ce
5 changed files with 50 additions and 22 deletions

View File

@ -4,6 +4,8 @@ all: release-build
debug-build:
cargo build
cp ./target/debug/hptp-recv ./3700recv
cp ./target/debug/hptp-send ./3700send
release-build:
cargo build --release

View File

@ -7,16 +7,16 @@ lazy_static! {
static WRAP_SIZE: usize = 60;
pub fn can_be_encoded(data: &[u8]) -> bool {
ENCODING_DETECTOR.is_match(data)
}
#[derive(Clone)]
pub struct MeowCoder {
line_index: usize,
}
impl MeowCoder {
pub fn can_be_encoded(data: &[u8]) -> bool {
ENCODING_DETECTOR.is_match(data)
}
pub fn new() -> MeowCoder {
MeowCoder{line_index: 0}
}
@ -43,7 +43,7 @@ impl MeowCoder {
(LOOKUP[first as usize], LOOKUP[second as usize])
}
pub fn encode(input: &Vec<u8>) -> Vec<u8> {
pub fn encode(input: &Vec<u8>) -> (Vec<u8>, bool) {
let mut out: Vec<u8> = Vec::new();
let mut prev_char: u8 = 0;
let mut pair_first = false;
@ -61,15 +61,23 @@ impl MeowCoder {
pair_first = false;
}
}
out
// trailing byte specifies whether this was cut or not
if pair_first {
out.push(MeowCoder::hex_to_nibble(prev_char) * 16);
(out, true)
} else {
(out, false)
}
}
pub fn decode(&mut self, input: &Vec<u8>) -> Vec<u8> {
pub fn decode(&mut self, input: &Vec<u8>, was_cut: bool) -> Vec<u8> {
let mut out: Vec<u8> = Vec::new();
for byte in input {
for (pos, byte) in input.iter().enumerate() {
let (first, second) = MeowCoder::u8_to_hex(*byte);
out.push(first);
out.push(second);
if pos < input.len() - 1 || !was_cut {
out.push(second);
}
self.line_index += 2;
if self.line_index == WRAP_SIZE {
self.line_index = 0;
@ -86,27 +94,43 @@ mod tests {
#[test]
fn test_match() {
assert_eq!(can_be_encoded(b"abcd1234"), true);
assert_eq!(can_be_encoded(b"abcXd1234"), false);
assert_eq!(can_be_encoded(b"012345678901234567890123456789012345678901234567890123456789\nabcdef"), true);
assert_eq!(can_be_encoded(b"01234567890123456789012345678901234567890123456789012345678\nabcdef"), false);
assert_eq!(can_be_encoded(b"\x12\xab\x45\n"), false);
assert_eq!(MeowCoder::can_be_encoded(b"abcd1234"), true);
assert_eq!(MeowCoder::can_be_encoded(b"abcXd1234"), false);
assert_eq!(MeowCoder::can_be_encoded(b"012345678901234567890123456789012345678901234567890123456789\nabcdef"), true);
assert_eq!(MeowCoder::can_be_encoded(b"01234567890123456789012345678901234567890123456789012345678\nabcdef"), false);
assert_eq!(MeowCoder::can_be_encoded(b"\x12\xab\x45\n"), false);
}
#[test]
fn test_encode() {
let vec = vec!['a' as u8, '4' as u8, 'c' as u8, 'd' as u8,
'\n' as u8, 'e' as u8, 'f' as u8];
assert_eq!(MeowCoder::encode(&vec), vec![0xa4, 0xcd, 0xef]);
assert_eq!(MeowCoder::encode(&vec), (vec![0xa4, 0xcd, 0xef], false));
let vec2 = vec!['a' as u8, '4' as u8, 'c' as u8, 'd' as u8,
'\n' as u8, 'e' as u8, 'f' as u8, '9' as u8];
assert_eq!(MeowCoder::encode(&vec2), (vec![0xa4, 0xcd, 0xef, 0x90], true));
}
#[test]
fn test_encode_decode() {
let hex_str: &[u8] = b"012345678901234567890123456789012345678901234567890123456789\nabcdef";
let vec: Vec<u8> = Vec::from(hex_str);
let vec2 = MeowCoder::encode(&vec);
let (vec2, was_cut) = MeowCoder::encode(&vec);
assert_eq!(was_cut, false);
let mut coder = MeowCoder::new();
let out = coder.decode(&vec2);
let out = coder.decode(&vec2, was_cut);
assert_eq!(out, vec);
}
#[test]
fn test_encode_decode_cut() {
let hex_str: &[u8] = b"012345678901234567890123456789012345678901234567890123456789\nabcdef3";
let vec: Vec<u8> = Vec::from(hex_str);
let (vec2, was_cut) = MeowCoder::encode(&vec);
assert_eq!(was_cut, true);
let mut coder = MeowCoder::new();
let out = coder.decode(&vec2, was_cut);
assert_eq!(out, vec);
}
}

View File

@ -31,6 +31,7 @@ pub trait SerDes: Sized {
type BO = byteorder::LE;
const LAST_SEG_MASK: u32 = 1 << 31;
const MEOW_CODED_MASK: u32 = 1 << 30;
impl SerDes for UpMsg {
fn des(buf: &[u8]) -> Result<Self, DesError> {
@ -39,11 +40,11 @@ impl SerDes for UpMsg {
} else {
let hdr = BO::read_u32(&buf[0..4]);
Ok(UpMsg::Data {
seg_idx: hdr & !LAST_SEG_MASK,
seg_idx: hdr & !LAST_SEG_MASK & !MEOW_CODED_MASK,
payload: SegData {
bytes: buf[4..].into(),
is_last_segment: (hdr & LAST_SEG_MASK) != 0,
is_meow_encoded: false,
is_meow_encoded: (hdr & MEOW_CODED_MASK) != 0,
},
})
}
@ -60,7 +61,8 @@ impl SerDes for UpMsg {
},
seg_idx,
} => {
let hdr = *seg_idx | if *is_last_segment { LAST_SEG_MASK } else { 0 };
let hdr = *seg_idx | if *is_last_segment { LAST_SEG_MASK } else { 0 }
| if *is_meow_encoded { MEOW_CODED_MASK } else { 0 };
BO::write_u32(&mut buf[0..4], hdr);
let len = bytes.len();
buf[4..4 + len].copy_from_slice(&bytes[..]);

View File

@ -50,7 +50,7 @@ pub struct SegmentSet {
#[derive(Clone)]
pub struct SegData {
pub(crate) bytes: Vec<u8>,
pub bytes: Vec<u8>,
pub is_last_segment: bool,
pub is_meow_encoded: bool,
}

View File

@ -8,5 +8,5 @@ sudo unshare -n capsh --caps="cap_net_admin+eip cap_setpcap,cap_setuid,cap_setgi
-- -c "export PATH=$PWD/.netsim:\$PATH; export HOME=$PWD; /usr/bin/ip link set lo up; netsim; \
export PERL5LIB=\"/home/$USER/perl5/lib/perl5\${PERL5LIB:+:\${PERL5LIB}}\" \
export PERL_LOCAL_LIB_ROOT=\"/home/$USER/perl5\${PERL_LOCAL_LIB_ROOT:+:\${PERL_LOCAL_LIB_ROOT}}\" \
tc qdisc show dev lo; /bin/bash --init-file <(echo unset HISTFILE)"
tc qdisc show dev lo; cd .netsim; /bin/bash --init-file <(echo unset HISTFILE)"
true