zvariant/
signature_parser.rs
1use std::ops::{Bound, RangeBounds};
2
3use crate::{subslice, Basic, ObjectPath, Result, Signature, STRUCT_SIG_END_CHAR};
4
5#[cfg(unix)]
6use crate::Fd;
7
8#[cfg(feature = "gvariant")]
9use crate::utils::MAYBE_SIGNATURE_CHAR;
10use crate::utils::{
11 ARRAY_SIGNATURE_CHAR, DICT_ENTRY_SIG_END_CHAR, DICT_ENTRY_SIG_START_CHAR,
12 STRUCT_SIG_START_CHAR, VARIANT_SIGNATURE_CHAR,
13};
14
15#[derive(Debug, Clone)]
16pub(crate) struct SignatureParser<'s> {
17 signature: Signature<'s>,
18 pos: usize,
19 end: usize,
20}
21
22impl<'s> SignatureParser<'s> {
23 pub fn new(signature: Signature<'s>) -> Self {
24 let end = signature.len();
25
26 Self {
27 signature,
28 pos: 0,
29 end,
30 }
31 }
32
33 pub(crate) unsafe fn from_bytes_unchecked(signature: &'s [u8]) -> Result<Self> {
34 if signature.len() > 255 {
35 return Err(serde::de::Error::invalid_length(
36 signature.len(),
37 &"<= 255 characters",
38 ));
39 }
40
41 let signature = Signature::from_bytes_unchecked(signature);
42 Ok(Self::new(signature))
43 }
44
45 pub fn validate(signature: &'s [u8]) -> Result<()> {
46 for s in unsafe { Self::from_bytes_unchecked(signature)? } {
48 s?;
49 }
50 Ok(())
51 }
52
53 pub fn signature(&self) -> Signature<'_> {
54 self.signature.slice(self.pos..self.end)
55 }
56
57 pub fn next_char(&self) -> Result<char> {
58 subslice(self.signature.as_bytes(), self.pos).map(|b| *b as char)
59 }
60
61 #[inline]
62 pub fn skip_char(&mut self) -> Result<()> {
63 self.skip_chars(1)
64 }
65
66 pub fn skip_chars(&mut self, num_chars: usize) -> Result<()> {
67 self.pos += num_chars;
68
69 if self.pos > self.end {
71 return Err(serde::de::Error::invalid_length(
72 self.signature.len(),
73 &format!(">= {} characters", self.pos).as_str(),
74 ));
75 }
76
77 Ok(())
78 }
79
80 #[inline]
81 pub fn len(&self) -> usize {
82 self.end - self.pos
83 }
84
85 #[inline]
86 pub fn done(&self) -> bool {
87 self.pos == self.end
88 }
89
90 pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
96 let len = self.len();
97
98 let pos = match range.start_bound() {
99 Bound::Included(&n) => n,
100 Bound::Excluded(&n) => n + 1,
101 Bound::Unbounded => 0,
102 };
103
104 let end = match range.end_bound() {
105 Bound::Included(&n) => n + 1,
106 Bound::Excluded(&n) => n,
107 Bound::Unbounded => len,
108 };
109
110 assert!(
111 pos <= end,
112 "range start must not be greater than end: {:?} > {:?}",
113 pos,
114 end,
115 );
116 assert!(end <= len, "range end out of bounds: {:?} > {:?}", end, len,);
117
118 let mut clone = self.clone();
119 clone.pos += pos;
120 clone.end = self.pos + end;
121
122 clone
123 }
124
125 pub fn parse_next_signature(&mut self) -> Result<Signature<'s>> {
127 let len = &self.next_signature()?.len();
128 let pos = self.pos;
129 self.pos += len;
130
131 if self.pos > self.end {
133 return Err(serde::de::Error::invalid_length(
134 self.signature.len(),
135 &format!(">= {} characters", self.pos).as_str(),
136 ));
137 }
138
139 Ok(self.signature.slice(pos..self.pos))
140 }
141
142 pub fn next_signature(&self) -> Result<Signature<'_>> {
144 match self
145 .signature()
146 .as_bytes()
147 .first()
148 .map(|b| *b as char)
149 .ok_or_else(|| -> crate::Error {
150 serde::de::Error::invalid_length(0, &">= 1 character")
151 })? {
152 u8::SIGNATURE_CHAR
153 | bool::SIGNATURE_CHAR
154 | i16::SIGNATURE_CHAR
155 | u16::SIGNATURE_CHAR
156 | i32::SIGNATURE_CHAR
157 | u32::SIGNATURE_CHAR
158 | i64::SIGNATURE_CHAR
159 | u64::SIGNATURE_CHAR
160 | f64::SIGNATURE_CHAR
161 | <&str>::SIGNATURE_CHAR
162 | ObjectPath::SIGNATURE_CHAR
163 | Signature::SIGNATURE_CHAR
164 | VARIANT_SIGNATURE_CHAR => Ok(self.signature_slice(0, 1)),
165 #[cfg(unix)]
166 Fd::SIGNATURE_CHAR => Ok(self.signature_slice(0, 1)),
167 ARRAY_SIGNATURE_CHAR => self.next_array_signature(),
168 STRUCT_SIG_START_CHAR => self.next_structure_signature(),
169 DICT_ENTRY_SIG_START_CHAR => self.next_dict_entry_signature(),
170 #[cfg(feature = "gvariant")]
171 MAYBE_SIGNATURE_CHAR => self.next_maybe_signature(),
172 c => Err(serde::de::Error::invalid_value(
173 serde::de::Unexpected::Char(c),
174 &"a valid signature character",
175 )),
176 }
177 }
178
179 fn next_single_child_type_container_signature(
180 &self,
181 expected_sig_prefix: char,
182 ) -> Result<Signature<'_>> {
183 let signature = self.signature();
184
185 if signature.len() < 2 {
186 return Err(serde::de::Error::invalid_length(
187 signature.len(),
188 &">= 2 characters",
189 ));
190 }
191
192 let c = signature
194 .as_bytes()
195 .first()
196 .map(|b| *b as char)
197 .expect("empty signature");
198 if c != expected_sig_prefix {
199 return Err(serde::de::Error::invalid_value(
200 serde::de::Unexpected::Char(c),
201 &expected_sig_prefix.to_string().as_str(),
202 ));
203 }
204
205 let child_parser = self.slice(1..);
207 let child_len = child_parser.next_signature()?.len();
208
209 Ok(self.signature_slice(0, child_len + 1))
210 }
211
212 fn next_array_signature(&self) -> Result<Signature<'_>> {
213 self.next_single_child_type_container_signature(ARRAY_SIGNATURE_CHAR)
214 }
215
216 #[cfg(feature = "gvariant")]
217 fn next_maybe_signature(&self) -> Result<Signature<'_>> {
218 self.next_single_child_type_container_signature(MAYBE_SIGNATURE_CHAR)
219 }
220
221 fn next_structure_signature(&self) -> Result<Signature<'_>> {
222 let signature = self.signature();
223
224 if signature.len() < 3 {
225 return Err(serde::de::Error::invalid_length(
226 signature.len(),
227 &">= 2 characters",
228 ));
229 }
230
231 let mut bytes = signature.as_bytes().iter();
232 let c = bytes.next().map(|b| *b as char).expect("empty signature");
234 if c != STRUCT_SIG_START_CHAR {
235 return Err(serde::de::Error::invalid_value(
236 serde::de::Unexpected::Char(c),
237 &crate::STRUCT_SIG_START_STR,
238 ));
239 }
240 if bytes.next().map(|b| *b as char).expect("empty signature") == STRUCT_SIG_END_CHAR {
241 return Err(serde::de::Error::invalid_value(
242 serde::de::Unexpected::Str("()"),
243 &"at least one field signature between `(` and `)`",
244 ));
245 }
246
247 let mut fields_sig_len = 0;
248 let mut fields_parser = self.slice(1..);
249 while !fields_parser.done() && fields_parser.next_char()? != STRUCT_SIG_END_CHAR {
250 fields_sig_len += fields_parser.parse_next_signature()?.len();
251 }
252 let c = fields_parser.next_char()?;
253 if c != STRUCT_SIG_END_CHAR {
254 return Err(serde::de::Error::invalid_value(
255 serde::de::Unexpected::Char(c),
256 &crate::STRUCT_SIG_END_STR,
257 ));
258 }
259
260 Ok(self.signature_slice(0, fields_sig_len + 2))
262 }
263
264 fn next_dict_entry_signature(&self) -> Result<Signature<'_>> {
265 let signature = self.signature();
266
267 if signature.len() < 4 {
268 return Err(serde::de::Error::invalid_length(
269 signature.len(),
270 &">= 4 characters",
271 ));
272 }
273
274 let bytes = signature.as_bytes();
276 let c = bytes.first().map(|b| *b as char).expect("empty signature");
277 if c != DICT_ENTRY_SIG_START_CHAR {
278 return Err(serde::de::Error::invalid_value(
279 serde::de::Unexpected::Char(c),
280 &crate::DICT_ENTRY_SIG_START_STR,
281 ));
282 }
283
284 let key_parser = self.slice(1..);
285 let key_signature = key_parser.next_signature()?;
286 if key_signature.len() != 1 {
288 return Err(serde::de::Error::invalid_length(
289 key_signature.len(),
290 &"dict-entry key's signature can only be a single character",
291 ));
292 }
293
294 let value_parser = self.slice(2..);
296 let value_len = value_parser.next_signature()?.len();
297 let end = value_len + 3;
299
300 if signature.len() < end {
301 return Err(serde::de::Error::invalid_length(
302 signature.len(),
303 &format!(">= {end} characters").as_str(),
304 ));
305 }
306 if bytes[end - 1] as char != DICT_ENTRY_SIG_END_CHAR {
307 return Err(serde::de::Error::invalid_value(
308 serde::de::Unexpected::Char(c),
309 &crate::DICT_ENTRY_SIG_END_STR,
310 ));
311 }
312
313 Ok(self.signature_slice(0, end))
314 }
315
316 fn signature_slice(&self, idx: usize, end: usize) -> Signature<'_> {
317 self.signature.slice(self.pos + idx..self.pos + end)
318 }
319}
320
321impl<'a> Iterator for SignatureParser<'a> {
322 type Item = Result<Signature<'a>>;
323
324 fn next(&mut self) -> Option<Self::Item> {
325 if self.done() {
326 None
327 } else {
328 Some(self.parse_next_signature())
329 }
330 }
331}