use bitvec::prelude::*;
use std::io;
const STOP_BYTE: u8 = 0x80;
const SIGNIFICANT_BYTE: u8 = !STOP_BYTE;
const NEGATIVE_SIGN_MASK: u8 = 0x40;
pub trait Codec {
fn deserialize(&mut self, input: &mut impl io::Read) -> io::Result<usize>;
fn serialize(&self, output: &mut impl io::Write) -> io::Result<usize>;
}
impl Codec for u32 {
fn serialize(&self, output: &mut impl io::Write) -> io::Result<usize> {
let mut bytes = [0u8; 5];
let i;
if *self >= 0x1000_0000 {
bytes[0] = (self >> 28) as u8;
bytes[1] = (self >> 21) as u8 & SIGNIFICANT_BYTE;
bytes[2] = (self >> 14) as u8 & SIGNIFICANT_BYTE;
bytes[3] = (self >> 7) as u8 & SIGNIFICANT_BYTE;
bytes[4] = *self as u8 | STOP_BYTE;
i = 5;
} else if *self >= 0x20_0000 {
bytes[0] = (self >> 21) as u8 & SIGNIFICANT_BYTE;
bytes[1] = (self >> 14) as u8 & SIGNIFICANT_BYTE;
bytes[2] = (self >> 7) as u8 & SIGNIFICANT_BYTE;
bytes[3] = *self as u8 | STOP_BYTE;
i = 4;
} else if *self >= 0x4000 {
bytes[0] = (self >> 14) as u8 & SIGNIFICANT_BYTE;
bytes[1] = (self >> 7) as u8 & SIGNIFICANT_BYTE;
bytes[2] = *self as u8 | STOP_BYTE;
i = 3;
} else if *self >= 0x80 {
bytes[0] = (self >> 7) as u8 & SIGNIFICANT_BYTE;
bytes[1] = *self as u8 | STOP_BYTE;
i = 2;
} else {
bytes[0] = *self as u8 | STOP_BYTE;
i = 1;
}
output.write_all(&bytes[..i])?;
Ok(i)
}
fn deserialize(&mut self, input: &mut impl io::Read) -> io::Result<usize> {
*self = 0;
let bytes = decode_stop_bit_entity(input)?;
for byte in &bytes {
*self = (*self << 7) | u32::from(*byte);
}
Ok(bytes.len())
}
}
impl Codec for i32 {
fn serialize(&self, output: &mut impl io::Write) -> io::Result<usize> {
let mut bytes = [0u8; 5];
let i;
let abs = self.abs();
if abs >= 0x800_0000 {
bytes[0] = (self >> 28) as u8;
bytes[1] = (self >> 21) as u8 & SIGNIFICANT_BYTE;
bytes[2] = (self >> 14) as u8 & SIGNIFICANT_BYTE;
bytes[3] = (self >> 7) as u8 & SIGNIFICANT_BYTE;
bytes[4] = *self as u8 | STOP_BYTE;
i = 5;
} else if abs >= 0x10_0000 {
bytes[0] = (self >> 21) as u8 & SIGNIFICANT_BYTE;
bytes[1] = (self >> 14) as u8 & SIGNIFICANT_BYTE;
bytes[2] = (self >> 7) as u8 & SIGNIFICANT_BYTE;
bytes[3] = *self as u8 | STOP_BYTE;
i = 4;
} else if abs >= 0x2000 {
bytes[0] = (self >> 14) as u8 & SIGNIFICANT_BYTE;
bytes[1] = (self >> 7) as u8 & SIGNIFICANT_BYTE;
bytes[2] = *self as u8 | STOP_BYTE;
i = 3;
} else if abs >= 0x40 {
bytes[0] = (self >> 7) as u8 & SIGNIFICANT_BYTE;
bytes[1] = *self as u8 | STOP_BYTE;
i = 2;
} else {
bytes[0] = *self as u8 | STOP_BYTE;
i = 1;
}
output.write_all(&bytes[..i])?;
Ok(i)
}
fn deserialize(&mut self, input: &mut impl io::Read) -> io::Result<usize> {
let bytes = decode_stop_bit_entity(input)?;
let is_negative = (bytes[0] & NEGATIVE_SIGN_MASK) != 0;
*self = -(is_negative as i32);
for byte in &bytes {
*self = (*self << 7) | i32::from(*byte);
}
Ok(bytes.len())
}
}
impl Codec for u64 {
fn deserialize(&mut self, _input: &mut impl io::Read) -> io::Result<usize> {
todo!();
}
fn serialize(&self, _output: &mut impl io::Write) -> io::Result<usize> {
todo!();
}
}
impl Codec for i64 {
fn deserialize(&mut self, _input: &mut impl io::Read) -> io::Result<usize> {
todo!();
}
fn serialize(&self, _output: &mut impl io::Write) -> io::Result<usize> {
todo!();
}
}
impl Codec for Vec<u8> {
fn serialize(&self, output: &mut impl io::Write) -> io::Result<usize> {
let len = self.len() as u32;
len.serialize(output)?;
output.write_all(self)?;
Ok(len as usize)
}
fn deserialize(&mut self, input: &mut impl io::Read) -> io::Result<usize> {
let mut len = 0u32;
len.deserialize(input)?;
*self = vec![0u8; len as usize];
input.read_exact(&mut self[..])?;
Ok(len as usize)
}
}
impl Codec for String {
fn serialize(&self, output: &mut impl io::Write) -> io::Result<usize> {
let len = self.len() as u32;
let bytes = self.as_bytes();
len.serialize(output)?;
output.write_all(bytes)?;
Ok(len as usize)
}
fn deserialize(&mut self, input: &mut impl io::Read) -> io::Result<usize> {
let mut len = 0u32;
len.deserialize(input)?;
let mut bytes = vec![0u8; len as usize];
input.read_exact(&mut bytes[..])?;
*self = String::from_utf8_lossy(&bytes[..]).to_string();
Ok(len as usize)
}
}
fn _serialize_bitvec(bits: &BitSlice<Msb0, u8>, output: &mut impl io::Write) -> io::Result<usize> {
let significant_data_bits_per_byte = bits.chunks_exact(7);
let mut i = 0;
let remaineder = significant_data_bits_per_byte.remainder().load::<u8>();
for significant_data_bits in significant_data_bits_per_byte {
let byte = significant_data_bits.load::<u8>();
if byte != 0 {
output.write_all(&[byte])?;
i += 1;
}
}
if remaineder != 0 {
output.write_all(&[STOP_BYTE | remaineder])?;
}
Ok(i)
}
#[derive(Debug, Clone)]
pub struct PresenceMap {
bits: BitVec,
}
impl PresenceMap {
pub fn bits(&self) -> impl Iterator<Item = &bool> {
self.bits.iter()
}
}
impl Codec for PresenceMap {
fn serialize(&self, _output: &mut impl io::Write) -> io::Result<usize> {
todo!();
}
fn deserialize(&mut self, input: &mut impl io::Read) -> io::Result<usize> {
self.bits = BitVec::new();
let mut stop_bit = false;
while !stop_bit {
let mut buffer = [0u8; 1];
input.read_exact(&mut buffer[..])?;
let byte = buffer[0];
stop_bit = byte >= STOP_BYTE;
if !stop_bit {
self.bits.push(byte >> 7 == 1);
}
self.bits.push((byte >> 6) & 1 == 1);
self.bits.push((byte >> 5) & 1 == 1);
self.bits.push((byte >> 4) & 1 == 1);
self.bits.push((byte >> 4) & 1 == 1);
self.bits.push((byte >> 3) & 1 == 1);
self.bits.push((byte >> 2) & 1 == 1);
self.bits.push((byte >> 1) & 1 == 1);
self.bits.push((byte >> 0) & 1 == 1);
}
Ok(self.bits.len())
}
}
pub fn decode_stop_bit_entity(input: &mut impl io::Read) -> io::Result<Vec<u8>> {
let mut bytes = Vec::new();
loop {
let mut byte = [0u8; 1];
input.read_exact(&mut byte[..])?;
if byte[0] >= STOP_BYTE {
byte[0] ^= STOP_BYTE;
bytes.push(byte[0]);
break;
} else {
bytes.push(byte[0]);
}
}
Ok(bytes)
}
#[allow(dead_code)]
pub fn decode_stop_bit_bitvec(input: &mut impl io::Read) -> io::Result<BitVec> {
let mut bits = BitVec::new();
let mut stop_bit = false;
while !stop_bit {
let mut buffer = [0u8; 1];
input.read_exact(&mut buffer[..])?;
let byte = buffer[0];
stop_bit = byte >= STOP_BYTE;
if !stop_bit {
bits.push(byte >> 7 == 1);
}
bits.push((byte >> 6) & 1 == 1);
bits.push((byte >> 5) & 1 == 1);
bits.push((byte >> 4) & 1 == 1);
bits.push((byte >> 4) & 1 == 1);
bits.push((byte >> 3) & 1 == 1);
bits.push((byte >> 2) & 1 == 1);
bits.push((byte >> 1) & 1 == 1);
bits.push((byte >> 0) & 1 == 1);
}
Ok(bits)
}
#[cfg(test)]
mod test {
use super::*;
use quickcheck_macros::quickcheck;
#[quickcheck]
fn encode_then_decode_u32(expected_value: u32) -> bool {
let mut bytes: Vec<u8> = Vec::new();
expected_value.serialize(&mut bytes).unwrap();
let mut value = 0u32;
value.deserialize(&mut &bytes[..]).unwrap();
value == expected_value
}
#[test]
fn encode_i32_example() {
let mut bytes: Vec<u8> = Vec::new();
(-794_2755_i32).serialize(&mut bytes).unwrap();
assert_eq!(bytes, vec![0x7c, 0x1b, 0x1b, 0x9d]);
}
#[test]
fn decode_i32_fast_doc_example() {
let bytes: Vec<u8> = vec![0x7c, 0x1b, 0x1b, 0x9d];
let mut value = 0i32;
value.deserialize(&mut &bytes[..]).unwrap();
assert_eq!(value, -794_2755);
}
#[test]
fn encode_64i32_regression() {
let mut bytes: Vec<u8> = Vec::new();
(64i32).serialize(&mut bytes).unwrap();
assert_eq!(bytes, vec![0x00, 0xc0]);
}
#[test]
fn encode_then_decode_99i32_regression() {
let expected_value = 99i32;
let mut bytes: Vec<u8> = Vec::new();
expected_value.serialize(&mut bytes).unwrap();
let mut value = 0i32;
value.deserialize(&mut &bytes[..]).unwrap();
assert_eq!(value, expected_value);
}
#[quickcheck]
fn encode_then_decode_string(expected_value: String) -> bool {
let mut bytes: Vec<u8> = Vec::new();
expected_value.serialize(&mut bytes).unwrap();
let mut value = String::default();
value.deserialize(&mut &bytes[..]).unwrap();
*value == expected_value
}
#[quickcheck]
fn encode_then_decode_bytes(expected_value: Vec<u8>) -> bool {
let mut bytes: Vec<u8> = Vec::default();
expected_value.serialize(&mut bytes).unwrap();
let mut value = Vec::default();
value.deserialize(&mut &bytes[..]).unwrap();
*value == expected_value
}
}