Skip to content

Commit df8c1af

Browse files
committed
Added subclassing support for gio::SocketControlMessage
1 parent 1f762ec commit df8c1af

File tree

2 files changed

+264
-0
lines changed

2 files changed

+264
-0
lines changed

gio/src/subclass/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mod io_stream;
1010
mod list_model;
1111
mod output_stream;
1212
mod seekable;
13+
mod socket_control_message;
1314

1415
pub use self::application::ArgumentList;
1516

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

0 commit comments

Comments
 (0)