anni_common/
decode.rs

1use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
2use std::io;
3use std::io::Read;
4use std::string::FromUtf8Error;
5use thiserror::Error;
6
7#[derive(Debug, Error)]
8pub enum DecodeError {
9    #[error(transparent)]
10    IOError(#[from] io::Error),
11    #[error(transparent)]
12    FromUtf8Error(#[from] FromUtf8Error),
13    #[error("invalid token, expected {expected:?}, got {got:?}")]
14    InvalidTokenError { expected: Vec<u8>, got: Vec<u8> },
15}
16
17type DecodeResult<T> = std::result::Result<T, DecodeError>;
18
19pub fn take<R: Read>(reader: &mut R, len: usize) -> DecodeResult<Vec<u8>> {
20    let (r, _) = take_sized(reader, len)?;
21    Ok(r)
22}
23
24pub fn take_sized<R: Read>(reader: &mut R, len: usize) -> std::io::Result<(Vec<u8>, u64)> {
25    let mut r = Vec::with_capacity(len);
26    let got = std::io::copy(&mut reader.take(len as u64), &mut r)?;
27    Ok((r, got))
28}
29
30pub fn take_to_end<R: Read>(reader: &mut R) -> DecodeResult<Vec<u8>> {
31    let mut r = Vec::new();
32    reader.read_to_end(&mut r)?;
33    Ok(r)
34}
35
36#[inline]
37pub fn take_string<R: Read>(reader: &mut R, len: usize) -> DecodeResult<String> {
38    Ok(String::from_utf8(take(reader, len)?)?)
39}
40
41#[inline]
42pub fn skip<R: Read>(reader: &mut R, len: usize) -> DecodeResult<u64> {
43    Ok(std::io::copy(
44        &mut reader.take(len as u64),
45        &mut std::io::sink(),
46    )?)
47}
48
49pub fn token<R: Read>(reader: &mut R, token: &[u8]) -> DecodeResult<()> {
50    let got = take(reader, token.len())?;
51    if got[..] == token[..] {
52        Ok(())
53    } else {
54        Err(DecodeError::InvalidTokenError {
55            expected: token.to_owned(),
56            got,
57        })
58    }
59}
60
61#[inline]
62pub fn u8<R: Read>(reader: &mut R) -> DecodeResult<u8> {
63    Ok(reader.read_u8()?)
64}
65
66#[inline]
67pub fn u32_le<R: Read>(reader: &mut R) -> DecodeResult<u32> {
68    Ok(reader.read_u32::<LittleEndian>()?)
69}
70
71#[inline]
72pub fn u32_be<R: Read>(reader: &mut R) -> DecodeResult<u32> {
73    Ok(reader.read_u32::<BigEndian>()?)
74}
75
76#[inline]
77pub fn u16_le<R: Read>(reader: &mut R) -> DecodeResult<u16> {
78    Ok(reader.read_u16::<LittleEndian>()?)
79}
80
81#[inline]
82pub fn u16_be<R: Read>(reader: &mut R) -> DecodeResult<u16> {
83    Ok(reader.read_u16::<BigEndian>()?)
84}
85
86#[inline]
87pub fn u24_le<R: Read>(reader: &mut R) -> DecodeResult<u32> {
88    Ok(reader.read_u24::<LittleEndian>()?)
89}
90
91#[inline]
92pub fn u24_be<R: Read>(reader: &mut R) -> DecodeResult<u32> {
93    Ok(reader.read_u24::<BigEndian>()?)
94}
95
96pub fn raw_to_string(input: &[u8]) -> String {
97    let mut detector = chardetng::EncodingDetector::new();
98    detector.feed(input, true);
99    let (result, encoding, _) = detector.guess(None, true).decode(input);
100    log::trace!("Encoding detected: {}", encoding.name());
101    result.into()
102}
103
104// https://github.com/serde-rs/serde/issues/1425#issuecomment-439729881
105pub fn non_empty_str<'de, D: serde::Deserializer<'de>>(d: D) -> Result<Option<String>, D::Error> {
106    use serde::Deserialize;
107    let o: Option<String> = Option::deserialize(d)?;
108    Ok(o.filter(|s| !s.is_empty()))
109}