#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
#[cfg(feature = "std")]
use std::vec::Vec;
use super::CoreError;
#[allow(clippy::similar_names)]
pub fn decode_uu_data<'a, I>(lines: I) -> Result<Vec<u8>, CoreError>
where
I: Iterator<Item = &'a str>,
{
let mut result = Vec::new();
for line in lines {
let line = line.trim_start().trim_end_matches(['\n', '\r']);
if line.is_empty() {
continue;
}
if line == "end" || line.starts_with("end ") {
break;
}
let input_bytes = line.as_bytes();
if input_bytes.is_empty() {
continue;
}
let expected_length = (input_bytes[0].wrapping_sub(b' ')) as usize;
if expected_length > 45 {
continue;
}
if expected_length == 0 {
break;
}
let data_part = &input_bytes[1..];
let mut decoded_bytes = Vec::new();
for chunk in data_part.chunks(4) {
let mut group = [b' '; 4];
for (i, &byte) in chunk.iter().enumerate() {
group[i] = byte;
}
let c1 = group[0].wrapping_sub(b' ');
let c2 = group[1].wrapping_sub(b' ');
let c3 = group[2].wrapping_sub(b' ');
let c4 = group[3].wrapping_sub(b' ');
let decoded_byte1 = (c1 << 2) | (c2 >> 4);
let decoded_byte2 = ((c2 & 0x0F) << 4) | (c3 >> 2);
let decoded_byte3 = ((c3 & 0x03) << 6) | c4;
decoded_bytes.push(decoded_byte1);
decoded_bytes.push(decoded_byte2);
decoded_bytes.push(decoded_byte3);
}
decoded_bytes.truncate(expected_length);
result.extend_from_slice(&decoded_bytes);
}
Ok(result)
}