arsc/parser/
read_util.rs

1use paste::paste;
2use std::io::{Read, Result, Seek, SeekFrom};
3
4macro_rules! read_num {
5    ($num_type: ty) => {
6        paste! {
7        pub fn [<read_ $num_type>]<R: Read>(reader: &mut R) -> Result<$num_type> {
8            let mut bytes = [0_u8; std::mem::size_of::<$num_type>()];
9            reader.read_exact(&mut bytes)?;
10            Ok(<$num_type>::from_le_bytes(bytes))
11        }
12        }
13    };
14}
15
16read_num!(u8);
17read_num!(u16);
18read_num!(u32);
19
20/// read 0-terminated string as utf16 encoding
21/// ## Warning:
22/// This function always reads `SIZE * 2` bytes
23pub fn read_string_utf16<const SIZE: usize, R: Read + Seek>(reader: &mut R) -> Result<String> {
24    let end = reader.stream_position()? + SIZE as u64 * 2;
25    let bytes = std::iter::repeat_with(|| read_u16(reader))
26        .take(SIZE)
27        .take_while(|byte| byte.as_ref().ok() != Some(&0))
28        .collect::<Result<Vec<_>>>()?;
29    let string = String::from_utf16(&bytes).expect("Not Uft-16");
30    reader.seek(SeekFrom::Start(end))?;
31    Ok(string)
32}