pub const fn encode_min_output_size(input_len: usize) -> usize {
if input_len == 0 {
1
} else {
input_len
}
}
pub const fn encode_max_output_size(input_len: usize) -> usize {
if input_len == 0 {
1
} else if input_len >= usize::max_value() - 253 {
usize::max_value()
} else {
let increase = (input_len + 253) / 254;
if input_len >= usize::max_value() - increase {
usize::max_value()
} else {
input_len + increase
}
}
}
fn encode_size_hint(in_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
let lower_bound = encode_min_output_size(in_hint.0);
let upper_bound = in_hint.1.map(|x| encode_max_output_size(x));
(lower_bound, upper_bound)
}
pub const fn decode_min_output_size(input_len: usize) -> usize {
if input_len >= 1 {
let increase = (input_len - 1) / 255;
input_len - 1 - increase
} else {
0
}
}
pub const fn decode_max_output_size(input_len: usize) -> usize {
input_len
}
fn decode_size_hint(in_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
let lower_bound = decode_min_output_size(in_hint.0);
let upper_bound = in_hint.1.map(|x| decode_max_output_size(x));
(lower_bound, upper_bound)
}
pub fn encode_array<'a>(out_buf: &'a mut [u8], in_buf: &[u8]) -> crate::Result<&'a [u8]> {
let mut code_i = 0;
let mut out_i = 1;
let mut last_value = 0_u8;
if code_i >= out_buf.len() {
return Err(crate::Error::OutputBufferTooSmall);
}
for x in in_buf {
if out_i - code_i >= 0xFF {
out_buf[code_i] = 0xFF;
code_i = out_i;
if code_i >= out_buf.len() {
return Err(crate::Error::OutputBufferTooSmall);
}
out_i = code_i + 1;
}
if *x == 0 {
out_buf[code_i] = (out_i - code_i) as u8;
code_i = out_i;
if code_i >= out_buf.len() {
return Err(crate::Error::OutputBufferTooSmall);
}
out_i = code_i + 1;
last_value = 0;
} else {
last_value = *x;
if out_i >= out_buf.len() {
return Err(crate::Error::OutputBufferTooSmall);
}
out_buf[out_i] = last_value;
out_i += 1;
}
}
if last_value >= (out_i - code_i) as u8 {
out_buf[code_i] = last_value;
out_i -= 1;
} else {
out_buf[code_i] = (out_i - code_i) as u8;
}
Ok(&out_buf[..out_i])
}
#[cfg(feature = "alloc")]
pub fn encode_vector(in_buf: &[u8]) -> crate::Result<alloc::vec::Vec<u8>> {
let mut code_i = 0;
let mut run_len = 0_u8;
let mut last_value = 0_u8;
let mut out_vec = alloc::vec::Vec::<u8>::with_capacity(encode_max_output_size(in_buf.len()));
for x in in_buf {
if run_len == 0xFF {
out_vec[code_i] = 0xFF;
code_i += 0xFF;
run_len = 0;
}
if *x == 0 {
if run_len == 0 {
out_vec.push(1);
code_i += 1;
} else {
out_vec[code_i] = run_len;
code_i += run_len as usize;
}
run_len = 0;
last_value = 0;
} else {
if run_len == 0 {
out_vec.push(0xFF);
run_len = 1;
}
last_value = *x;
out_vec.push(last_value);
run_len += 1;
}
}
if run_len == 0 {
out_vec.push(1);
} else if last_value >= run_len {
out_vec[code_i] = last_value;
out_vec.pop();
} else {
out_vec[code_i] = run_len;
}
Ok(out_vec)
}
struct EncodeIterator<I>
where
I: Iterator<Item = u8>,
{
in_iter: I,
in_lookahead: Option<Option<u8>>,
eof: bool,
last_run_0xff: bool,
hold_write_i: u8,
hold_read_i: u8,
hold_buf: [u8; 255],
}
impl<I> EncodeIterator<I>
where
I: Iterator<Item = u8>,
{
fn new(i: I) -> EncodeIterator<I> {
return EncodeIterator {
in_iter: i,
in_lookahead: None,
eof: false,
last_run_0xff: false,
hold_write_i: 0,
hold_read_i: 0,
hold_buf: [1; 255],
};
}
}
impl<I> Iterator for EncodeIterator<I>
where
I: Iterator<Item = u8>,
{
type Item = u8;
fn next(&mut self) -> Option<Self::Item> {
let mut last_byte: u8 = 0;
if self.hold_write_i != 0 {
if self.hold_read_i < self.hold_write_i {
let byte_val = self.hold_buf[self.hold_read_i as usize];
self.hold_read_i += 1;
return Some(byte_val);
} else {
self.hold_read_i = 0;
self.hold_write_i = 0;
}
}
if self.eof {
return None;
}
loop {
if self.hold_write_i == 0xFE {
self.last_run_0xff = true;
let in_iter_next = self.in_iter.next();
if in_iter_next.is_none() {
self.eof = true;
if last_byte >= 0xFF {
self.hold_write_i -= 1;
}
}
self.in_lookahead = Some(in_iter_next);
return Some(0xFF);
} else {
let in_iter_next = if self.in_lookahead.is_some() {
self.in_lookahead.take().unwrap()
} else {
self.in_iter.next()
};
let byte_val = in_iter_next.unwrap_or_else(|| {
self.eof = true;
0
});
if self.last_run_0xff {
self.last_run_0xff = false;
if self.eof {
return None;
}
}
if byte_val == 0 {
let run_len = self.hold_write_i + 1;
let count_byte = if self.eof && self.hold_write_i > 0 && last_byte >= run_len {
self.hold_write_i -= 1;
last_byte
} else {
run_len
};
return Some(count_byte);
} else {
last_byte = byte_val;
self.hold_buf[self.hold_write_i as usize] = byte_val;
self.hold_write_i += 1;
}
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let in_iter_size_hint = self.in_iter.size_hint();
encode_size_hint(in_iter_size_hint)
}
}
pub fn encode_iter<I>(i: I) -> impl Iterator<Item = u8>
where
I: Iterator<Item = u8>,
{
EncodeIterator::<I>::new(i)
}
pub fn encode_ref_iter<'a, I>(i: I) -> impl Iterator<Item = u8> + 'a
where
I: Iterator<Item = &'a u8> + 'a,
{
EncodeIterator::<_>::new(i.copied())
}
pub fn decode_array<'a>(out_buf: &'a mut [u8], in_buf: &[u8]) -> crate::Result<&'a [u8]> {
let mut code_i = 0;
let mut out_i = 0;
if !in_buf.is_empty() {
loop {
let code = in_buf[code_i];
if code == 0 {
return Err(crate::Error::ZeroInEncodedData);
}
for in_i in (code_i + 1)..(code_i + code as usize) {
if out_i >= out_buf.len() {
return Err(crate::Error::OutputBufferTooSmall);
}
if in_i >= in_buf.len() {
out_buf[out_i] = code;
out_i += 1;
break;
}
let in_byte = in_buf[in_i];
if in_byte == 0 {
return Err(crate::Error::ZeroInEncodedData);
}
out_buf[out_i] = in_byte;
out_i += 1;
}
code_i += code as usize;
if code_i >= in_buf.len() {
break;
}
if code < 0xFF {
if out_i >= out_buf.len() {
return Err(crate::Error::OutputBufferTooSmall);
}
out_buf[out_i] = 0;
out_i += 1;
}
}
}
Ok(&out_buf[..out_i])
}
#[cfg(feature = "alloc")]
pub fn decode_vector(in_buf: &[u8]) -> crate::Result<alloc::vec::Vec<u8>> {
let mut code_i = 0;
let mut out_vec = alloc::vec::Vec::<u8>::with_capacity(decode_max_output_size(in_buf.len()));
if !in_buf.is_empty() {
loop {
let code = in_buf[code_i];
if code == 0 {
return Err(crate::Error::ZeroInEncodedData);
}
for in_i in (code_i + 1)..(code_i + code as usize) {
if in_i >= in_buf.len() {
out_vec.push(code);
break;
}
let in_byte = in_buf[in_i];
if in_byte == 0 {
return Err(crate::Error::ZeroInEncodedData);
}
out_vec.push(in_byte);
}
code_i += code as usize;
if code_i >= in_buf.len() {
break;
}
if code < 0xFF {
out_vec.push(0);
}
}
}
Ok(out_vec)
}
struct DecodeIterator<I>
where
I: Iterator<Item = u8>,
{
in_iter: I,
eof: bool,
last_run: u8,
count_run: u8,
}
impl<I> DecodeIterator<I>
where
I: Iterator<Item = u8>,
{
fn new(i: I) -> DecodeIterator<I> {
return DecodeIterator {
in_iter: i,
eof: false,
last_run: 0,
count_run: 0,
};
}
}
impl<I> Iterator for DecodeIterator<I>
where
I: Iterator<Item = u8>,
{
type Item = u8;
fn next(&mut self) -> Option<Self::Item> {
loop {
if self.eof {
self.eof = false;
return None;
}
let in_iter_next = self.in_iter.next();
let byte_val = in_iter_next.unwrap_or(0);
if byte_val == 0 {
if self.count_run != 0 {
self.eof = true;
return Some(self.last_run);
} else {
return None;
}
}
if self.count_run == 0 {
let last_run = self.last_run;
self.last_run = byte_val;
self.count_run = byte_val - 1;
if last_run != 0 && last_run != 0xFF {
return Some(0);
}
} else {
self.count_run -= 1;
return Some(byte_val);
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let in_iter_size_hint = self.in_iter.size_hint();
decode_size_hint(in_iter_size_hint)
}
}
pub fn decode_iter<I>(i: I) -> impl Iterator<Item = u8>
where
I: Iterator<Item = u8>,
{
DecodeIterator::<I>::new(i)
}
pub fn decode_ref_iter<'a, I>(i: I) -> impl Iterator<Item = u8> + 'a
where
I: Iterator<Item = &'a u8> + 'a,
{
DecodeIterator::<_>::new(i.copied())
}
struct DecodeResultIterator<I>
where
I: Iterator<Item = u8>,
{
in_iter: I,
eof: bool,
last_run: u8,
count_run: u8,
}
impl<I> DecodeResultIterator<I>
where
I: Iterator<Item = u8>,
{
fn new(i: I) -> DecodeResultIterator<I> {
return DecodeResultIterator {
in_iter: i,
eof: false,
last_run: 0,
count_run: 0,
};
}
}
impl<I> Iterator for DecodeResultIterator<I>
where
I: Iterator<Item = u8>,
{
type Item = crate::Result<u8>;
fn next(&mut self) -> Option<Self::Item> {
loop {
if self.eof {
return None;
}
let in_iter_next = self.in_iter.next();
if in_iter_next.is_none() {
self.eof = true;
if self.count_run != 0 {
return Some(Ok(self.last_run));
} else {
return None;
}
}
let byte_val = in_iter_next.unwrap();
if byte_val == 0 {
self.eof = true;
return Some(Err(crate::Error::ZeroInEncodedData));
}
if self.count_run == 0 {
let last_run = self.last_run;
self.last_run = byte_val;
self.count_run = byte_val - 1;
if last_run != 0 && last_run != 0xFF {
return Some(Ok(0));
}
} else {
self.count_run -= 1;
return Some(Ok(byte_val));
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let in_iter_size_hint = self.in_iter.size_hint();
decode_size_hint(in_iter_size_hint)
}
}
pub fn decode_result_iter<I>(i: I) -> impl Iterator<Item = crate::Result<u8>>
where
I: Iterator<Item = u8>,
{
DecodeResultIterator::<I>::new(i)
}
pub fn decode_result_ref_iter<'a, I>(i: I) -> impl Iterator<Item = crate::Result<u8>> + 'a
where
I: Iterator<Item = &'a u8> + 'a,
{
DecodeResultIterator::<_>::new(i.copied())
}