mirror of
https://github.com/mbilker/vgpu_unlock-rs.git
synced 2025-10-29 12:20:11 +01:00
format: support hex formatting slices of any type that can be converted to bytes
This commit is contained in:
@@ -5,6 +5,9 @@
|
||||
use std::char;
|
||||
use std::fmt::{self, Write};
|
||||
|
||||
use crate::to_bytes::ToBytes;
|
||||
use crate::utils;
|
||||
|
||||
pub struct CStrFormat<'a>(pub &'a [u8]);
|
||||
|
||||
impl<'a> fmt::Debug for CStrFormat<'a> {
|
||||
@@ -16,7 +19,7 @@ impl<'a> fmt::Debug for CStrFormat<'a> {
|
||||
|
||||
impl<'a> fmt::Display for CStrFormat<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let s = crate::from_c_str(self.0);
|
||||
let s = utils::from_c_str(self.0);
|
||||
|
||||
fmt::Debug::fmt(&s, f)
|
||||
}
|
||||
@@ -37,16 +40,16 @@ impl<T: fmt::LowerHex> fmt::Display for HexFormat<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HexFormatSlice<'a>(pub &'a [u8]);
|
||||
pub struct HexFormatSlice<'a, T>(pub &'a [T]);
|
||||
|
||||
impl<'a> fmt::Debug for HexFormatSlice<'a> {
|
||||
impl<'a, T: Copy + fmt::LowerHex + ToBytes> fmt::Debug for HexFormatSlice<'a, T> {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for HexFormatSlice<'a> {
|
||||
impl<'a, T: Copy + fmt::LowerHex + ToBytes> fmt::Display for HexFormatSlice<'a, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.0.is_empty() {
|
||||
f.write_str("[]")
|
||||
@@ -54,7 +57,9 @@ impl<'a> fmt::Display for HexFormatSlice<'a> {
|
||||
f.write_str("0x")?;
|
||||
|
||||
for v in self.0.iter() {
|
||||
write!(f, "{:02x}", v)?;
|
||||
for b in v.to_ne_bytes() {
|
||||
write!(f, "{b:02x}")?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
12
src/lib.rs
12
src/lib.rs
@@ -8,7 +8,6 @@
|
||||
//! - Arc Compute for their work on Mdev-GPU and GVM documenting more field names in the vGPU
|
||||
//! configuration structure
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::cmp;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
@@ -33,6 +32,7 @@ mod human_number;
|
||||
mod ioctl;
|
||||
mod log;
|
||||
mod nvidia;
|
||||
mod to_bytes;
|
||||
mod utils;
|
||||
mod uuid;
|
||||
|
||||
@@ -489,12 +489,6 @@ pub unsafe extern "C" fn ioctl(fd: RawFd, request: c_ulong, argp: *mut c_void) -
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn from_c_str(value: &[u8]) -> Cow<'_, str> {
|
||||
let len = value.iter().position(|&c| c == 0).unwrap_or(value.len());
|
||||
|
||||
String::from_utf8_lossy(&value[..len])
|
||||
}
|
||||
|
||||
fn load_overrides() -> Result<String, bool> {
|
||||
let config_path = match env::var_os("VGPU_UNLOCK_PROFILE_OVERRIDE_CONFIG_PATH") {
|
||||
Some(path) => PathBuf::from(path),
|
||||
@@ -581,7 +575,7 @@ fn apply_profile_override<C: VgpuConfigLike>(
|
||||
$value
|
||||
);
|
||||
};
|
||||
($target_field:ident, $preprocess:ident, $value:expr) => {
|
||||
($target_field:ident, $preprocess:expr, $value:expr) => {
|
||||
info!(
|
||||
"Patching {}/{}: {} -> {}",
|
||||
vgpu_type,
|
||||
@@ -670,7 +664,7 @@ fn apply_profile_override<C: VgpuConfigLike>(
|
||||
if value_bytes.len() > config.$target_field().len() - 1 {
|
||||
error_too_long!($target_field, $value);
|
||||
} else {
|
||||
patch_msg!($target_field, from_c_str, $value);
|
||||
patch_msg!($target_field, utils::from_c_str, $value);
|
||||
|
||||
// Zero out the field first.
|
||||
// (`fill` was stabilized in Rust 1.50, but Debian Bullseye ships with 1.48)
|
||||
|
||||
49
src/to_bytes.rs
Normal file
49
src/to_bytes.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
pub trait ToBytes {
|
||||
type Bytes: Copy + AsRef<[u8]> + AsMut<[u8]> + IntoIterator<Item = u8> + 'static;
|
||||
|
||||
fn to_ne_bytes(self) -> Self::Bytes;
|
||||
}
|
||||
|
||||
macro_rules! impl_to_bytes {
|
||||
($ty:tt, $len:expr) => {
|
||||
impl ToBytes for $ty {
|
||||
type Bytes = [u8; $len];
|
||||
|
||||
fn to_ne_bytes(self) -> Self::Bytes {
|
||||
$ty::to_ne_bytes(self)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl ToBytes for i8 {
|
||||
type Bytes = [u8; 1];
|
||||
|
||||
fn to_ne_bytes(self) -> Self::Bytes {
|
||||
[self as u8]
|
||||
}
|
||||
}
|
||||
|
||||
impl_to_bytes!(i16, 2);
|
||||
impl_to_bytes!(i32, 4);
|
||||
impl_to_bytes!(i64, 8);
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
impl_to_bytes!(isize, 4);
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
impl_to_bytes!(isize, 8);
|
||||
|
||||
impl ToBytes for u8 {
|
||||
type Bytes = [u8; 1];
|
||||
|
||||
fn to_ne_bytes(self) -> Self::Bytes {
|
||||
[self]
|
||||
}
|
||||
}
|
||||
|
||||
impl_to_bytes!(u16, 2);
|
||||
impl_to_bytes!(u32, 4);
|
||||
impl_to_bytes!(u64, 8);
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
impl_to_bytes!(usize, 4);
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
impl_to_bytes!(usize, 8);
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(feature = "proxmox")]
|
||||
@@ -21,6 +22,12 @@ impl fmt::LowerHex for AlignedU64 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_c_str(value: &[u8]) -> Cow<'_, str> {
|
||||
let len = value.iter().position(|&c| c == 0).unwrap_or(value.len());
|
||||
|
||||
String::from_utf8_lossy(&value[..len])
|
||||
}
|
||||
|
||||
/// Extracts the VMID from the last segment of a mdev uuid
|
||||
///
|
||||
/// For example, for this uuid 00000000-0000-0000-0000-000000000100
|
||||
|
||||
Reference in New Issue
Block a user