1 | //! Utility functions for X11 things. |
2 | //! |
3 | //! The most important definitions in this module are the [`TryParse`], [`TryParseFd`] and |
4 | //! [`Serialize`] traits. These traits are used internally for parsing incoming data and producing |
5 | //! outgoing data when talking with the X11 server. |
6 | |
7 | use core::convert::TryInto; |
8 | |
9 | use alloc::string::String; |
10 | use alloc::vec::Vec; |
11 | |
12 | use crate::errors::ParseError; |
13 | use crate::protocol::{request_name, ErrorKind}; |
14 | use crate::utils::RawFdContainer; |
15 | use crate::BufWithFds; |
16 | |
17 | /// Representation of an X11 error packet that was sent by the server. |
18 | #[derive (Debug, Clone, PartialEq, Eq)] |
19 | pub struct X11Error { |
20 | /// The kind of error that occurred. |
21 | pub error_kind: ErrorKind, |
22 | /// The kind of error that occurred as it appears "on the wire". |
23 | pub error_code: u8, |
24 | /// The sequence number of the request that caused this error. |
25 | pub sequence: u16, |
26 | /// The value in the request that caused the error. |
27 | pub bad_value: u32, |
28 | /// The minor opcode of the request that caused this error. |
29 | pub minor_opcode: u16, |
30 | /// The major opcode of the request that caused this error. |
31 | pub major_opcode: u8, |
32 | /// Name of the extension that caused this error, if known. |
33 | pub extension_name: Option<String>, |
34 | /// Name of the request that caused this error, if known. |
35 | pub request_name: Option<&'static str>, |
36 | } |
37 | |
38 | impl X11Error { |
39 | /// Parse an X11 error. |
40 | pub fn try_parse( |
41 | data: &[u8], |
42 | ext_info_provider: &dyn ExtInfoProvider, |
43 | ) -> Result<Self, ParseError> { |
44 | let (response_type, remaining) = u8::try_parse(data)?; |
45 | let (error_code, remaining) = u8::try_parse(remaining)?; |
46 | let (sequence, remaining) = u16::try_parse(remaining)?; |
47 | let (bad_value, remaining) = u32::try_parse(remaining)?; |
48 | let (minor_opcode, remaining) = u16::try_parse(remaining)?; |
49 | let (major_opcode, _) = u8::try_parse(remaining)?; |
50 | if response_type != 0 { |
51 | Err(ParseError::InvalidValue) |
52 | } else { |
53 | let error_kind = ErrorKind::from_wire_error_code(error_code, ext_info_provider); |
54 | let (extension_name, request_name) = |
55 | request_name(ext_info_provider, major_opcode, minor_opcode); |
56 | Ok(X11Error { |
57 | error_kind, |
58 | error_code, |
59 | sequence, |
60 | bad_value, |
61 | minor_opcode, |
62 | major_opcode, |
63 | extension_name, |
64 | request_name, |
65 | }) |
66 | } |
67 | } |
68 | } |
69 | |
70 | #[cfg (test)] |
71 | mod tryparse_x11error_test { |
72 | use super::{ErrorKind, ExtInfoProvider, ParseError, X11Error}; |
73 | use crate::x11_utils::ExtensionInformation; |
74 | |
75 | struct Provider; |
76 | |
77 | impl ExtInfoProvider for Provider { |
78 | fn get_from_major_opcode(&self, major_opcode: u8) -> Option<(&str, ExtensionInformation)> { |
79 | assert_eq!(major_opcode, 10); |
80 | None |
81 | } |
82 | fn get_from_event_code(&self, _event_code: u8) -> Option<(&str, ExtensionInformation)> { |
83 | unimplemented!() |
84 | } |
85 | fn get_from_error_code(&self, _error_code: u8) -> Option<(&str, ExtensionInformation)> { |
86 | unimplemented!() |
87 | } |
88 | } |
89 | |
90 | #[test ] |
91 | fn try_parse_error() { |
92 | let input = [ |
93 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
94 | 0, 0, 0, |
95 | ]; |
96 | let error = X11Error::try_parse(&input, &Provider); |
97 | let expected = X11Error { |
98 | error_kind: ErrorKind::Request, |
99 | error_code: 1, |
100 | sequence: u16::from_ne_bytes([2, 3]), |
101 | bad_value: u32::from_ne_bytes([4, 5, 6, 7]), |
102 | minor_opcode: u16::from_ne_bytes([8, 9]), |
103 | major_opcode: 10, |
104 | extension_name: None, |
105 | request_name: Some("UnmapWindow" ), |
106 | }; |
107 | assert_eq!(error, Ok(expected)); |
108 | } |
109 | |
110 | #[test ] |
111 | fn reject_invalid_response_type() { |
112 | let result = X11Error::try_parse(&[1; 32], &Provider); |
113 | assert_eq!(Err(ParseError::InvalidValue), result); |
114 | } |
115 | } |
116 | |
117 | impl From<&X11Error> for [u8; 32] { |
118 | fn from(input: &X11Error) -> Self { |
119 | let sequence_bytes = input.sequence.serialize(); |
120 | let bad_value_bytes = input.bad_value.serialize(); |
121 | let minor_opcode_bytes = input.minor_opcode.serialize(); |
122 | [ |
123 | 0, |
124 | input.error_code, |
125 | sequence_bytes[0], |
126 | sequence_bytes[1], |
127 | bad_value_bytes[0], |
128 | bad_value_bytes[1], |
129 | bad_value_bytes[2], |
130 | bad_value_bytes[3], |
131 | minor_opcode_bytes[0], |
132 | minor_opcode_bytes[1], |
133 | input.major_opcode, |
134 | 0, |
135 | 0, |
136 | 0, |
137 | 0, |
138 | 0, |
139 | 0, |
140 | 0, |
141 | 0, |
142 | 0, |
143 | 0, |
144 | 0, |
145 | 0, |
146 | 0, |
147 | 0, |
148 | 0, |
149 | 0, |
150 | 0, |
151 | 0, |
152 | 0, |
153 | 0, |
154 | 0, |
155 | ] |
156 | } |
157 | } |
158 | impl From<X11Error> for [u8; 32] { |
159 | fn from(input: X11Error) -> Self { |
160 | Self::from(&input) |
161 | } |
162 | } |
163 | |
164 | #[cfg (test)] |
165 | mod serialise_x11error_test { |
166 | use super::{ErrorKind, X11Error}; |
167 | |
168 | #[test ] |
169 | fn test_serialise() { |
170 | let error = X11Error { |
171 | error_kind: ErrorKind::Request, |
172 | error_code: 1, |
173 | sequence: u16::from_ne_bytes([2, 3]), |
174 | bad_value: u32::from_ne_bytes([4, 5, 6, 7]), |
175 | minor_opcode: u16::from_ne_bytes([8, 9]), |
176 | major_opcode: 10, |
177 | extension_name: None, |
178 | request_name: None, |
179 | }; |
180 | let expected = [ |
181 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
182 | 0, 0, 0, |
183 | ]; |
184 | assert_eq!(expected, <[u8; 32]>::from(error)); |
185 | } |
186 | } |
187 | |
188 | /// Information about a X11 extension. |
189 | #[derive (Debug, Copy, Clone, PartialEq, Eq)] |
190 | pub struct ExtensionInformation { |
191 | /// Major opcode used in request |
192 | pub major_opcode: u8, |
193 | /// Lowest event number used by the extension. |
194 | pub first_event: u8, |
195 | /// Lowest error number used by the extension. |
196 | pub first_error: u8, |
197 | } |
198 | |
199 | /// Trait to provide information about extensions. |
200 | pub trait ExtInfoProvider { |
201 | /// Returns the information of the extension that whose |
202 | /// opcode is `major_opcode`. |
203 | fn get_from_major_opcode(&self, major_opcode: u8) -> Option<(&str, ExtensionInformation)>; |
204 | |
205 | /// Returns the information of the extension that whose |
206 | /// event number range includes `event_number`. |
207 | fn get_from_event_code(&self, event_code: u8) -> Option<(&str, ExtensionInformation)>; |
208 | |
209 | /// Returns the information of the extension that whose |
210 | /// error number range includes `error_number`. |
211 | fn get_from_error_code(&self, error_code: u8) -> Option<(&str, ExtensionInformation)>; |
212 | } |
213 | |
214 | /// A type implementing this trait can be parsed from some raw bytes. |
215 | pub trait TryParse: Sized { |
216 | /// Try to parse the given values into an instance of this type. |
217 | /// |
218 | /// If parsing is successful, an instance of the type and a slice for the remaining data should |
219 | /// be returned. Otherwise, an error is returned. |
220 | fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError>; |
221 | } |
222 | |
223 | /// A type implementing this trait can be parsed from some raw bytes and a list of fds. |
224 | pub trait TryParseFd: Sized { |
225 | /// Try to parse the given values into an instance of this type. |
226 | /// |
227 | /// File descriptors are consumed by removing them from the beginning of the given `fds` `Vec`. |
228 | /// If a file descriptor is expected, but missing, a `ParseError` should be returned. If more file |
229 | /// descriptors are provided than expected, this is not an error and the remaining descriptors |
230 | /// should be left in the `Vec`. |
231 | /// |
232 | /// If parsing is successful, an instance of the type and a slice for the remaining data should |
233 | /// be returned. Otherwise, an error is returned. |
234 | fn try_parse_fd<'a>( |
235 | value: &'a [u8], |
236 | fds: &mut Vec<RawFdContainer>, |
237 | ) -> Result<(Self, &'a [u8]), ParseError>; |
238 | } |
239 | |
240 | impl<T: TryParse> TryParseFd for T { |
241 | fn try_parse_fd<'a>( |
242 | value: &'a [u8], |
243 | _: &mut Vec<RawFdContainer>, |
244 | ) -> Result<(Self, &'a [u8]), ParseError> { |
245 | T::try_parse(value) |
246 | } |
247 | } |
248 | |
249 | /// A representation of the header of a request. |
250 | #[derive (Debug, Clone, Copy)] |
251 | pub struct RequestHeader { |
252 | /// The major opcode of the request. |
253 | pub major_opcode: u8, |
254 | /// The minor opcode of the request (which, for some requests, may not be an |
255 | /// opcode at all). |
256 | pub minor_opcode: u8, |
257 | /// The remaining length of the request, measured in 4 bytes units. Unlike the wire format, |
258 | /// this does *not* include the header itself, which is 1 unit (or 2 if BigRequests is |
259 | /// enabled and the length in the first unit is zero). If the BigRequests extension is |
260 | /// enabled this can be greater than u16::max_value - 1. |
261 | pub remaining_length: u32, |
262 | } |
263 | |
264 | /// A type implementing this trait is an X11 request. |
265 | pub trait Request { |
266 | /// The protocol name of the extension that this request belongs to, or None for core requests |
267 | const EXTENSION_NAME: Option<&'static str>; |
268 | |
269 | /// Serialize this request into its X11 protocol wire representation. |
270 | /// |
271 | /// The argument is the major opcode of the extension that this request belongs to. For core |
272 | /// requests, the argument may not have any influence |
273 | fn serialize(self, extension_opcode: u8) -> BufWithFds<Vec<u8>>; |
274 | } |
275 | |
276 | /// A type alias for reply parsers (matches the signature of TryParseFd). |
277 | pub type ReplyParsingFunction = |
278 | for<'a> fn( |
279 | &'a [u8], |
280 | &mut Vec<RawFdContainer>, |
281 | ) -> Result<(crate::protocol::Reply, &'a [u8]), ParseError>; |
282 | |
283 | /// A X11 request that does not have a reply |
284 | pub trait VoidRequest: Request {} |
285 | |
286 | /// A X11 request that has a reply without FDs |
287 | pub trait ReplyRequest: Request { |
288 | /// The kind of reply that this request generates. |
289 | type Reply: Into<crate::protocol::Reply> + TryParse; |
290 | } |
291 | |
292 | /// A X11 request that has a reply with FDs |
293 | pub trait ReplyFDsRequest: Request { |
294 | /// The kind of reply that this request generates. |
295 | type Reply: Into<crate::protocol::Reply> + TryParseFd; |
296 | } |
297 | |
298 | /// A type implementing this trait can be serialized into X11 raw bytes. |
299 | pub trait Serialize { |
300 | /// The value returned by `serialize`. |
301 | /// |
302 | /// This should be `Vec<u8>` in most cases. However, arrays like `[u8; 4]` should also be |
303 | /// allowed and thus this is an associated type. |
304 | /// |
305 | /// If generic associated types were available, implementing `AsRef<[u8]>` would be required. |
306 | type Bytes; |
307 | |
308 | /// Serialize this value into X11 raw bytes. |
309 | fn serialize(&self) -> Self::Bytes; |
310 | |
311 | /// Serialize this value into X11 raw bytes, appending the result into `bytes`. |
312 | /// |
313 | /// When calling this method, the given vector must satisfy `assert_eq!(bytes.len() % 4, 0);`. |
314 | /// In words: Its length must be a multiple of four. |
315 | fn serialize_into(&self, bytes: &mut Vec<u8>); |
316 | } |
317 | |
318 | // Now implement TryParse and Serialize for some primitive data types that we need. |
319 | |
320 | macro_rules! implement_try_parse { |
321 | ($t:ty) => { |
322 | impl TryParse for $t { |
323 | fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> { |
324 | let len = core::mem::size_of::<$t>(); |
325 | let bytes = value |
326 | .get(..len) |
327 | .ok_or(ParseError::InsufficientData)? |
328 | .try_into() // TryInto<[u8; len]> |
329 | .unwrap(); |
330 | Ok((<$t>::from_ne_bytes(bytes), &value[len..])) |
331 | } |
332 | } |
333 | }; |
334 | } |
335 | |
336 | macro_rules! implement_serialize { |
337 | ($t:ty: $size:expr) => { |
338 | impl Serialize for $t { |
339 | type Bytes = [u8; $size]; |
340 | fn serialize(&self) -> Self::Bytes { |
341 | self.to_ne_bytes() |
342 | } |
343 | fn serialize_into(&self, bytes: &mut Vec<u8>) { |
344 | bytes.extend_from_slice(&self.to_ne_bytes()); |
345 | } |
346 | } |
347 | }; |
348 | } |
349 | |
350 | macro_rules! forward_float { |
351 | ($from:ty: $to:ty) => { |
352 | impl TryParse for $from { |
353 | fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> { |
354 | let (data, remaining) = <$to>::try_parse(value)?; |
355 | Ok((<$from>::from_bits(data), remaining)) |
356 | } |
357 | } |
358 | impl Serialize for $from { |
359 | type Bytes = <$to as Serialize>::Bytes; |
360 | fn serialize(&self) -> Self::Bytes { |
361 | self.to_bits().serialize() |
362 | } |
363 | fn serialize_into(&self, bytes: &mut Vec<u8>) { |
364 | self.to_bits().serialize_into(bytes); |
365 | } |
366 | } |
367 | }; |
368 | } |
369 | |
370 | implement_try_parse!(u8); |
371 | implement_try_parse!(i8); |
372 | implement_try_parse!(u16); |
373 | implement_try_parse!(i16); |
374 | implement_try_parse!(u32); |
375 | implement_try_parse!(i32); |
376 | implement_try_parse!(u64); |
377 | implement_try_parse!(i64); |
378 | |
379 | implement_serialize!(u8: 1); |
380 | implement_serialize!(i8: 1); |
381 | implement_serialize!(u16: 2); |
382 | implement_serialize!(i16: 2); |
383 | implement_serialize!(u32: 4); |
384 | implement_serialize!(i32: 4); |
385 | implement_serialize!(u64: 8); |
386 | implement_serialize!(i64: 8); |
387 | |
388 | forward_float!(f32: u32); |
389 | forward_float!(f64: u64); |
390 | |
391 | #[cfg (test)] |
392 | mod float_tests { |
393 | use super::{Serialize, TryParse}; |
394 | |
395 | fn test_round_trip<F>(value: F) |
396 | where |
397 | F: TryParse + Serialize + PartialEq + core::fmt::Debug + Copy, |
398 | <F as Serialize>::Bytes: AsRef<[u8]>, |
399 | { |
400 | let empty = &[][..]; |
401 | |
402 | // Test using serialize() |
403 | assert_eq!(Ok((value, empty)), F::try_parse(value.serialize().as_ref())); |
404 | |
405 | // Test using serialize_into() |
406 | let mut output = alloc::vec::Vec::new(); |
407 | value.serialize_into(&mut output); |
408 | assert_eq!(Ok((value, empty)), F::try_parse(&output)); |
409 | } |
410 | |
411 | #[test ] |
412 | fn test_f32_round_trips() { |
413 | for &f in &[0f32, 1., std::f32::consts::PI, 42., 1337., 1e7] { |
414 | test_round_trip(f); |
415 | test_round_trip(-f); |
416 | } |
417 | } |
418 | |
419 | #[test ] |
420 | fn test_f64_round_trips() { |
421 | for &f in &[0f64, 1., std::f64::consts::PI, 42., 1337., 1e7] { |
422 | test_round_trip(f); |
423 | test_round_trip(-f); |
424 | } |
425 | } |
426 | |
427 | #[test ] |
428 | fn test_parse_known_value() { |
429 | let bytes = 0x42280000u32.to_ne_bytes(); |
430 | let value = f32::try_parse(&bytes); |
431 | let empty = &[][..]; |
432 | assert_eq!(Ok((42., empty)), value); |
433 | } |
434 | |
435 | #[test ] |
436 | fn test_serialize_known_value() { |
437 | assert_eq!(0x42280000u32.to_ne_bytes(), 42f32.serialize()); |
438 | } |
439 | } |
440 | |
441 | impl TryParse for bool { |
442 | fn try_parse(value: &[u8]) -> Result<(Self, &[u8]), ParseError> { |
443 | let (data: u8, remaining: &[u8]) = u8::try_parse(value)?; |
444 | Ok((data != 0, remaining)) |
445 | } |
446 | } |
447 | |
448 | impl Serialize for bool { |
449 | type Bytes = [u8; 1]; |
450 | fn serialize(&self) -> Self::Bytes { |
451 | [u8::from(*self)] |
452 | } |
453 | fn serialize_into(&self, bytes: &mut Vec<u8>) { |
454 | bytes.push(u8::from(*self)); |
455 | } |
456 | } |
457 | |
458 | // Tuple handling |
459 | |
460 | macro_rules! tuple_try_parse { |
461 | ($($name:ident)*) => { |
462 | impl<$($name,)*> TryParse for ($($name,)*) |
463 | where $($name: TryParse,)* |
464 | { |
465 | #[allow(non_snake_case)] |
466 | fn try_parse(remaining: &[u8]) -> Result<(($($name,)*), &[u8]), ParseError> { |
467 | $(let ($name, remaining) = $name::try_parse(remaining)?;)* |
468 | Ok((($($name,)*), remaining)) |
469 | } |
470 | } |
471 | } |
472 | } |
473 | |
474 | macro_rules! tuple_serialize { |
475 | ($($name:ident:$idx:tt)*) => { |
476 | impl<$($name,)*> Serialize for ($($name,)*) |
477 | where $($name: Serialize,)* |
478 | { |
479 | type Bytes = Vec<u8>; |
480 | fn serialize(&self) -> Self::Bytes { |
481 | let mut result = Vec::new(); |
482 | self.serialize_into(&mut result); |
483 | result |
484 | } |
485 | fn serialize_into(&self, bytes: &mut Vec<u8>) { |
486 | $(self.$idx.serialize_into(bytes);)* |
487 | } |
488 | } |
489 | } |
490 | } |
491 | |
492 | macro_rules! tuple_impls { |
493 | ($($name:ident:$idx:tt)*) => { |
494 | tuple_try_parse!($($name)*); |
495 | tuple_serialize!($($name:$idx)*); |
496 | } |
497 | } |
498 | |
499 | // We can optimise serialisation of empty tuples or one-element-tuples with different Bytes type |
500 | impl Serialize for () { |
501 | type Bytes = [u8; 0]; |
502 | fn serialize(&self) -> Self::Bytes { |
503 | [] |
504 | } |
505 | fn serialize_into(&self, _bytes: &mut Vec<u8>) {} |
506 | } |
507 | |
508 | impl<T: Serialize> Serialize for (T,) { |
509 | type Bytes = T::Bytes; |
510 | fn serialize(&self) -> Self::Bytes { |
511 | self.0.serialize() |
512 | } |
513 | fn serialize_into(&self, bytes: &mut Vec<u8>) { |
514 | self.0.serialize_into(bytes) |
515 | } |
516 | } |
517 | |
518 | tuple_try_parse!(); |
519 | tuple_try_parse!(A); |
520 | tuple_impls!(A:0 B:1); |
521 | tuple_impls!(A:0 B:1 C:2); |
522 | tuple_impls!(A:0 B:1 C:2 D:3); |
523 | tuple_impls!(A:0 B:1 C:2 D:3 E:4); |
524 | tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5); |
525 | tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6); |
526 | tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7); |
527 | tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8); |
528 | tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9); |
529 | tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10); |
530 | tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10 L:11); |
531 | tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10 L:11 M:12); |
532 | tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10 L:11 M:12 N:13); |
533 | tuple_impls!(A:0 B:1 C:2 D:3 E:4 F:5 G:6 H:7 I:8 J:9 K:10 L:11 M:12 N:13 O:14); |
534 | |
535 | /// Parse a list of objects from the given data. |
536 | /// |
537 | /// This function parses a list of objects where the length of the list was specified externally. |
538 | /// The wire format for `list_length` instances of `T` will be read from the given data. |
539 | pub(crate) fn parse_list<T>(data: &[u8], list_length: usize) -> Result<(Vec<T>, &[u8]), ParseError> |
540 | where |
541 | T: TryParse, |
542 | { |
543 | let mut remaining: &[u8] = data; |
544 | let mut result: Vec = Vec::with_capacity(list_length); |
545 | for _ in 0..list_length { |
546 | let (entry: T, new_remaining: &[u8]) = T::try_parse(remaining)?; |
547 | result.push(entry); |
548 | remaining = new_remaining; |
549 | } |
550 | Ok((result, remaining)) |
551 | } |
552 | |
553 | /// Parse a list of `u8` from the given data. |
554 | #[inline ] |
555 | pub(crate) fn parse_u8_list(data: &[u8], list_length: usize) -> Result<(&[u8], &[u8]), ParseError> { |
556 | if data.len() < list_length { |
557 | Err(ParseError::InsufficientData) |
558 | } else { |
559 | Ok(data.split_at(mid:list_length)) |
560 | } |
561 | } |
562 | |
563 | /// Parse an array of `u8` from the given data. |
564 | #[inline ] |
565 | pub(crate) fn parse_u8_array_ref<const N: usize>( |
566 | data: &[u8], |
567 | ) -> Result<(&[u8; N], &[u8]), ParseError> { |
568 | let (slice: &[u8], remaining: &[u8]) = parse_u8_list(data, N)?; |
569 | let slice: &[u8; N] = slice |
570 | .try_into() |
571 | .expect(msg:"Cannot fail since slice has expected length" ); |
572 | Ok((slice, remaining)) |
573 | } |
574 | |
575 | /// Parse an array of `u8` from the given data. |
576 | #[inline ] |
577 | pub(crate) fn parse_u8_array<const N: usize>(data: &[u8]) -> Result<([u8; N], &[u8]), ParseError> { |
578 | let (array: &[u8; N], remaining: &[u8]) = parse_u8_array_ref(data)?; |
579 | Ok((*array, remaining)) |
580 | } |
581 | |
582 | impl<T: Serialize> Serialize for [T] { |
583 | type Bytes = Vec<u8>; |
584 | fn serialize(&self) -> Self::Bytes { |
585 | let mut result: Vec = Vec::new(); |
586 | self.serialize_into(&mut result); |
587 | result |
588 | } |
589 | fn serialize_into(&self, bytes: &mut Vec<u8>) { |
590 | for item: &T in self { |
591 | item.serialize_into(bytes); |
592 | } |
593 | } |
594 | } |
595 | |
596 | // This macro is used by the generated code to implement e.g. `std::ops::BitOr` and |
597 | // `std::ops::BitOrAssign`. |
598 | macro_rules! bitmask_binop { |
599 | ($t:ty, $u:ty) => { |
600 | impl core::ops::BitOr for $t { |
601 | type Output = $t; |
602 | fn bitor(self, other: Self) -> Self::Output { |
603 | Self::from(<$u>::from(self) | <$u>::from(other)) |
604 | } |
605 | } |
606 | impl core::ops::BitOr<$u> for $t { |
607 | type Output = $t; |
608 | fn bitor(self, other: $u) -> Self::Output { |
609 | self | Self::from(other) |
610 | } |
611 | } |
612 | impl core::ops::BitOr<$t> for $u { |
613 | type Output = $t; |
614 | fn bitor(self, other: $t) -> Self::Output { |
615 | <$t>::from(self) | other |
616 | } |
617 | } |
618 | impl core::ops::BitOrAssign for $t { |
619 | fn bitor_assign(&mut self, other: $t) { |
620 | *self = *self | Self::from(other) |
621 | } |
622 | } |
623 | impl core::ops::BitOrAssign<$t> for $u { |
624 | fn bitor_assign(&mut self, other: $t) { |
625 | *self |= Self::from(other) |
626 | } |
627 | } |
628 | impl core::ops::BitOrAssign<$u> for $t { |
629 | fn bitor_assign(&mut self, other: $u) { |
630 | self.0 |= other |
631 | } |
632 | } |
633 | impl core::ops::BitAnd for $t { |
634 | type Output = $t; |
635 | fn bitand(self, other: Self) -> Self::Output { |
636 | Self::from(<$u>::from(self) & <$u>::from(other)) |
637 | } |
638 | } |
639 | impl core::ops::BitAnd<$u> for $t { |
640 | type Output = $t; |
641 | fn bitand(self, other: $u) -> Self::Output { |
642 | self & Self::from(other) |
643 | } |
644 | } |
645 | impl core::ops::BitAnd<$t> for $u { |
646 | type Output = $t; |
647 | fn bitand(self, other: $t) -> Self::Output { |
648 | <$t>::from(self) & other |
649 | } |
650 | } |
651 | impl core::ops::BitAndAssign for $t { |
652 | fn bitand_assign(&mut self, other: $t) { |
653 | self.0 &= other |
654 | } |
655 | } |
656 | impl core::ops::BitAndAssign<$t> for $u { |
657 | fn bitand_assign(&mut self, other: $t) { |
658 | *self &= Self::from(other) |
659 | } |
660 | } |
661 | impl core::ops::BitAndAssign<$u> for $t { |
662 | fn bitand_assign(&mut self, other: $u) { |
663 | self.0 &= other |
664 | } |
665 | } |
666 | impl $t { |
667 | /// Check if this object has all bits set that are also set in `flag`. |
668 | /// |
669 | /// `flag` can be a single enum variant or a whole other mask. |
670 | pub fn contains(self, flag: impl Into<$u>) -> bool { |
671 | let flag = flag.into(); |
672 | (<$u>::from(self) & flag) == flag |
673 | } |
674 | |
675 | /// Check if this object has some bits set that are also set in `flag`. |
676 | /// |
677 | /// `flag` can be a single enum variant or a whole other mask. |
678 | pub fn intersects(self, flag: impl Into<$u>) -> bool { |
679 | let flag = flag.into(); |
680 | (<$u>::from(self) & flag) != 0 |
681 | } |
682 | } |
683 | }; |
684 | } |
685 | |
686 | /// Wrapper around TryInto that produces a ParseError. |
687 | /// |
688 | /// This trait shortens `x.try_into().or(Err(ParseError::ConversionFailed))` to `x.try_to_usize()`. |
689 | pub(crate) trait TryIntoUSize: TryInto<usize> { |
690 | /// Attempt the conversion |
691 | fn try_to_usize(self) -> Result<usize, ParseError> { |
692 | self.try_into().or(res:Err(ParseError::ConversionFailed)) |
693 | } |
694 | } |
695 | |
696 | impl TryIntoUSize for u8 {} |
697 | impl TryIntoUSize for u16 {} |
698 | impl TryIntoUSize for u32 {} |
699 | impl TryIntoUSize for u64 {} |
700 | impl TryIntoUSize for i8 {} |
701 | impl TryIntoUSize for i16 {} |
702 | impl TryIntoUSize for i32 {} |
703 | impl TryIntoUSize for i64 {} |
704 | |
705 | /// Has the BigRequests extension been enabled? |
706 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
707 | pub enum BigRequests { |
708 | /// The BigRequests extension has been enabled. |
709 | Enabled, |
710 | /// The BigRequests extension has not been enabled. |
711 | NotEnabled, |
712 | } |
713 | |
714 | /// Parse the given input for a RequestHeader and the remaining input. |
715 | pub fn parse_request_header( |
716 | input: &[u8], |
717 | big_requests_enabled: BigRequests, |
718 | ) -> Result<(RequestHeader, &[u8]), ParseError> { |
719 | let (major_opcode, remaining) = u8::try_parse(input)?; |
720 | let (minor_opcode, remaining) = u8::try_parse(remaining)?; |
721 | let (length, remaining) = u16::try_parse(remaining)?; |
722 | let (remaining_length, finally_remaining) = if length == 0 { |
723 | if big_requests_enabled == BigRequests::NotEnabled { |
724 | return Err(ParseError::InvalidValue); |
725 | } |
726 | |
727 | let (length, remaining) = u32::try_parse(remaining)?; |
728 | if length < 2 { |
729 | return Err(ParseError::InvalidValue); |
730 | } |
731 | // Adjust length for the size of this header (two 4 byte units). |
732 | (length - 2, remaining) |
733 | } else { |
734 | // Adjust length for the size of this header (one 4 byte unit). |
735 | (u32::from(length) - 1, remaining) |
736 | }; |
737 | Ok(( |
738 | RequestHeader { |
739 | major_opcode, |
740 | minor_opcode, |
741 | remaining_length, |
742 | }, |
743 | finally_remaining, |
744 | )) |
745 | } |
746 | |