gio/subclass/
socket_control_message.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::{prelude::*, subclass::prelude::*, translate::*};
4
5use crate::{ffi, SocketControlMessage};
6
7pub trait SocketControlMessageImpl: ObjectImpl + SocketControlMessageImplExt {
8    /// Returns the "level" (i.e. the originating protocol) of the control message.
9    /// This is often SOL_SOCKET.
10    ///
11    /// # Returns
12    ///
13    /// an integer describing the level
14    fn level(&self) -> i32 {
15        self.parent_level()
16    }
17
18    fn msg_type(&self) -> i32 {
19        self.parent_msg_type()
20    }
21
22    /// Returns the space required for the control message, not including
23    /// headers or alignment.
24    ///
25    /// # Returns
26    ///
27    /// The number of bytes required.
28    fn size(&self) -> usize {
29        self.parent_size()
30    }
31
32    /// Converts the data in the message to bytes placed in the
33    /// message.
34    ///
35    /// @data is guaranteed to have enough space to fit the size
36    /// returned by g_socket_control_message_get_size() on this
37    /// object.
38    fn serialize(&self, data: &mut [u8]) {
39        self.parent_serialize(data);
40    }
41
42    fn deserialize(level: i32, type_: i32, data: &[u8]) -> Option<SocketControlMessage> {
43        Self::parent_deserialize(level, type_, data)
44    }
45}
46
47mod sealed {
48    pub trait Sealed {}
49    impl<T: super::SocketControlMessageImplExt> Sealed for T {}
50}
51
52pub trait SocketControlMessageImplExt: sealed::Sealed + ObjectSubclass {
53    fn parent_level(&self) -> i32 {
54        unsafe {
55            let data = Self::type_data();
56            let parent_class = data.as_ref().parent_class() as *mut ffi::GSocketControlMessageClass;
57            let f = (*parent_class)
58                .get_level
59                .expect("No parent class implementation for \"level\"");
60
61            f(self
62                .obj()
63                .unsafe_cast_ref::<SocketControlMessage>()
64                .to_glib_none()
65                .0)
66        }
67    }
68
69    fn parent_msg_type(&self) -> i32 {
70        unsafe {
71            let data = Self::type_data();
72            let parent_class = data.as_ref().parent_class() as *mut ffi::GSocketControlMessageClass;
73            let f = (*parent_class)
74                .get_type
75                .expect("No parent class implementation for \"msg_type\"");
76
77            f(self
78                .obj()
79                .unsafe_cast_ref::<SocketControlMessage>()
80                .to_glib_none()
81                .0)
82        }
83    }
84
85    fn parent_size(&self) -> usize {
86        unsafe {
87            let data = Self::type_data();
88            let parent_class = data.as_ref().parent_class() as *mut ffi::GSocketControlMessageClass;
89            let f = (*parent_class)
90                .get_size
91                .expect("No parent class implementation for \"size\"");
92
93            f(self
94                .obj()
95                .unsafe_cast_ref::<SocketControlMessage>()
96                .to_glib_none()
97                .0)
98        }
99    }
100
101    fn parent_serialize(&self, data: &mut [u8]) {
102        unsafe {
103            let type_data = Self::type_data();
104            let parent_class =
105                type_data.as_ref().parent_class() as *mut ffi::GSocketControlMessageClass;
106            let f = (*parent_class)
107                .serialize
108                .expect("No parent class implementation for \"serialize\"");
109
110            f(
111                self.obj()
112                    .unsafe_cast_ref::<SocketControlMessage>()
113                    .to_glib_none()
114                    .0,
115                data.as_mut_ptr() as _,
116            )
117        }
118    }
119
120    fn parent_deserialize(level: i32, type_: i32, data: &[u8]) -> Option<SocketControlMessage> {
121        unsafe {
122            let type_data = Self::type_data();
123            let parent_class =
124                type_data.as_ref().parent_class() as *mut ffi::GSocketControlMessageClass;
125
126            (*parent_class).deserialize.map(|f| {
127                let message_ptr = f(level, type_, data.len(), data.as_ptr() as _);
128                from_glib_full(message_ptr)
129            })
130        }
131    }
132}
133
134impl<T: SocketControlMessageImpl> SocketControlMessageImplExt for T {}
135
136unsafe impl<T: SocketControlMessageImpl> IsSubclassable<T> for SocketControlMessage {
137    fn class_init(class: &mut ::glib::Class<Self>) {
138        Self::parent_class_init::<T>(class);
139
140        let klass = class.as_mut();
141        klass.get_level = Some(socket_control_message_get_level::<T>);
142        klass.get_type = Some(socket_control_message_get_type::<T>);
143        klass.get_size = Some(socket_control_message_get_size::<T>);
144        klass.serialize = Some(socket_control_message_serialize::<T>);
145        klass.deserialize = Some(socket_control_message_deserialize::<T>);
146    }
147}
148
149unsafe extern "C" fn socket_control_message_get_level<T: SocketControlMessageImpl>(
150    ptr: *mut ffi::GSocketControlMessage,
151) -> i32 {
152    let instance = &*(ptr as *mut T::Instance);
153    let imp = instance.imp();
154
155    imp.level()
156}
157
158unsafe extern "C" fn socket_control_message_get_type<T: SocketControlMessageImpl>(
159    ptr: *mut ffi::GSocketControlMessage,
160) -> i32 {
161    let instance = &*(ptr as *mut T::Instance);
162    let imp = instance.imp();
163
164    imp.msg_type()
165}
166
167unsafe extern "C" fn socket_control_message_get_size<T: SocketControlMessageImpl>(
168    ptr: *mut ffi::GSocketControlMessage,
169) -> usize {
170    let instance = &*(ptr as *mut T::Instance);
171    let imp = instance.imp();
172
173    imp.size()
174}
175
176unsafe extern "C" fn socket_control_message_serialize<T: SocketControlMessageImpl>(
177    ptr: *mut ffi::GSocketControlMessage,
178    data: glib::ffi::gpointer,
179) {
180    let instance = &*(ptr as *mut T::Instance);
181    let imp = instance.imp();
182
183    let data = std::slice::from_raw_parts_mut(data as *mut u8, imp.size());
184
185    imp.serialize(data);
186}
187
188unsafe extern "C" fn socket_control_message_deserialize<T: SocketControlMessageImpl>(
189    level: i32,
190    type_: i32,
191    size: usize,
192    data: glib::ffi::gpointer,
193) -> *mut ffi::GSocketControlMessage {
194    let data = std::slice::from_raw_parts(data as *mut u8, size);
195
196    T::deserialize(level, type_, data).into_glib_ptr()
197}
198
199#[cfg(test)]
200mod tests {
201    use super::*;
202    use crate::prelude::*;
203    use std::cell::Cell;
204    use std::mem::size_of;
205
206    mod imp {
207        use super::*;
208
209        #[derive(Default)]
210        pub struct TestSocketControlMessage(pub Cell<u64>);
211
212        #[glib::object_subclass]
213        impl ObjectSubclass for TestSocketControlMessage {
214            const NAME: &'static str = "TestSocketControlMessage";
215            type Type = super::TestSocketControlMessage;
216            type ParentType = SocketControlMessage;
217        }
218
219        impl ObjectImpl for TestSocketControlMessage {}
220
221        impl SocketControlMessageImpl for TestSocketControlMessage {
222            fn level(&self) -> i32 {
223                i32::MAX
224            }
225
226            fn msg_type(&self) -> i32 {
227                i32::MAX
228            }
229
230            fn size(&self) -> usize {
231                size_of::<u64>()
232            }
233
234            fn serialize(&self, data: &mut [u8]) {
235                data.copy_from_slice(&self.0.get().to_ne_bytes());
236            }
237
238            fn deserialize(level: i32, type_: i32, data: &[u8]) -> Option<SocketControlMessage> {
239                if level == i32::MAX && type_ == i32::MAX {
240                    let obj = glib::Object::new::<super::TestSocketControlMessage>();
241                    obj.imp().0.set(u64::from_ne_bytes(data.try_into().ok()?));
242                    Some(obj.into())
243                } else {
244                    None
245                }
246            }
247        }
248    }
249
250    glib::wrapper! {
251        pub struct TestSocketControlMessage(ObjectSubclass<imp::TestSocketControlMessage>)
252            @extends SocketControlMessage;
253    }
254
255    #[test]
256    fn test_socket_control_message_subclassing() {
257        let obj = glib::Object::new::<TestSocketControlMessage>();
258
259        assert_eq!(obj.level(), i32::MAX);
260        assert_eq!(obj.msg_type(), i32::MAX);
261        assert_eq!(obj.size(), size_of::<u64>());
262
263        obj.imp().0.set(0x12345678abcdefu64);
264
265        let mut data = [0; size_of::<u64>()];
266        obj.serialize(&mut data);
267
268        let de = SocketControlMessage::deserialize(i32::MAX, i32::MAX, &data)
269            .expect("deserialize failed");
270        let de = de
271            .downcast::<TestSocketControlMessage>()
272            .expect("downcast failed");
273        assert_eq!(de.imp().0.get(), 0x12345678abcdefu64);
274    }
275}