Skip to main content

binocular/preview/
encoding.rs

1pub fn try_decode_utf16(bytes: &[u8]) -> Option<String> {
2    if bytes.len() < 2 {
3        return None;
4    }
5
6    if bytes[0] == 0xFF && bytes[1] == 0xFE {
7        return Some(decode_utf16(bytes, Endian::Little));
8    }
9
10    if bytes[0] == 0xFE && bytes[1] == 0xFF {
11        return Some(decode_utf16(bytes, Endian::Big));
12    }
13
14    None
15}
16
17enum Endian {
18    Little,
19    Big,
20}
21
22fn decode_utf16(bytes: &[u8], endian: Endian) -> String {
23    let u16_iter = bytes[2..].chunks_exact(2).map(|chunk| match endian {
24        Endian::Little => u16::from_le_bytes([chunk[0], chunk[1]]),
25        Endian::Big => u16::from_be_bytes([chunk[0], chunk[1]]),
26    });
27
28    char::decode_utf16(u16_iter)
29        .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
30        .collect()
31}