use byteorder::{ByteOrder, NetworkEndian};
const _RFC1071_CHUNK_SIZE: usize = 32;
#[allow(dead_code)]
pub(crate) fn confirm_checksum(mut data: &[u8]) -> u16 {
let mut acc = 0;
while data.len() >= _RFC1071_CHUNK_SIZE {
let mut d = &data[.._RFC1071_CHUNK_SIZE];
while d.len() >= 2 {
acc += NetworkEndian::read_u16(d) as u32;
d = &d[2..];
}
data = &data[_RFC1071_CHUNK_SIZE..];
}
while data.len() >= 2 {
acc += NetworkEndian::read_u16(data) as u32;
data = &data[2..];
}
if let Some(&v) = data.first() {
acc += (v as u32) << 8;
}
propagate_carries(acc)
}
#[allow(dead_code)]
fn propagate_carries(word: u32) -> u16 {
let sum = (word >> 16) + (word & 0xffff);
((sum >> 16) as u16) + (sum as u16)
}
pub(crate) fn one_complement_sum(data: &[u8], pos: Option<usize>) -> u16 {
let mut sum = 0u32;
let mut idx = 0;
while idx < data.len() {
if let Some(p) = pos {
if idx == p {
idx = p + 2; }
if idx == data.len() {
break;
}
};
let word = (data[idx] as u32) << 8 | data[idx + 1] as u32;
sum += word;
idx += 2;
}
while sum >> 16 != 0 {
sum = (sum >> 16) + (sum & 0xFFFF);
}
!sum as u16
}