xcb_rust_protocol/
util.rs

1use alloc::vec::Vec;
2
3use crate::proto::request_name;
4use crate::Error;
5
6pub trait VariableLengthFromBytes: Sized {
7    fn from_bytes(bytes: &[u8]) -> crate::Result<(Self, usize)>;
8}
9
10pub trait VariableLengthSerialize {
11    fn serialize_into(self, buf: &mut [u8]) -> crate::Result<usize>;
12}
13
14pub trait FixedLengthFromBytes<const N: usize>: Sized {
15    fn from_bytes(bytes: &[u8]) -> crate::Result<Self>;
16}
17
18impl<const N: usize> FixedLengthFromBytes<N> for [u8; N] {
19    #[inline]
20    fn from_bytes(bytes: &[u8]) -> crate::Result<Self> {
21        unsafe {
22            Ok(bytes
23                .get(..N)
24                .ok_or(Error::FromBytes)?
25                .try_into()
26                .unwrap_unchecked())
27        }
28    }
29}
30
31pub trait FixedLengthSerialize<const N: usize> {
32    fn serialize_fixed(self) -> [u8; N];
33}
34
35impl<const N: usize> FixedLengthSerialize<N> for [u8; N] {
36    #[inline]
37    fn serialize_fixed(self) -> [u8; N] {
38        self
39    }
40}
41
42impl<const N: usize, FLS> FixedLengthSerialize<N> for &FLS
43where
44    FLS: FixedLengthSerialize<N> + Copy,
45{
46    #[inline]
47    fn serialize_fixed(self) -> [u8; N] {
48        (*self).serialize_fixed()
49    }
50}
51
52#[inline]
53pub fn u8_vec_from_bytes(bytes: &[u8], count: usize) -> crate::Result<Vec<u8>> {
54    Ok(bytes.get(..count).ok_or(Error::FromBytes)?.to_vec())
55}
56
57#[macro_export]
58macro_rules! vec_from_bytes_fixed {
59    ($buf: expr, $entity: ty, $count: expr, $size: expr) => {
60        {
61            let mut __v = alloc::vec::Vec::with_capacity($count);
62            for i in 0..$count {
63                __v.push(<$entity>::from_bytes($buf.get(i * $size..).ok_or($crate::error::Error::FromBytes)?)?);
64            }
65            __v
66        }
67    };
68    ($buf: expr, $entity: ty, $count: expr, $size: expr, $($arg: expr)*) => {
69        {
70            let mut __v = alloc::vec::Vec::with_capacity($count);
71            for i in 0..$count {
72                __v.push(<$entity>::from_bytes($buf.get(i * $size..).ok_or($crate::error::Error::FromBytes)?,
73                    $($arg,)*
74                )?);
75            }
76            __v
77        }
78    };
79}
80
81#[inline]
82pub fn u8_vec_serialize_into(buf: &mut [u8], bytes: &[u8]) -> crate::Result<()> {
83    buf.get_mut(0..bytes.len())
84        .ok_or(Error::Serialize)?
85        .copy_from_slice(bytes);
86    Ok(())
87}
88
89#[inline]
90pub fn fixed_vec_serialize_into<const N: usize, FLS: FixedLengthSerialize<N>>(
91    buf: &mut [u8],
92    items: impl IntoIterator<Item = FLS>,
93) -> crate::Result<()> {
94    for (i, item) in items.into_iter().enumerate() {
95        buf.get_mut(i * N..i * N + N)
96            .ok_or(Error::Serialize)?
97            .copy_from_slice(&item.serialize_fixed());
98    }
99    Ok(())
100}
101
102#[macro_export]
103macro_rules! vec_from_bytes_var {
104    ($buf: expr, $entity: ty, $offset: expr, $count: expr) => {
105        {
106            let mut __v = alloc::vec::Vec::with_capacity($count);
107            for _ in 0..$count {
108                let (item, __new_offset) = <$entity>::from_bytes($buf.get($offset..).ok_or($crate::error::Error::FromBytes)?)?;
109                $offset += __new_offset;
110                __v.push(item);
111            }
112            (__v)
113        }
114    };
115    ($buf: expr, $entity: ty, $offset: expr, $count: expr, $($arg: expr)*) => {
116        {
117            let mut __v = alloc::vec::Vec::with_capacity($count);
118            for _ in 0..$count {
119                let (item, __new_offset) = <$entity>::from_bytes($buf.get($offset..).ok_or($crate::error::Error::FromBytes)?,
120                    $($arg,)*
121                )?;
122                $offset += __new_offset;
123                __v.push(item);
124            }
125            __v
126        }
127    };
128}
129
130#[inline]
131pub fn var_vec_serialize_into<VLS: VariableLengthSerialize>(
132    buf: &mut [u8],
133    items: impl IntoIterator<Item = VLS>,
134) -> crate::Result<usize> {
135    let mut offset = 0;
136    for item in items {
137        offset += item.serialize_into(buf.get_mut(offset..).ok_or(crate::Error::Serialize)?)?;
138    }
139    Ok(offset)
140}
141
142impl FixedLengthSerialize<0> for () {
143    fn serialize_fixed(self) -> [u8; 0] {
144        []
145    }
146}
147
148impl FixedLengthFromBytes<0> for () {
149    fn from_bytes(_: &[u8]) -> crate::Result<Self> {
150        Ok(())
151    }
152}
153
154macro_rules! implement_num_serde {
155    ($num_type: ty, $byte_size: expr) => {
156        impl FixedLengthSerialize<$byte_size> for $num_type {
157            #[inline]
158            fn serialize_fixed(self) -> [u8; $byte_size] {
159                self.to_ne_bytes()
160            }
161        }
162        impl FixedLengthFromBytes<$byte_size> for $num_type {
163            #[inline]
164            fn from_bytes(bytes: &[u8]) -> $crate::Result<Self> {
165                #[cfg(feature = "debug")]
166                let byte_buf = bytes
167                    .get(..$byte_size)
168                    .ok_or_else(|| crate::Error::FromBytes)?;
169                #[cfg(not(feature = "debug"))]
170                let byte_buf = bytes.get(..$byte_size).ok_or(crate::Error::FromBytes)?;
171                Ok(Self::from_ne_bytes(
172                    bytes
173                        .get(..$byte_size)
174                        .ok_or(crate::Error::FromBytes)?
175                        .try_into()
176                        .unwrap(),
177                ))
178            }
179        }
180    };
181}
182
183implement_num_serde!(u8, 1);
184implement_num_serde!(u16, 2);
185implement_num_serde!(u32, 4);
186implement_num_serde!(u64, 8);
187implement_num_serde!(i8, 1);
188implement_num_serde!(i16, 2);
189implement_num_serde!(i32, 4);
190implement_num_serde!(i64, 8);
191
192implement_num_serde!(f32, 4);
193implement_num_serde!(f64, 8);
194
195#[macro_export]
196macro_rules! implement_bit_ops {
197    ($kind: ty) => {
198        impl core::ops::BitAnd for $kind {
199            type Output = Self;
200
201            #[inline]
202            fn bitand(self, rhs: Self) -> Self::Output {
203                Self(self.0 & rhs.0)
204            }
205        }
206
207        impl core::ops::BitOr for $kind {
208            type Output = Self;
209
210            #[inline]
211            fn bitor(self, rhs: Self) -> Self::Output {
212                Self(self.0 | rhs.0)
213            }
214        }
215
216        impl core::ops::BitAndAssign for $kind {
217            #[inline]
218            fn bitand_assign(&mut self, rhs: Self) {
219                self.0 &= rhs.0;
220            }
221        }
222
223        impl core::ops::BitOrAssign for $kind {
224            #[inline]
225            fn bitor_assign(&mut self, rhs: Self) {
226                self.0 |= rhs.0
227            }
228        }
229    };
230}
231
232pub trait XcbErrorHandler {
233    fn parse_error(&mut self) -> crate::Result<XcbError>;
234}
235
236pub fn parse_error<E>(buf: &[u8], ext: &E) -> crate::Result<XcbError>
237where
238    E: ExtensionInfoProvider,
239{
240    let opcode = *buf.get(1).ok_or(Error::FromBytes)?;
241    let sequence = u16::from_ne_bytes(buf.get(2..4).ok_or(Error::FromBytes)?.try_into()?);
242    let bad_value = u32::from_ne_bytes(buf.get(4..8).ok_or(Error::FromBytes)?.try_into()?);
243    let minor_opcode = u16::from_ne_bytes(buf.get(8..10).ok_or(Error::FromBytes)?.try_into()?);
244    let major_opcode = *buf.get(10).ok_or(Error::FromBytes)?;
245    let ext_name = ext.get_from_major_opcode(major_opcode).map(|e| e.0);
246    let err = XcbError {
247        opcode,
248        sequence,
249        bad_value,
250        minor_opcode,
251        major_opcode,
252        extension_name: ext_name,
253        request_name: request_name(ext_name, major_opcode, minor_opcode),
254    };
255    Ok(err)
256}
257
258#[derive(Debug, Copy, Clone)]
259pub struct XcbError {
260    pub opcode: u8,
261    pub sequence: u16,
262    pub bad_value: u32,
263    pub minor_opcode: u16,
264    pub major_opcode: u8,
265    pub extension_name: Option<&'static str>,
266    pub request_name: Option<&'static str>,
267}
268
269pub trait ExtensionInfoProvider {
270    fn get_by_name(&self, name: &str) -> Option<ExtensionInformation>;
271
272    fn get_from_major_opcode(
273        &self,
274        major_opcode: u8,
275    ) -> Option<(&'static str, ExtensionInformation)>;
276
277    fn get_from_event_code(&self, event_code: u8) -> Option<(&'static str, ExtensionInformation)>;
278
279    fn get_from_error_code(&self, error_code: u8) -> Option<(&'static str, ExtensionInformation)>;
280}
281
282/// Information about a X11 extension.
283#[derive(Debug, Copy, Clone, PartialEq, Eq)]
284pub struct ExtensionInformation {
285    /// Major opcode used in request
286    pub major_opcode: u8,
287    /// Lowest event number used by the extension.
288    pub first_event: u8,
289    /// Lowest error number used by the extension.
290    pub first_error: u8,
291}
292
293/// Get the response type out of the raw bytes of an X11 error or event.
294#[inline]
295pub fn response_type(raw_bytes: &[u8]) -> Result<u8, Error> {
296    raw_bytes.first().map(|x| x & 0x7f).ok_or(Error::FromBytes)
297}
298
299pub struct Iter32<'a> {
300    ind: usize,
301    inner: &'a [u8],
302}
303
304impl<'a> Iterator for Iter32<'a> {
305    type Item = u32;
306
307    fn next(&mut self) -> Option<Self::Item> {
308        let target = self.ind * 4;
309        self.inner.get(target..target + 4).map(|buf| {
310            self.ind += 1;
311            unsafe { u32::from_ne_bytes(buf.try_into().unwrap_unchecked()) }
312        })
313    }
314}
315
316pub trait AsIter32 {
317    fn as_iter_32(&self) -> Iter32;
318}
319
320impl<const N: usize> AsIter32 for [u8; N] {
321    fn as_iter_32(&self) -> Iter32 {
322        Iter32 {
323            ind: 0,
324            inner: self,
325        }
326    }
327}
328
329impl<'a> AsIter32 for &'a [u8] {
330    fn as_iter_32(&self) -> Iter32 {
331        Iter32 {
332            ind: 0,
333            inner: self,
334        }
335    }
336}