pub fn encode(source: &[u8], dest: &mut[u8]) -> usize {
let mut dest_index = 1;
let mut code_index = 0;
let mut num_between_sentinel = 1;
if source.is_empty() {
return 0;
}
for x in source {
if *x == 0 {
dest[code_index] = num_between_sentinel;
num_between_sentinel = 1;
code_index = dest_index;
dest_index += 1;
} else {
dest[dest_index] = *x;
num_between_sentinel += 1;
dest_index += 1;
if 0xFF == num_between_sentinel {
dest[code_index] = num_between_sentinel;
num_between_sentinel = 1;
code_index = dest_index;
dest_index += 1;
}
}
}
dest[code_index] = num_between_sentinel;
return dest_index;
}
pub fn encode_with_sentinel(source: &[u8], dest: &mut[u8], sentinel: u8) -> usize {
let encoded_size = encode(source, dest);
for x in &mut dest[..encoded_size] {
*x ^= sentinel;
}
return encoded_size;
}
pub fn encode_vec(source: &[u8]) -> Vec<u8> {
let mut encoded = vec![0; max_encoding_length(source.len())];
let encoded_len = encode(source, &mut encoded[..]);
encoded.truncate(encoded_len);
return encoded;
}
pub fn encode_vec_with_sentinel(source: &[u8], sentinel: u8) -> Vec<u8> {
let mut encoded = vec![0; max_encoding_length(source.len())];
let encoded_len = encode_with_sentinel(source, &mut encoded[..], sentinel);
encoded.truncate(encoded_len);
return encoded;
}
macro_rules! decode_raw (
($src:ident, $dst:ident) => ({
let mut source_index = 0;
let mut dest_index = 0;
while source_index < $src.len() {
let code = $src[source_index];
if source_index + code as usize > $src.len() && code != 1 {
return Err(());
}
source_index += 1;
for _ in (1..code) {
$dst[dest_index] = $src[source_index];
source_index += 1;
dest_index += 1;
}
if 0xFF != code && source_index < $src.len() {
$dst[dest_index] = 0;
dest_index += 1;
}
}
Ok(dest_index)
})
);
pub fn decode(source: &[u8], dest: &mut[u8]) -> Result<usize, ()> {
decode_raw!(source, dest)
}
pub fn decode_in_place(buff: &mut[u8]) -> Result<usize, ()> {
decode_raw!(buff, buff)
}
pub fn decode_with_sentinel(source: &[u8], dest: &mut[u8], sentinel: u8) -> Result<usize, ()> {
for (x, y) in source.iter().zip(dest.iter_mut()) {
*y = *x ^ sentinel;
}
decode_in_place(dest)
}
pub fn decode_in_place_with_sentinel(buff: &mut[u8], sentinel: u8) -> Result<usize, ()> {
for x in buff.iter_mut() {
*x ^= sentinel;
}
decode_in_place(buff)
}
pub fn decode_vec(source: &[u8]) -> Result<Vec<u8>, ()> {
let mut decoded = vec![0; source.len()];
match decode(source, &mut decoded[..]) {
Ok(n) => {
decoded.truncate(n);
Ok(decoded)
},
Err(()) => Err(()),
}
}
pub fn decode_vec_with_sentinel(source: &[u8], sentinel: u8) -> Result<Vec<u8>, ()> {
let mut decoded = vec![0; source.len()];
match decode_with_sentinel(source, &mut decoded[..], sentinel) {
Ok(n) => {
decoded.truncate(n);
Ok(decoded)
},
Err(()) => Err(()),
}
}
pub fn max_encoding_length(source_len: usize) -> usize {
source_len + (source_len / 254) + if source_len % 254 > 0 { 1 } else { 0 }
}