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