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