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