libsystemd_sys/bus/
vtable.rs

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