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#[derive(Debug, Copy, Clone, PartialEq, Eq)]
284pub struct ExtensionInformation {
285 pub major_opcode: u8,
287 pub first_event: u8,
289 pub first_error: u8,
291}
292
293#[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}