use super::HcidResult;
pub fn cap_decode(
char_offset: usize,
data: &[u8],
char_erasures: &Vec<u8>,
) -> HcidResult<Option<u8>> {
let mut bin = String::new();
for i in 0..data.len() {
if char_erasures[char_offset + i] == b'1' {
bin.clear();
break;
}
let c = data[i];
if c >= b'A' && c <= b'Z' {
bin.push('1');
} else if c >= b'a' && c <= b'z' {
bin.push('0');
}
if bin.len() >= 8 {
break;
}
}
if bin.len() < 8 {
Ok(None)
} else {
Ok(Some(u8::from_str_radix(&bin, 2)?))
}
}
pub fn b32_correct(data: &[u8], char_erasures: &mut Vec<u8>) -> Vec<u8> {
let mut out: Vec<u8> = Vec::new();
let len = data.len();
for i in 0..len {
out.push(match data[i] {
b'0' => b'O',
b'1' | b'l' | b'L' => b'I',
b'2' => b'Z',
b'A'..=b'Z' | b'a'..=b'z' | b'3'..=b'9' => data[i],
_ => {
char_erasures[i] = b'1';
b'A'
}
})
}
out
}
pub fn char_lower(c: &mut u8) {
if *c >= b'A' && *c <= b'Z' {
*c ^= 32;
}
}
pub fn char_upper(c: &mut u8) {
if *c >= b'a' && *c <= b'z' {
*c ^= 32;
}
}
pub fn cap_encode_bin(seg: &mut [u8], bin: &[u8], min: usize) -> HcidResult<()> {
let mut count = 0;
let mut bin_idx = 0;
for c in seg.iter_mut() {
if bin_idx >= bin.len() {
char_lower(c);
continue;
}
if (*c >= b'A' && *c <= b'Z') || (*c >= b'a' && *c <= b'z') {
count += 1;
if bin[bin_idx] == b'1' {
char_upper(c);
} else {
char_lower(c);
}
bin_idx += 1;
}
}
if count < min {
for c in seg.iter_mut() {
char_lower(c);
}
}
Ok(())
}