Skip to main content

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