1pub mod endian;
16#[cfg(target_os = "linux")]
17pub mod uds;
18
19use std::sync::atomic::{AtomicU64, Ordering};
20
21pub fn truncate_u64(val: u64, size: u64) -> u64 {
22 val & (u64::MAX >> (64 - (size << 3)))
23}
24
25#[macro_export]
26macro_rules! align_up {
27 ($num:expr, $bits:expr) => {{
28 let mask = (1 << $bits) - 1;
29 ($num.wrapping_add(mask)) & !mask
30 }};
31}
32
33#[macro_export]
34macro_rules! align_up_ty {
35 ($num:expr, $ty:ty) => {{
36 let mask = ::core::mem::align_of::<$ty>() - 1;
37 ($num.wrapping_add(mask)) & !mask
38 }};
39}
40
41#[macro_export]
42macro_rules! align_down {
43 ($num:expr, $bits:expr) => {{
44 let mask = (1 << $bits) - 1;
45 $num & !mask
46 }};
47}
48
49#[macro_export]
50macro_rules! assign_bits {
51 ($dst:expr, $src:expr, $mask:expr) => {
52 $dst = ($dst & !$mask) | ($src & $mask)
53 };
54}
55
56#[macro_export]
57macro_rules! mask_bits {
58 ($dst:expr, $src:expr, $mask:expr) => {
59 ($dst & !$mask) | ($src & $mask)
60 };
61}
62
63#[cfg(target_arch = "x86_64")]
64#[inline]
65pub fn wrapping_sum<'a, T>(data: T) -> u8
66where
67 T: IntoIterator<Item = &'a u8>,
68{
69 data.into_iter().fold(0u8, |accu, e| accu.wrapping_add(*e))
70}
71
72pub fn get_atomic_low32(num: &AtomicU64) -> u32 {
73 num.load(Ordering::Acquire) as u32
74}
75
76pub fn get_atomic_high32(num: &AtomicU64) -> u32 {
77 (num.load(Ordering::Acquire) >> 32) as u32
78}
79
80pub fn set_low32(num: &mut u64, val: u32) {
81 *num &= !0xffff_ffff;
82 *num |= val as u64;
83}
84
85pub fn set_high32(num: &mut u64, val: u32) {
86 *num &= 0xffff_ffff;
87 *num |= (val as u64) << 32;
88}
89
90pub fn set_atomic_low32(num: &AtomicU64, val: u32) {
91 let mut cur = num.load(Ordering::Acquire);
92 set_low32(&mut cur, val);
93 num.store(cur, Ordering::Release)
94}
95
96pub fn set_atomic_high32(num: &AtomicU64, val: u32) {
97 let mut cur = num.load(Ordering::Acquire);
98 set_high32(&mut cur, val);
99 num.store(cur, Ordering::Release)
100}
101
102#[macro_export]
103macro_rules! ffi {
104 ($f:expr) => {{
105 let ret = $f;
106 if ret <= -1 {
107 Err(::std::io::Error::last_os_error())
108 } else {
109 Ok(ret)
110 }
111 }};
112 ($f:expr, $failure:expr) => {{
113 let ret = $f;
114 if ret == $failure {
115 Err(::std::io::Error::last_os_error())
116 } else {
117 Ok(ret)
118 }
119 }};
120}
121
122#[macro_export]
123macro_rules! c_enum {
124 (
125 $(#[$attr:meta])*
126 $vs:vis struct $EnumName:ident($TyName:ty);
127 {
128 $( $(#[$vattr:meta])* $VARIANT:ident = $value:expr;)*
129 }
130 ) => {
131 #[repr(transparent)]
132 #[derive(PartialEq, Eq, Copy, Clone)]
133 $(#[$attr])*
134 $vs struct $EnumName($TyName);
135
136 impl $EnumName {
137 $($(#[$vattr])* pub const $VARIANT: $EnumName = $EnumName($value);)*
138
139 #[allow(dead_code)]
140 pub const fn raw(self) -> $TyName {
141 self.0
142 }
143 }
144
145 impl ::core::fmt::Debug for $EnumName {
146 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
147 f.write_str(stringify!($EnumName))?;
148 match *self {
149 $($EnumName::$VARIANT => {
150 f.write_str("::")?;
151 f.write_str(stringify!($VARIANT))
152 })*
153 _ => {
154 ::core::fmt::Write::write_char(f, '(')?;
155 ::core::fmt::Debug::fmt(&self.0, f)?;
156 ::core::fmt::Write::write_char(f, ')')
157 }
158 }
159 }
160 }
161
162
163 impl From<$EnumName> for $TyName {
164 fn from(value: $EnumName) -> Self {
165 value.0
166 }
167 }
168
169 impl From<$TyName> for $EnumName {
170 fn from(value: $TyName) -> Self {
171 $EnumName(value)
172 }
173 }
174 }
175}
176
177#[cfg(test)]
178#[path = "utils_test.rs"]
179mod tests;