Implement auto generation for header objects

next
Sayan Nandan 1 year ago
parent 45c93eac3c
commit 2756682729
No known key found for this signature in database
GPG Key ID: 42EEDF4AE9D96B54

@ -304,7 +304,7 @@ impl StaticRecordUV {
pub const fn os(&self) -> HostOS {
self.os
}
pub const fn encode(&self) -> StaticRecordUVRaw {
pub const fn encoded(&self) -> StaticRecordUVRaw {
StaticRecordUVRaw::new(
self.header_version(),
self.ptr_width(),

@ -30,7 +30,7 @@ use crate::{
storage::{
header::{HostArch, HostEndian, HostOS, HostPointerWidth},
v1::header_impl::FileSpecifierVersion,
versions::{DriverVersion, ServerVersion},
versions::{self, DriverVersion, ServerVersion},
},
},
util,
@ -160,6 +160,13 @@ impl DRHostSignatureRaw {
const DRHS_OFFSET_P5: usize = Self::DRHS_OFFSET_P4 + 1;
const DRHS_OFFSET_P6: usize = Self::DRHS_OFFSET_P5 + 1;
const _ENSURE: () = assert!(Self::DRHS_OFFSET_P6 == sizeof!(Self) - 1);
pub const fn new_auto(file_specifier_version: FileSpecifierVersion) -> Self {
Self::new(
versions::v1::V1_SERVER_VERSION,
versions::v1::V1_DRIVER_VERSION,
file_specifier_version,
)
}
pub const fn new(
server_version: ServerVersion,
driver_version: DriverVersion,
@ -343,6 +350,16 @@ impl DRRuntimeSignatureRaw {
const DRRS_OFFSET_P3: usize = Self::DRRS_OFFSET_P2 + sizeof!(u128);
const DRRS_OFFSET_P4: usize = Self::DRRS_OFFSET_P3 + 1;
const _ENSURE: () = assert!(Self::DRRS_OFFSET_P4 == sizeof!(Self) - 255);
pub fn new_auto(modify_count: u64) -> Self {
let hostname = crate::util::os::get_hostname();
Self::new(
modify_count,
crate::util::os::get_epoch_time(),
crate::util::os::get_uptime(),
hostname.len(),
hostname.raw(),
)
}
pub fn new(
modify_count: u64,
host_epoch_time: u128,

@ -135,6 +135,19 @@ impl GRMetadataRecordRaw {
pub const fn empty_buffer() -> [u8; sizeof!(Self)] {
[0u8; sizeof!(Self)]
}
pub const fn new_auto(
scope: FileScope,
specifier: FileSpecifier,
specifier_id: FileSpecifierVersion,
) -> Self {
Self::new_full(
versions::v1::V1_SERVER_VERSION,
versions::v1::V1_DRIVER_VERSION,
scope,
specifier,
specifier_id,
)
}
pub const fn new_full(
server_version: ServerVersion,
driver_version: DriverVersion,
@ -320,6 +333,18 @@ impl GRHostRecordRaw {
const GRHR_OFFSET_P5: usize = Self::GRHR_OFFSET_P4 + sizeof!(u64);
const GRHR_OFFSET_P6: usize = Self::GRHR_OFFSET_P5 + 1;
const _ENSURE: () = assert!(Self::GRHR_OFFSET_P6 == sizeof!(Self) - 255);
pub fn new_auto(setting_version: u32, run_mode: HostRunMode, startup_counter: u64) -> Self {
let hostname = crate::util::os::get_hostname();
Self::new(
crate::util::os::get_epoch_time(),
crate::util::os::get_uptime(),
setting_version,
run_mode,
startup_counter,
hostname.len(),
hostname.raw(),
)
}
pub fn new(
p0_epoch_time: u128,
p1_uptime: u128,

@ -182,9 +182,9 @@ impl SDSSHeader {
pub fn dr_rs(&self) -> &dr::DRRuntimeSignature {
&self.dr_rs
}
pub fn encode(&self) -> SDSSHeaderRaw {
pub fn encoded(&self) -> SDSSHeaderRaw {
SDSSHeaderRaw::new_full(
self.sr.encode(),
self.sr.encoded(),
self.gr_mdr().encoded(),
self.gr_hr().encoded(),
self.dr_hs().encoded(),
@ -202,6 +202,27 @@ pub struct SDSSHeaderRaw {
}
impl SDSSHeaderRaw {
pub fn new_auto(
gr_mdr_scope: FileScope,
gr_mdr_specifier: FileSpecifier,
gr_mdr_specifier_id: FileSpecifierVersion,
gr_hr_setting_version: u32,
gr_hr_run_mode: HostRunMode,
gr_hr_startup_counter: u64,
dr_rts_modify_count: u64,
) -> Self {
Self::new_full(
sr::StaticRecordRaw::new_auto(),
gr::GRMetadataRecordRaw::new_auto(gr_mdr_scope, gr_mdr_specifier, gr_mdr_specifier_id),
gr::GRHostRecordRaw::new_auto(
gr_hr_setting_version,
gr_hr_run_mode,
gr_hr_startup_counter,
),
dr::DRHostSignatureRaw::new_auto(gr_mdr_specifier_id),
dr::DRRuntimeSignatureRaw::new_auto(dr_rts_modify_count),
)
}
pub fn new_full(
sr: sr::StaticRecordRaw,
gr_mdr: gr::GRMetadataRecordRaw,
@ -241,7 +262,7 @@ impl SDSSHeaderRaw {
pub fn get1_dr_1_hr_0(&self) -> &[u8] {
self.gr_1_hr.data.slice()
}
pub const fn calculate_fixed_header_size() -> usize {
pub const fn header_size() -> usize {
sizeof!(sr::StaticRecordRaw)
+ sizeof!(gr::GRMetadataRecordRaw)
+ sizeof!(gr::GRHostRecordRaw)

@ -38,9 +38,9 @@ impl StaticRecord {
pub const fn new(sr: StaticRecordUV) -> Self {
Self { sr }
}
pub const fn encode(&self) -> StaticRecordRaw {
pub const fn encoded(&self) -> StaticRecordRaw {
StaticRecordRaw {
base: self.sr.encode(),
base: self.sr.encoded(),
}
}
pub const fn sr(&self) -> &StaticRecordUV {
@ -54,10 +54,11 @@ pub struct StaticRecordRaw {
}
impl StaticRecordRaw {
pub const fn new() -> Self {
Self {
base: StaticRecordUVRaw::create(versions::v1::V1_HEADER_VERSION),
}
pub const fn new_auto() -> Self {
Self::new(StaticRecordUVRaw::create(versions::v1::V1_HEADER_VERSION))
}
pub const fn new(base: StaticRecordUVRaw) -> Self {
Self { base }
}
pub const fn empty_buffer() -> [u8; sizeof!(Self)] {
[0u8; sizeof!(Self)]

@ -264,7 +264,7 @@ pub fn dirsize(path: impl AsRef<Path>) -> IoResult<u64> {
/// Returns the current system uptime in milliseconds
pub fn get_uptime() -> u128 {
uptime().unwrap()
uptime_impl::uptime().unwrap()
}
/// Returns the current epoch time in nanoseconds
@ -275,58 +275,166 @@ pub fn get_epoch_time() -> u128 {
.as_nanos()
}
#[cfg(target_os = "linux")]
fn uptime() -> std::io::Result<u128> {
let mut sysinfo: libc::sysinfo = unsafe { std::mem::zeroed() };
let res = unsafe { libc::sysinfo(&mut sysinfo) };
if res == 0 {
Ok(sysinfo.uptime as u128 * 1_000)
} else {
Err(std::io::Error::last_os_error())
}
/// Returns the hostname
pub fn get_hostname() -> hostname_impl::Hostname {
hostname_impl::Hostname::get()
}
#[cfg(any(
target_os = "macos",
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd"
))]
fn uptime() -> std::io::Result<u128> {
use libc::{c_void, size_t, sysctl, timeval};
use std::ptr;
let mib = [libc::CTL_KERN, libc::KERN_BOOTTIME];
let mut boottime = timeval {
tv_sec: 0,
tv_usec: 0,
};
let mut size = std::mem::size_of::<libc::timeval>() as size_t;
let result = unsafe {
sysctl(
// this cast is fine. sysctl only needs to access the ptr to array base (read)
&mib as *const _ as *mut _,
2,
&mut boottime as *mut timeval as *mut c_void,
&mut size,
ptr::null_mut(),
0,
)
};
mod uptime_impl {
#[cfg(target_os = "linux")]
pub(super) fn uptime() -> std::io::Result<u128> {
let mut sysinfo: libc::sysinfo = unsafe { std::mem::zeroed() };
let res = unsafe { libc::sysinfo(&mut sysinfo) };
if res == 0 {
Ok(sysinfo.uptime as u128 * 1_000)
} else {
Err(std::io::Error::last_os_error())
}
}
#[cfg(any(
target_os = "macos",
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd"
))]
pub(super) fn uptime() -> std::io::Result<u128> {
use libc::{c_void, size_t, sysctl, timeval};
use std::ptr;
let mib = [libc::CTL_KERN, libc::KERN_BOOTTIME];
let mut boottime = timeval {
tv_sec: 0,
tv_usec: 0,
};
let mut size = std::mem::size_of::<libc::timeval>() as size_t;
let result = unsafe {
sysctl(
// this cast is fine. sysctl only needs to access the ptr to array base (read)
&mib as *const _ as *mut _,
2,
&mut boottime as *mut timeval as *mut c_void,
&mut size,
ptr::null_mut(),
0,
)
};
if result == 0 {
let current_time = unsafe { libc::time(ptr::null_mut()) };
let uptime_secs = current_time - boottime.tv_sec;
Ok((uptime_secs as u128) * 1_000)
} else {
Err(std::io::Error::last_os_error())
if result == 0 {
let current_time = unsafe { libc::time(ptr::null_mut()) };
let uptime_secs = current_time - boottime.tv_sec;
Ok((uptime_secs as u128) * 1_000)
} else {
Err(std::io::Error::last_os_error())
}
}
#[cfg(target_os = "windows")]
pub(super) fn uptime() -> std::io::Result<u128> {
Ok(unsafe { winapi::um::sysinfoapi::GetTickCount64() } as u128)
}
}
#[cfg(target_os = "windows")]
fn uptime() -> std::io::Result<u128> {
Ok(unsafe { winapi::um::sysinfoapi::GetTickCount64() } as u128)
mod hostname_impl {
use std::ffi::CStr;
pub struct Hostname {
len: u8,
raw: [u8; 255],
}
impl Hostname {
pub fn get() -> Self {
get_hostname()
}
unsafe fn new_from_raw_buf(buf: &[u8; 256]) -> Self {
let mut raw = [0u8; 255];
raw.copy_from_slice(&buf[..255]);
Self {
len: CStr::from_ptr(buf.as_ptr().cast()).to_bytes().len() as _,
raw,
}
}
pub fn as_str(&self) -> &str {
unsafe {
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
self.raw.as_ptr(),
self.len as _,
))
}
}
pub fn raw(&self) -> [u8; 255] {
self.raw
}
pub fn len(&self) -> u8 {
self.len
}
}
#[cfg(target_family = "unix")]
fn get_hostname() -> Hostname {
use libc::gethostname;
let mut buf: [u8; 256] = [0; 256];
unsafe {
gethostname(buf.as_mut_ptr().cast(), buf.len());
Hostname::new_from_raw_buf(&buf)
}
}
#[cfg(target_family = "windows")]
fn get_hostname() -> (usize, [u8; 255]) {
use winapi::shared::minwindef::DWORD;
use winapi::um::sysinfoapi::GetComputerNameA;
let mut buf: [u8; 256] = [0; 256];
let mut size: DWORD = buf.len() as u32;
unsafe {
GetComputerNameA(buf.as_mut_ptr().cast(), &mut size);
Hostname::new_from_raw_buf(&buf)
}
}
#[cfg(test)]
mod test {
use std::process::Command;
#[cfg(target_os = "linux")]
fn test_get_hostname() -> Result<String, Box<dyn std::error::Error>> {
let output = Command::new("sh")
.arg("-c")
.arg("hostname")
.output()?;
let hostname = String::from_utf8_lossy(&output.stdout).trim().to_string();
Ok(hostname)
}
#[cfg(target_os = "windows")]
fn test_get_hostname() -> Result<String, Box<dyn std::error::Error>> {
let output = Command::new("cmd")
.args(&["/C", "hostname"])
.output()?;
let hostname = String::from_utf8_lossy(&output.stdout).trim().to_string();
Ok(hostname)
}
#[cfg(target_os = "macos")]
fn test_get_hostname() -> Result<String, Box<dyn std::error::Error>> {
let output = Command::new("sh")
.arg("-c")
.arg("scutil --get LocalHostName")
.output()?;
let hostname = String::from_utf8_lossy(&output.stdout).trim().to_string();
Ok(hostname)
}
#[test]
fn t_get_hostname() {
let hostname_from_cmd = test_get_hostname().unwrap();
assert_eq!(hostname_from_cmd.as_str(), super::Hostname::get().as_str());
}
}
}
#[test]

Loading…
Cancel
Save