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:
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    let instance = &*(ptr as *mut T::Instance);
150    let imp = instance.imp();
151
152    imp.level()
153}
154
155unsafe extern "C" fn socket_control_message_get_type<T: SocketControlMessageImpl>(
156    ptr: *mut ffi::GSocketControlMessage,
157) -> i32 {
158    let instance = &*(ptr as *mut T::Instance);
159    let imp = instance.imp();
160
161    imp.msg_type()
162}
163
164unsafe extern "C" fn socket_control_message_get_size<T: SocketControlMessageImpl>(
165    ptr: *mut ffi::GSocketControlMessage,
166) -> usize {
167    let instance = &*(ptr as *mut T::Instance);
168    let imp = instance.imp();
169
170    imp.size()
171}
172
173unsafe extern "C" fn socket_control_message_serialize<T: SocketControlMessageImpl>(
174    ptr: *mut ffi::GSocketControlMessage,
175    data: glib::ffi::gpointer,
176) {
177    let instance = &*(ptr as *mut T::Instance);
178    let imp = instance.imp();
179
180    let data = std::slice::from_raw_parts_mut(data as *mut u8, imp.size());
181
182    imp.serialize(data);
183}
184
185unsafe extern "C" fn socket_control_message_deserialize<T: SocketControlMessageImpl>(
186    level: i32,
187    type_: i32,
188    size: usize,
189    data: glib::ffi::gpointer,
190) -> *mut ffi::GSocketControlMessage {
191    let data = std::slice::from_raw_parts(data as *mut u8, size);
192
193    T::deserialize(level, type_, data).into_glib_ptr()
194}
195
196#[cfg(test)]
197mod tests {
198    use super::*;
199    use crate::prelude::*;
200    use std::cell::Cell;
201    use std::mem::size_of;
202
203    mod imp {
204        use super::*;
205
206        #[derive(Default)]
207        pub struct TestSocketControlMessage(pub Cell<u64>);
208
209        #[glib::object_subclass]
210        impl ObjectSubclass for TestSocketControlMessage {
211            const NAME: &'static str = "TestSocketControlMessage";
212            type Type = super::TestSocketControlMessage;
213            type ParentType = SocketControlMessage;
214        }
215
216        impl ObjectImpl for TestSocketControlMessage {}
217
218        impl SocketControlMessageImpl for TestSocketControlMessage {
219            fn level(&self) -> i32 {
220                i32::MAX
221            }
222
223            fn msg_type(&self) -> i32 {
224                i32::MAX
225            }
226
227            fn size(&self) -> usize {
228                size_of::<u64>()
229            }
230
231            fn serialize(&self, data: &mut [u8]) {
232                data.copy_from_slice(&self.0.get().to_ne_bytes());
233            }
234
235            fn deserialize(level: i32, type_: i32, data: &[u8]) -> Option<SocketControlMessage> {
236                if level == i32::MAX && type_ == i32::MAX {
237                    let obj = glib::Object::new::<super::TestSocketControlMessage>();
238                    obj.imp().0.set(u64::from_ne_bytes(data.try_into().ok()?));
239                    Some(obj.into())
240                } else {
241                    None
242                }
243            }
244        }
245    }
246
247    glib::wrapper! {
248        pub struct TestSocketControlMessage(ObjectSubclass<imp::TestSocketControlMessage>)
249            @extends SocketControlMessage;
250    }
251
252    #[test]
253    fn test_socket_control_message_subclassing() {
254        let obj = glib::Object::new::<TestSocketControlMessage>();
255
256        assert_eq!(obj.level(), i32::MAX);
257        assert_eq!(obj.msg_type(), i32::MAX);
258        assert_eq!(obj.size(), size_of::<u64>());
259
260        obj.imp().0.set(0x12345678abcdefu64);
261
262        let mut data = [0; size_of::<u64>()];
263        obj.serialize(&mut data);
264
265        let de = SocketControlMessage::deserialize(i32::MAX, i32::MAX, &data)
266            .expect("deserialize failed");
267        let de = de
268            .downcast::<TestSocketControlMessage>()
269            .expect("downcast failed");
270        assert_eq!(de.imp().0.get(), 0x12345678abcdefu64);
271    }
272}