pub type EOByte = u8;
pub type EOChar = u8;
pub type EOShort = u16;
pub type EOThree = u32;
pub type EOInt = u32;
pub const MAX1: EOInt = 253;
pub const MAX2: EOInt = 64009;
pub const MAX3: EOInt = 16194277;
pub const MAX4: EOInt = 4097152080;
pub const EO_BREAK_CHAR: EOByte = 0xFF;
pub fn encode_number(mut number: EOInt) -> [EOByte; 4] {
if number > MAX4 {
panic!("Cannot encode {} it exceeds max value of {}", number, MAX4);
}
let mut bytes: [EOByte; 4] = [254, 254, 254, 254];
let original_number = number;
if original_number >= MAX3 {
bytes[3] = (number / MAX3) as EOByte + 1;
number %= MAX3;
}
if original_number >= MAX2 {
bytes[2] = (number / MAX2) as EOByte + 1;
number %= MAX2;
}
if original_number >= MAX1 {
bytes[1] = (number / MAX1) as EOByte + 1;
number %= MAX1;
}
bytes[0] = number as EOByte + 1;
bytes
}
pub fn decode_number(bytes: &[EOByte]) -> EOInt {
let mut data: [EOInt; 4] = [254, 254, 254, 254];
for i in 0..4 {
if bytes.len() > i && bytes[i] != 0 {
data[i] = bytes[i].into();
}
if data[i] == 254 {
data[i] = 1;
}
data[i] -= 1;
}
(data[3] * MAX3) + (data[2] * MAX2) + (data[1] * MAX1) + data[0]
}
pub fn encode_map_string(s: &str, length: usize) -> Bytes {
let mut buf = BytesMut::with_capacity(length);
buf.put_bytes(0xFF, length);
for (i, c) in s.chars().enumerate() {
buf[i] = c as u8;
}
let mut flippy = buf.len() % 2 == 1;
for c in buf.iter_mut() {
if flippy {
if (0x22..=0x4F).contains(c) {
*c = 0x71 - *c;
} else if (0x50..=0x7E).contains(c) {
*c = 0xCD - *c;
}
} else if (0x22..=0x7E).contains(c) {
*c = 0x9F - *c;
}
flippy = !flippy;
}
buf.reverse();
buf.freeze()
}
pub fn decode_map_string(bytes: Bytes) -> String {
let mut buf = BytesMut::with_capacity(bytes.len());
buf.put(bytes);
buf.reverse();
let mut chars = BytesMut::with_capacity(buf.len());
chars.put_bytes(0xFF, buf.len());
let mut flippy = buf.len() % 2 == 1;
for (i, c) in buf.iter_mut().enumerate() {
if *c == 0xFF {
chars.truncate(i);
break;
}
if flippy {
if (0x22..=0x4F).contains(c) {
*c = 0x71 - *c;
} else if (0x50..=0x7E).contains(c) {
*c = 0xCD - *c;
}
} else if (0x22..=0x7E).contains(c) {
*c = 0x9F - *c;
}
chars[i] = *c;
flippy = !flippy;
}
String::from_utf8_lossy(&chars).to_string()
}
mod stream_builder;
use bytes::{Bytes, BytesMut, BufMut};
pub use stream_builder::StreamBuilder;
mod stream_reader;
pub use stream_reader::StreamReader;
mod serializeable;
pub use serializeable::Serializeable;
#[cfg(test)]
mod tests {
use super::{EOByte, EOInt};
#[test]
fn encode_number() {
let mut test_numbers: Vec<(EOInt, [EOByte; 4])> = Vec::with_capacity(11);
test_numbers.push((0, [1, 254, 254, 254]));
test_numbers.push((5, [6, 254, 254, 254]));
test_numbers.push((42, [43, 254, 254, 254]));
test_numbers.push((253, [1, 2, 254, 254]));
test_numbers.push((533, [28, 3, 254, 254]));
test_numbers.push((9001, [147, 36, 254, 254]));
test_numbers.push((64009, [1, 1, 2, 254]));
test_numbers.push((888888, [100, 225, 14, 254]));
test_numbers.push((7162531, [102, 228, 112, 254]));
test_numbers.push((16194277, [1, 1, 1, 2]));
test_numbers.push((18994242, [15, 189, 44, 2]));
for d in test_numbers {
let bytes = super::encode_number(d.0);
assert_eq!(bytes, d.1);
}
}
#[test]
fn decode_number() {
let mut test_numbers: Vec<(EOInt, [EOByte; 4])> = Vec::with_capacity(11);
test_numbers.push((0, [1, 254, 254, 254]));
test_numbers.push((5, [6, 254, 254, 254]));
test_numbers.push((42, [43, 254, 254, 254]));
test_numbers.push((253, [1, 2, 254, 254]));
test_numbers.push((533, [28, 3, 254, 254]));
test_numbers.push((9001, [147, 36, 254, 254]));
test_numbers.push((64009, [1, 1, 2, 254]));
test_numbers.push((888888, [100, 225, 14, 254]));
test_numbers.push((7162531, [102, 228, 112, 254]));
test_numbers.push((16194277, [1, 1, 1, 2]));
test_numbers.push((18994242, [15, 189, 44, 2]));
for d in test_numbers {
let number = super::decode_number(&d.1);
assert_eq!(number, d.0);
}
}
}