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