1use nom::{
10 bytes::complete::take,
11 combinator::{flat_map, map_res},
12 number::complete::{le_i16, le_i32, le_u128, le_u16, le_u32, le_u8},
13};
14
15use super::errors::{ParseError, ParseResult};
16
17pub type Byte = u8;
18pub type Word = u16;
19pub type Short = i16;
20pub type Dword = u32;
21pub type Long = i32;
22pub type Float = f32;
23pub type Double = f64;
24pub type Qword = u64;
25pub type Long64 = i64;
26pub type Uuid = u128;
27
28#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
29pub struct Point {
30 pub x: Long,
31 pub y: Long,
32}
33
34#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
35pub struct Size {
36 pub width: Long,
37 pub height: Long,
38}
39
40#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
41pub struct Rect {
42 pub point: Point,
43 pub size: Size,
44}
45
46#[derive(Debug, Copy, Clone)]
47pub struct Fixed(pub u16, pub u16);
48
49#[derive(Debug, Copy, Clone)]
50pub struct RGB {
51 pub red: u8,
52 pub green: u8,
53 pub blue: u8,
54}
55
56#[derive(Debug, Copy, Clone, Default, PartialEq, Eq)]
57pub struct Color {
58 pub red: u8,
59 pub green: u8,
60 pub blue: u8,
61 pub alpha: u8,
62}
63
64#[inline]
65pub fn byte(input: &[u8]) -> ParseResult<'_, Byte> {
66 le_u8(input)
67}
68
69#[inline]
70pub fn word(input: &[u8]) -> ParseResult<'_, Word> {
71 le_u16(input)
72}
73
74#[inline]
75pub fn short(input: &[u8]) -> ParseResult<'_, Short> {
76 le_i16(input)
77}
78
79#[inline]
80pub fn dword(input: &[u8]) -> ParseResult<'_, Dword> {
81 le_u32(input)
82}
83
84#[inline]
85pub fn long(input: &[u8]) -> ParseResult<'_, Long> {
86 le_i32(input)
87}
88
89pub fn parse_point(input: &[u8]) -> ParseResult<'_, Point> {
90 let (input, x) = long(input)?;
91 let (input, y) = long(input)?;
92 Ok((input, Point { x, y }))
93}
94
95pub fn parse_size(input: &[u8]) -> ParseResult<'_, Size> {
96 let (input, width) = long(input)?;
97 let (input, height) = long(input)?;
98 Ok((input, Size { width, height }))
99}
100
101pub fn parse_rect(input: &[u8]) -> ParseResult<'_, Rect> {
102 let (input, point) = parse_point(input)?;
103 let (input, size) = parse_size(input)?;
104 Ok((input, Rect { point, size }))
105}
106
107pub fn dword_size<'a>(input: &'a [u8], f: fn(Dword) -> ParseError<'a>) -> ParseResult<'a, Dword> {
112 let (input, size) = dword(input)?;
113 if size >= 4 {
114 Ok((input, size))
115 } else {
116 Err(nom::Err::Failure(f(size)))
117 }
118}
119
120pub fn parse_dword_as_usize(input: &[u8]) -> ParseResult<'_, usize> {
121 let (input, size) = dword(input)?;
122 let size = size
123 .try_into()
124 .map_err(|_| nom::Err::Failure(ParseError::DwordToUsize(size)))?;
125 Ok((input, size))
126}
127
128pub fn parse_dword_as_u8<'a>(input: &'a [u8], e: ParseError<'a>) -> ParseResult<'a, u8> {
129 let (input, size) = dword(input)?;
130 let size = size.try_into().map_err(|_| nom::Err::Failure(e))?;
131 Ok((input, size))
132}
133
134pub fn parse_string(input: &[u8]) -> ParseResult<'_, &str> {
135 map_res(flat_map(word, take), std::str::from_utf8)(input)
136}
137
138pub fn parse_uuid(input: &[u8]) -> ParseResult<'_, Uuid> {
139 le_u128(input)
140}
141
142pub fn fixed(input: &[u8]) -> ParseResult<'_, Fixed> {
143 let (input, low) = le_u16(input)?;
144 let (input, high) = le_u16(input)?;
145 Ok((input, Fixed(high, low)))
146}
147
148pub fn parse_color(input: &[u8]) -> ParseResult<'_, Color> {
149 let (input, red) = byte(input)?;
150 let (input, green) = byte(input)?;
151 let (input, blue) = byte(input)?;
152 let (input, alpha) = byte(input)?;
153 Ok((
154 input,
155 Color {
156 red,
157 green,
158 blue,
159 alpha,
160 },
161 ))
162}
163
164pub fn parse_rgb(input: &[u8]) -> ParseResult<'_, RGB> {
165 let (input, red) = byte(input)?;
166 let (input, green) = byte(input)?;
167 let (input, blue) = byte(input)?;
168 Ok((input, RGB { red, green, blue }))
169}