pub struct RunlengthCodec {
pub rle_val : u64,
pub shift_up_1: bool }
impl RunlengthCodec {
fn encode_literal(&self, lit: u64) -> u64 {
if self.shift_up_1{
lit+1
} else {
lit
}
}
fn decode_literal(&self, item: u64) -> u64 {
if self.shift_up_1 {
item -1
} else {
item
}
}
pub fn encode(&self, input: impl Iterator<Item=u64>) -> Vec<u64>{
let mut encoded: Vec<u64> = Vec::new();
let mut runlen = 0;
for x in input {
if x == self.rle_val {
runlen += 1;
}
else {
if runlen > 0 {
let val = self.encode_literal(self.rle_val);
encoded.push(val);
encoded.push(runlen);
runlen = 0;
}
encoded.push(
self.encode_literal(x)
);
}
}
if runlen >0 {
let val = self.encode_literal(self.rle_val);
encoded.push(val);
encoded.push(runlen);
}
encoded
}
pub fn decode(&self, input: Vec<u64>) -> Vec<u64>{
let mut decoded = Vec::with_capacity(input.len()); let mut iii = input.iter();
while let Some(&item) = iii.next() {
let adjusted_item = self.decode_literal(item);
if adjusted_item == (self.rle_val) {
let runlen = *iii.next().unwrap(); for _ in 0..runlen {
decoded.push(adjusted_item);
}
} else {
decoded.push(adjusted_item);
}
}
decoded
}
}
#[cfg(test)]
mod test {
use crate::busz::runlength_codec::RunlengthCodec;
#[test]
fn test_encode_decode_single_run(){
let c = RunlengthCodec { rle_val: 0, shift_up_1: true };
let plain = vec![0,0,0];
let enc = c.encode(plain.clone().into_iter());
assert!(plain.len()> enc.len());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
#[test]
fn test_encode_decode_no_run(){
let c = RunlengthCodec { rle_val: 0, shift_up_1: true };
let plain = vec![1,2,1];
let enc = c.encode(plain.clone().into_iter());
assert!(plain.len()== enc.len());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
#[test]
fn test_encode_decode_minxed_run(){
let c = RunlengthCodec { rle_val: 0, shift_up_1: true };
let plain = vec![1,0,0, 2,0,1,0];
let enc = c.encode(plain.clone().into_iter());
assert!(plain.len()< enc.len());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
#[test]
fn test_encode_decode_minxed_run_rle1(){
let c = RunlengthCodec { rle_val: 1, shift_up_1: true };
let plain = vec![0,1,1, 1,1, 0];
let enc = c.encode(plain.clone().into_iter());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
#[test]
fn test_encode_decode_minxed_run_rle1_1(){
let c = RunlengthCodec { rle_val: 1 , shift_up_1: true};
let plain = vec![0,1,1,];
let enc = c.encode(plain.clone().into_iter());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
#[test]
fn test_encode_decode_no_shift(){
let c = RunlengthCodec { rle_val: 0 , shift_up_1: false};
let plain = vec![0,0,1,1,];
let enc = c.encode(plain.clone().into_iter());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
#[test]
fn test_encode_decode_no_shift_2(){
let c = RunlengthCodec { rle_val: 1 , shift_up_1: false};
let plain = vec![0,0,1,1,];
let enc = c.encode(plain.clone().into_iter());
let dec = c.decode(enc);
assert_eq!(plain, dec)
}
}