mirror of
https://github.com/mbilker/vgpu_unlock-rs.git
synced 2026-01-17 11:57:00 +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::char;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
|
||||||
|
use crate::to_bytes::ToBytes;
|
||||||
|
use crate::utils;
|
||||||
|
|
||||||
pub struct CStrFormat<'a>(pub &'a [u8]);
|
pub struct CStrFormat<'a>(pub &'a [u8]);
|
||||||
|
|
||||||
impl<'a> fmt::Debug for CStrFormat<'a> {
|
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> {
|
impl<'a> fmt::Display for CStrFormat<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
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)
|
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]
|
#[inline]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
fmt::Display::fmt(self, f)
|
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 {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if self.0.is_empty() {
|
if self.0.is_empty() {
|
||||||
f.write_str("[]")
|
f.write_str("[]")
|
||||||
@@ -54,7 +57,9 @@ impl<'a> fmt::Display for HexFormatSlice<'a> {
|
|||||||
f.write_str("0x")?;
|
f.write_str("0x")?;
|
||||||
|
|
||||||
for v in self.0.iter() {
|
for v in self.0.iter() {
|
||||||
write!(f, "{:02x}", v)?;
|
for b in v.to_ne_bytes() {
|
||||||
|
write!(f, "{b:02x}")?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
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
|
//! - Arc Compute for their work on Mdev-GPU and GVM documenting more field names in the vGPU
|
||||||
//! configuration structure
|
//! configuration structure
|
||||||
|
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
@@ -33,6 +32,7 @@ mod human_number;
|
|||||||
mod ioctl;
|
mod ioctl;
|
||||||
mod log;
|
mod log;
|
||||||
mod nvidia;
|
mod nvidia;
|
||||||
|
mod to_bytes;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod uuid;
|
mod uuid;
|
||||||
|
|
||||||
@@ -489,12 +489,6 @@ pub unsafe extern "C" fn ioctl(fd: RawFd, request: c_ulong, argp: *mut c_void) -
|
|||||||
ret
|
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> {
|
fn load_overrides() -> Result<String, bool> {
|
||||||
let config_path = match env::var_os("VGPU_UNLOCK_PROFILE_OVERRIDE_CONFIG_PATH") {
|
let config_path = match env::var_os("VGPU_UNLOCK_PROFILE_OVERRIDE_CONFIG_PATH") {
|
||||||
Some(path) => PathBuf::from(path),
|
Some(path) => PathBuf::from(path),
|
||||||
@@ -581,7 +575,7 @@ fn apply_profile_override<C: VgpuConfigLike>(
|
|||||||
$value
|
$value
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
($target_field:ident, $preprocess:ident, $value:expr) => {
|
($target_field:ident, $preprocess:expr, $value:expr) => {
|
||||||
info!(
|
info!(
|
||||||
"Patching {}/{}: {} -> {}",
|
"Patching {}/{}: {} -> {}",
|
||||||
vgpu_type,
|
vgpu_type,
|
||||||
@@ -670,7 +664,7 @@ fn apply_profile_override<C: VgpuConfigLike>(
|
|||||||
if value_bytes.len() > config.$target_field().len() - 1 {
|
if value_bytes.len() > config.$target_field().len() - 1 {
|
||||||
error_too_long!($target_field, $value);
|
error_too_long!($target_field, $value);
|
||||||
} else {
|
} else {
|
||||||
patch_msg!($target_field, from_c_str, $value);
|
patch_msg!($target_field, utils::from_c_str, $value);
|
||||||
|
|
||||||
// Zero out the field first.
|
// Zero out the field first.
|
||||||
// (`fill` was stabilized in Rust 1.50, but Debian Bullseye ships with 1.48)
|
// (`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;
|
use std::fmt;
|
||||||
|
|
||||||
#[cfg(feature = "proxmox")]
|
#[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
|
/// Extracts the VMID from the last segment of a mdev uuid
|
||||||
///
|
///
|
||||||
/// For example, for this uuid 00000000-0000-0000-0000-000000000100
|
/// For example, for this uuid 00000000-0000-0000-0000-000000000100
|
||||||
|
|||||||
Reference in New Issue
Block a user