1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use std::mem::{transmute, zeroed};
use std::default::Default;
use super::super::{c_char, size_t};
use super::{sd_bus_message_handler_t, sd_bus_property_get_t, sd_bus_property_set_t};
#[derive(Clone,Copy,Debug)]
#[repr(u32)]
pub enum SdBusVtableType {
Start = '<' as u32,
End = '>' as u32,
Method = 'M' as u32,
Signal = 'S' as u32,
Property = 'P' as u32,
WritableProperty = 'W' as u32,
}
#[derive(Clone, Copy, Debug)]
#[repr(u64)]
pub enum SdBusVtableFlag {
#[allow(clippy::identity_op)]
Deprecated = 1 << 0,
Hidden = 1 << 1,
Unprivileged = 1 << 2,
MethodNoReply = 1 << 3,
PropertyConst = 1 << 4,
PropertyEmitsChange = 1 << 5,
PropertyEmitsInvalidation = 1 << 6,
PropertyExplicit = 1 << 7,
CapabilityMask = 0xFFFF << 40,
}
#[derive(Clone, Debug)]
#[repr(C)]
pub struct sd_bus_vtable {
type_and_flags: u64,
union_data: [usize; 5],
}
impl Default for sd_bus_vtable {
fn default() -> Self {
unsafe { zeroed() }
}
}
impl sd_bus_vtable {
pub fn type_and_flags(typ: u32, flags: u64) -> u64 {
let mut val = [0u8; 8];
assert!(typ <= ((1 << 8) - 1));
assert!(flags <= ((1 << 56) - 1));
val[0] = typ as u8;
let flags_raw: [u8; 8] = unsafe { transmute(flags) };
for i in 0..7 {
val[i + 1] = flags_raw[i];
}
unsafe { transmute(val) }
}
pub fn typ(&self) -> u32 {
unsafe {
let raw: *const u8 = &self.type_and_flags as *const _ as *const u8;
*raw as u32
}
}
pub fn flags(&self) -> u64 {
let mut val = [0u8; 8];
unsafe {
let raw: *const u8 = transmute(&self.type_and_flags);
for i in 1..8 {
val[i - 1] = *raw.offset(i as isize);
}
transmute(val)
}
}
}
#[test]
fn vtable_bitfield() {
let mut b: sd_bus_vtable = Default::default();
b.type_and_flags = sd_bus_vtable::type_and_flags(0xAA, 0xBBCCBB);
assert_eq!(b.typ(), 0xAA);
assert_eq!(b.flags(), 0xBBCCBB);
}
#[test]
fn size_eq() {
use std::mem::size_of;
assert_eq!(size_of::<usize>(), size_of::<size_t>());
assert_eq!(size_of::<usize>(), size_of::<*const u8>());
}
#[repr(C)]
pub struct sd_bus_table_start {
pub element_size: size_t,
}
#[repr(C)]
pub struct sd_bus_table_method {
pub member: *const c_char,
pub signature: *const c_char,
pub result: *const c_char,
pub handler: sd_bus_message_handler_t,
pub offset: size_t,
}
#[repr(C)]
pub struct sd_bus_table_signal {
pub member: *const c_char,
pub signature: *const c_char,
}
#[repr(C)]
pub struct sd_bus_table_property {
pub member: *const c_char,
pub signature: *const c_char,
pub get: sd_bus_property_get_t,
pub set: sd_bus_property_set_t,
pub offset: size_t,
}