use core::fmt::Debug;
use super::PerformanceRecord;
use crate::performance::error::Error;
#[derive(Debug)]
pub struct GuidEventRecord {
pub progress_id: u16,
pub acpi_id: u32,
pub timestamp: u64,
pub guid: crate::BinaryGuid,
}
impl GuidEventRecord {
pub const TYPE: u16 = 0x1010;
pub const REVISION: u8 = 1;
pub fn new(progress_id: u16, acpi_id: u32, timestamp: u64, guid: crate::BinaryGuid) -> Self {
Self { progress_id, acpi_id, timestamp, guid }
}
}
impl PerformanceRecord for GuidEventRecord {
fn record_type(&self) -> u16 {
Self::TYPE
}
fn revision(&self) -> u8 {
Self::REVISION
}
fn write_data_into(&self, buff: &mut [u8], offset: &mut usize) -> Result<(), Error> {
write_u16_le(buff, offset, self.progress_id)?;
write_u32_le(buff, offset, self.acpi_id)?;
write_u64_le(buff, offset, self.timestamp)?;
write_bytes(buff, offset, self.guid.as_bytes())?;
Ok(())
}
}
#[derive(Debug)]
pub struct DynamicStringEventRecord<'a> {
pub progress_id: u16,
pub acpi_id: u32,
pub timestamp: u64,
pub guid: crate::BinaryGuid,
pub string: &'a str,
}
impl<'a> DynamicStringEventRecord<'a> {
pub const TYPE: u16 = 0x1011;
pub const REVISION: u8 = 1;
pub fn new(progress_id: u16, acpi_id: u32, timestamp: u64, guid: crate::BinaryGuid, string: &'a str) -> Self {
Self { progress_id, acpi_id, timestamp, guid, string }
}
}
impl PerformanceRecord for DynamicStringEventRecord<'_> {
fn record_type(&self) -> u16 {
Self::TYPE
}
fn revision(&self) -> u8 {
Self::REVISION
}
fn write_data_into(&self, buff: &mut [u8], offset: &mut usize) -> Result<(), Error> {
write_u16_le(buff, offset, self.progress_id)?;
write_u32_le(buff, offset, self.acpi_id)?;
write_u64_le(buff, offset, self.timestamp)?;
write_bytes(buff, offset, self.guid.as_bytes())?;
write_bytes(buff, offset, self.string.as_bytes())?;
write_u8(buff, offset, 0)?; Ok(())
}
}
#[derive(Debug)]
pub struct DualGuidStringEventRecord<'a> {
pub progress_id: u16,
pub acpi_id: u32,
pub timestamp: u64,
pub guid_1: crate::BinaryGuid,
pub guid_2: crate::BinaryGuid,
pub string: &'a str,
}
impl<'a> DualGuidStringEventRecord<'a> {
pub const TYPE: u16 = 0x1012;
pub const REVISION: u8 = 1;
pub fn new(
progress_id: u16,
acpi_id: u32,
timestamp: u64,
guid_1: crate::BinaryGuid,
guid_2: crate::BinaryGuid,
string: &'a str,
) -> Self {
Self { progress_id, acpi_id, timestamp, guid_1, guid_2, string }
}
}
impl PerformanceRecord for DualGuidStringEventRecord<'_> {
fn record_type(&self) -> u16 {
Self::TYPE
}
fn revision(&self) -> u8 {
Self::REVISION
}
fn write_data_into(&self, buff: &mut [u8], offset: &mut usize) -> Result<(), Error> {
write_u16_le(buff, offset, self.progress_id)?;
write_u32_le(buff, offset, self.acpi_id)?;
write_u64_le(buff, offset, self.timestamp)?;
write_bytes(buff, offset, self.guid_1.as_bytes())?;
write_bytes(buff, offset, self.guid_2.as_bytes())?;
write_bytes(buff, offset, self.string.as_bytes())?;
write_u8(buff, offset, 0)?;
Ok(())
}
}
#[derive(Debug)]
pub struct GuidQwordEventRecord {
pub progress_id: u16,
pub acpi_id: u32,
pub timestamp: u64,
pub guid: crate::BinaryGuid,
pub qword: u64,
}
impl GuidQwordEventRecord {
pub const TYPE: u16 = 0x1013;
pub const REVISION: u8 = 1;
pub fn new(progress_id: u16, acpi_id: u32, timestamp: u64, guid: crate::BinaryGuid, qword: u64) -> Self {
Self { progress_id, acpi_id, timestamp, guid, qword }
}
}
impl PerformanceRecord for GuidQwordEventRecord {
fn record_type(&self) -> u16 {
Self::TYPE
}
fn revision(&self) -> u8 {
Self::REVISION
}
fn write_data_into(&self, buff: &mut [u8], offset: &mut usize) -> Result<(), Error> {
write_u16_le(buff, offset, self.progress_id)?;
write_u32_le(buff, offset, self.acpi_id)?;
write_u64_le(buff, offset, self.timestamp)?;
write_bytes(buff, offset, self.guid.as_bytes())?;
write_u64_le(buff, offset, self.qword)?;
Ok(())
}
}
#[derive(Debug)]
pub struct GuidQwordStringEventRecord<'a> {
pub progress_id: u16,
pub acpi_id: u32,
pub timestamp: u64,
pub guid: crate::BinaryGuid,
pub qword: u64,
pub string: &'a str,
}
impl<'a> GuidQwordStringEventRecord<'a> {
pub const TYPE: u16 = 0x1014;
pub const REVISION: u8 = 1;
pub fn new(
progress_id: u16,
acpi_id: u32,
timestamp: u64,
guid: crate::BinaryGuid,
qword: u64,
string: &'a str,
) -> Self {
Self { progress_id, acpi_id, timestamp, guid, qword, string }
}
}
impl PerformanceRecord for GuidQwordStringEventRecord<'_> {
fn record_type(&self) -> u16 {
Self::TYPE
}
fn revision(&self) -> u8 {
Self::REVISION
}
fn write_data_into(&self, buff: &mut [u8], offset: &mut usize) -> Result<(), Error> {
write_u16_le(buff, offset, self.progress_id)?;
write_u32_le(buff, offset, self.acpi_id)?;
write_u64_le(buff, offset, self.timestamp)?;
write_bytes(buff, offset, self.guid.as_bytes())?;
write_u64_le(buff, offset, self.qword)?;
write_bytes(buff, offset, self.string.as_bytes())?;
write_u8(buff, offset, 0)?;
Ok(())
}
}
trait IntoLeBytes {
type Bytes: AsRef<[u8]>;
fn to_le_bytes(self) -> Self::Bytes;
}
macro_rules! impl_into_le_bytes {
($t:ty) => {
impl IntoLeBytes for $t {
type Bytes = [u8; core::mem::size_of::<$t>()];
fn to_le_bytes(self) -> Self::Bytes {
<$t>::to_le_bytes(self)
}
}
};
}
impl_into_le_bytes!(u8);
impl_into_le_bytes!(u16);
impl_into_le_bytes!(u32);
impl_into_le_bytes!(u64);
fn ensure_space(buff: &[u8], offset: usize, needed: usize) -> Result<(), Error> {
if offset + needed > buff.len() {
return Err(Error::Serialization);
}
Ok(())
}
fn write_bytes(dest: &mut [u8], offset: &mut usize, src: &[u8]) -> Result<(), Error> {
ensure_space(dest, *offset, src.len())?;
dest[*offset..*offset + src.len()].copy_from_slice(src);
*offset += src.len();
Ok(())
}
fn write_uint<T: IntoLeBytes>(dest: &mut [u8], offset: &mut usize, v: T) -> Result<(), Error> {
let bytes = v.to_le_bytes();
write_bytes(dest, offset, bytes.as_ref())
}
fn write_u8(dest: &mut [u8], offset: &mut usize, v: u8) -> Result<(), Error> {
write_uint(dest, offset, v)
}
fn write_u16_le(dest: &mut [u8], offset: &mut usize, v: u16) -> Result<(), Error> {
write_uint(dest, offset, v)
}
fn write_u32_le(dest: &mut [u8], offset: &mut usize, v: u32) -> Result<(), Error> {
write_uint(dest, offset, v)
}
fn write_u64_le(dest: &mut [u8], offset: &mut usize, v: u64) -> Result<(), Error> {
write_uint(dest, offset, v)
}