utils.rs35.00%
1
// Copyright 2024 Google LLC2
//3
// Licensed under the Apache License, Version 2.0 (the "License");4
// you may not use this file except in compliance with the License.5
// You may obtain a copy of the License at6
//7
// https://www.apache.org/licenses/LICENSE-2.08
//9
// Unless required by applicable law or agreed to in writing, software10
// distributed under the License is distributed on an "AS IS" BASIS,11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12
// See the License for the specific language governing permissions and13
// limitations under the License.14
15
pub mod endian;16
#[cfg(target_os = "linux")]17
pub mod uds;18
19
use std::sync::atomic::{AtomicU64, Ordering};20
21
pub fn truncate_u64(val: u64, size: u64) -> u64 {39x22
val & (u64::MAX >> (64 - (size << 3)))39x23
}39x24
25
#[macro_export]26
macro_rules! align_up {27
($num:expr, $bits:expr) => {{28
let mask = (1 << $bits) - 1;29
($num.wrapping_add(mask)) & !mask30
}};31
}32
33
#[macro_export]34
macro_rules! align_up_ty {35
($num:expr, $ty:ty) => {{36
let mask = ::core::mem::align_of::<$ty>() - 1;37
($num.wrapping_add(mask)) & !mask38
}};39
}40
41
#[macro_export]42
macro_rules! align_down {43
($num:expr, $bits:expr) => {{44
let mask = (1 << $bits) - 1;45
$num & !mask46
}};47
}48
49
#[macro_export]50
macro_rules! assign_bits {51
($dst:expr, $src:expr, $mask:expr) => {52
$dst = ($dst & !$mask) | ($src & $mask)53
};54
}55
56
#[macro_export]57
macro_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]65
pub fn wrapping_sum<'a, T>(data: T) -> u866
where67
T: IntoIterator<Item = &'a u8>,68
{69
data.into_iter().fold(0u8, |accu, e| accu.wrapping_add(*e))70
}71
72
pub fn get_atomic_low32(num: &AtomicU64) -> u32 {73
num.load(Ordering::Acquire) as u3274
}75
76
pub fn get_atomic_high32(num: &AtomicU64) -> u32 {77
(num.load(Ordering::Acquire) >> 32) as u3278
}79
80
pub fn set_low32(num: &mut u64, val: u32) {81
*num &= !0xffff_ffff;82
*num |= val as u64;83
}84
85
pub fn set_high32(num: &mut u64, val: u32) {86
*num &= 0xffff_ffff;87
*num |= (val as u64) << 32;88
}89
90
pub 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
96
pub 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]103
macro_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]123
macro_rules! consts {124
(125
$(#[$attr:meta])*126
$vs:vis struct $EnumName:ident($TyName:ty) {127
$( $(#[$vattr:meta])* $VARIANT:ident = $value:expr;)*128
}129
) => {130
#[repr(transparent)]131
#[derive(PartialEq, Eq, Copy, Clone)]132
$(#[$attr])*133
$vs struct $EnumName($TyName);134
135
impl $EnumName {136
$($(#[$vattr])* pub const $VARIANT: $EnumName = $EnumName($value);)*137
138
#[allow(dead_code)]139
pub const fn raw(self) -> $TyName {104x140
self.0104x141
}104x142
143
#[allow(dead_code)]144
pub const fn name(self) -> &'static str {145
match self {146
$($EnumName::$VARIANT => stringify!($VARIANT),)*147
#[allow(unreachable_patterns)]148
_ => "Unknown"149
}150
}151
}152
153
impl ::core::fmt::Debug for $EnumName {154
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {21x155
f.write_str(stringify!($EnumName))?;21x156
match *self {21x157
$($EnumName::$VARIANT => {158
f.write_str("::")?;159
f.write_str(stringify!($VARIANT))160
})*161
#[allow(unreachable_patterns)]162
_ => {163
::core::fmt::Write::write_char(f, '(')?;164
::core::fmt::Debug::fmt(&self.0, f)?;165
::core::fmt::Write::write_char(f, ')')166
}167
}168
}21x169
}170
171
172
impl From<$EnumName> for $TyName {173
fn from(value: $EnumName) -> Self {13x174
value.013x175
}13x176
}177
178
impl From<$TyName> for $EnumName {179
fn from(value: $TyName) -> Self {22x180
$EnumName(value)22x181
}22x182
}183
}184
}185
186
#[macro_export]187
macro_rules! bitflags {188
(189
$(#[$attr:meta])*190
$vs:vis struct $FlagTy:ident($TyName:ty) {191
$(192
$(#[$inner:ident $($args:tt)*])*193
$FALG:ident = $value:expr;194
)*195
}196
) => {197
#[repr(transparent)]198
#[derive(PartialEq, Eq, Copy, Clone, Hash)]199
$(#[$attr])*200
$vs struct $FlagTy($TyName);201
202
::bitflags::bitflags! {203
impl $FlagTy: $TyName {204
$(205
$(#[$inner $($args)*])*206
const $FALG = $value;207
)*208
}209
}210
211
impl ::core::fmt::Debug for $FlagTy {212
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {126x213
if self.is_empty() {126x214
write!(f, "0")51x215
} else {216
::bitflags::parser::to_writer(self, f)75x217
}218
}126x219
}220
};221
}222
223
#[cfg(test)]224
#[path = "utils_test.rs"]225
mod tests;226