#![allow(non_snake_case)]
#![allow(non_upper_case_globals)] #![allow(dead_code)]
use crate::ported::hashtable::{Hashtable, Hashtable_delete, Hashtable_foreach, Hashtable_get};
use crate::ported::meter::Meter;
use crate::ported::object::{Object, ObjectClass, Object_class};
use crate::ported::richstring::RichString;
use crate::ported::xutils::String_safeStrncpy;
#[cfg(target_os = "macos")]
use crate::ported::darwin::platform::{
Platform_dynamicMeterDisplay, Platform_dynamicMeterInit, Platform_dynamicMeterUpdateValues,
Platform_dynamicMeters, Platform_dynamicMetersDone,
};
#[cfg(target_os = "dragonfly")]
use crate::ported::dragonflybsd::platform::{
Platform_dynamicMeterDisplay, Platform_dynamicMeterInit, Platform_dynamicMeterUpdateValues,
Platform_dynamicMeters, Platform_dynamicMetersDone,
};
#[cfg(target_os = "freebsd")]
use crate::ported::freebsd::platform::{
Platform_dynamicMeterDisplay, Platform_dynamicMeterInit, Platform_dynamicMeterUpdateValues,
Platform_dynamicMeters, Platform_dynamicMetersDone,
};
#[cfg(target_os = "linux")]
use crate::ported::linux::platform::{
Platform_dynamicMeterDisplay, Platform_dynamicMeterInit, Platform_dynamicMeterUpdateValues,
Platform_dynamicMeters, Platform_dynamicMetersDone,
};
#[cfg(target_os = "netbsd")]
use crate::ported::netbsd::platform::{
Platform_dynamicMeterDisplay, Platform_dynamicMeterInit, Platform_dynamicMeterUpdateValues,
Platform_dynamicMeters, Platform_dynamicMetersDone,
};
#[cfg(target_os = "openbsd")]
use crate::ported::openbsd::platform::{
Platform_dynamicMeterDisplay, Platform_dynamicMeterInit, Platform_dynamicMeterUpdateValues,
Platform_dynamicMeters, Platform_dynamicMetersDone,
};
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
use crate::ported::solaris::platform::{
Platform_dynamicMeterDisplay, Platform_dynamicMeterInit, Platform_dynamicMeterUpdateValues,
Platform_dynamicMeters, Platform_dynamicMetersDone,
};
#[cfg(not(any(
target_os = "macos",
target_os = "linux",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd",
target_os = "solaris",
target_os = "illumos",
target_os = "dragonfly"
)))]
use crate::ported::unsupported::platform::{
Platform_dynamicMeterDisplay, Platform_dynamicMeterInit, Platform_dynamicMeterUpdateValues,
Platform_dynamicMeters, Platform_dynamicMetersDone,
};
#[derive(Debug, Clone, PartialEq)]
pub struct DynamicMeter {
pub name: String,
pub caption: Option<String>,
pub description: Option<String>,
pub type_: u32,
pub maximum: f64,
}
static DynamicMeter_objectClass: ObjectClass = ObjectClass {
extends: Some(&Object_class),
};
impl Object for DynamicMeter {
fn klass(&self) -> &'static ObjectClass {
&DynamicMeter_objectClass
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DynamicIterator {
pub name: String,
pub key: u32,
pub found: bool,
}
pub fn DynamicMeter_compare(key: u32, meter: &DynamicMeter, iter: &mut DynamicIterator) {
if iter.name == meter.name {
iter.found = true;
iter.key = key;
}
}
pub fn DynamicMeters_new() -> *mut Hashtable {
Platform_dynamicMeters()
}
pub fn DynamicMeters_delete(dynamics: *mut Hashtable) {
if !dynamics.is_null() {
Platform_dynamicMetersDone(dynamics);
Hashtable_delete(unsafe { *Box::from_raw(dynamics) });
}
}
pub fn DynamicMeter_search(
dynamics: Option<&Hashtable>,
name: &str,
key: Option<&mut u32>,
) -> bool {
let mut iter = DynamicIterator {
name: name.to_string(),
key: 0,
found: false,
};
if let Some(dynamics) = dynamics {
Hashtable_foreach(dynamics, &mut |k, value| {
let any: &dyn core::any::Any = value;
let meter = any
.downcast_ref::<DynamicMeter>()
.expect("DynamicMeter_search: hashtable value is not a DynamicMeter");
DynamicMeter_compare(k, meter, &mut iter);
});
}
if let Some(key) = key {
*key = iter.key;
}
iter.found
}
pub fn DynamicMeter_lookup(dynamics: &Hashtable, key: u32) -> Option<&str> {
Hashtable_get(dynamics, key)
.and_then(|o| {
let any: &dyn core::any::Any = o;
any.downcast_ref::<DynamicMeter>()
})
.map(|meter| meter.name.as_str())
}
pub fn DynamicMeter_init(meter: &mut Meter) {
Platform_dynamicMeterInit(meter);
}
pub fn DynamicMeter_updateValues(meter: &mut Meter) {
Platform_dynamicMeterUpdateValues(meter);
}
pub fn DynamicMeter_display(meter: &Meter, out: &mut RichString) {
Platform_dynamicMeterDisplay(meter, out);
}
pub fn DynamicMeter_getCaption(this: &Meter) -> &str {
let settings = unsafe { (*this.host).settings.as_ref() }
.expect("DynamicMeter_getCaption: host->settings is NULL");
let dynamics: &Hashtable = unsafe {
&*settings
.dynamicMeters
.expect("DynamicMeter_getCaption: settings->dynamicMeters is NULL")
};
let meter = Hashtable_get(dynamics, this.param).and_then(|o| {
let any: &dyn core::any::Any = o;
any.downcast_ref::<DynamicMeter>()
});
if let Some(meter) = meter {
return meter.caption.as_deref().unwrap_or(meter.name.as_str());
}
&this.caption
}
pub fn DynamicMeter_getUiName(this: &Meter, name: &mut [u8], length: usize) {
assert!(length > 0);
let settings = unsafe { (*this.host).settings.as_ref() }
.expect("DynamicMeter_getUiName: host->settings is NULL");
let dynamics: &Hashtable = unsafe {
&*settings
.dynamicMeters
.expect("DynamicMeter_getUiName: settings->dynamicMeters is NULL")
};
let meter = Hashtable_get(dynamics, this.param).and_then(|o| {
let any: &dyn core::any::Any = o;
any.downcast_ref::<DynamicMeter>()
});
if let Some(meter) = meter {
if let Some(uiName) = meter.caption.as_deref() {
let uiName = uiName.as_bytes();
let mut uiNameLen = uiName.len();
if uiNameLen > 2 && uiName[uiNameLen - 2] == b':' {
uiNameLen -= 2;
}
let size = length.min(uiNameLen + 1);
String_safeStrncpy(&mut name[..size], uiName);
} else {
String_safeStrncpy(&mut name[..length], meter.name.as_bytes());
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn meter(name: &str) -> DynamicMeter {
DynamicMeter {
name: name.to_string(),
caption: None,
description: None,
type_: 0,
maximum: 0.0,
}
}
fn iter(name: &str) -> DynamicIterator {
DynamicIterator {
name: name.to_string(),
key: 0,
found: false,
}
}
#[test]
fn match_sets_found_and_key() {
let mut it = iter("cpu");
DynamicMeter_compare(7, &meter("cpu"), &mut it);
assert!(it.found);
assert_eq!(it.key, 7);
}
#[test]
fn no_match_leaves_iterator_untouched() {
let mut it = iter("cpu");
DynamicMeter_compare(7, &meter("mem"), &mut it);
assert!(!it.found);
assert_eq!(it.key, 0);
}
#[test]
fn string_eq_is_exact_case_sensitive() {
let mut it = iter("CPU");
DynamicMeter_compare(3, &meter("cpu"), &mut it);
assert!(!it.found);
assert_eq!(it.key, 0);
}
#[test]
fn later_match_overwrites_key_no_early_out() {
let mut it = iter("cpu");
DynamicMeter_compare(1, &meter("cpu"), &mut it);
assert_eq!(it.key, 1);
DynamicMeter_compare(2, &meter("cpu"), &mut it);
assert!(it.found);
assert_eq!(it.key, 2);
}
#[test]
fn empty_names_compare_equal() {
let mut it = iter("");
DynamicMeter_compare(5, &meter(""), &mut it);
assert!(it.found);
assert_eq!(it.key, 5);
}
use crate::ported::hashtable::{Hashtable_new, Hashtable_put};
fn registry(names: &[(u32, &str)]) -> Hashtable {
let mut ht = Hashtable_new(0, false);
for &(k, n) in names {
Hashtable_put(&mut ht, k, Box::new(meter(n)));
}
ht
}
#[test]
fn lookup_returns_name_for_present_key() {
let ht = registry(&[(1, "cpu"), (2, "mem"), (100, "io")]);
assert_eq!(DynamicMeter_lookup(&ht, 1), Some("cpu"));
assert_eq!(DynamicMeter_lookup(&ht, 2), Some("mem"));
assert_eq!(DynamicMeter_lookup(&ht, 100), Some("io"));
}
#[test]
fn lookup_returns_none_for_absent_key() {
let ht = registry(&[(1, "cpu")]);
assert_eq!(DynamicMeter_lookup(&ht, 999), None);
}
#[test]
fn search_finds_by_name_and_writes_key() {
let ht = registry(&[(10, "cpu"), (20, "mem"), (30, "io")]);
let mut key: u32 = 0;
assert!(DynamicMeter_search(Some(&ht), "mem", Some(&mut key)));
assert_eq!(key, 20);
}
#[test]
fn search_key_out_param_is_optional() {
let ht = registry(&[(5, "cpu")]);
assert!(DynamicMeter_search(Some(&ht), "cpu", None));
}
#[test]
fn search_miss_returns_false_and_zeroes_key() {
let ht = registry(&[(1, "cpu"), (2, "mem")]);
let mut key: u32 = 12345;
assert!(!DynamicMeter_search(
Some(&ht),
"nonexistent",
Some(&mut key)
));
assert_eq!(key, 0);
}
#[test]
fn search_null_table_returns_false() {
let mut key: u32 = 7;
assert!(!DynamicMeter_search(None, "cpu", Some(&mut key)));
assert_eq!(key, 0);
}
#[test]
fn search_is_case_sensitive_like_string_eq() {
let ht = registry(&[(1, "CPU")]);
let mut key: u32 = 0;
assert!(!DynamicMeter_search(Some(&ht), "cpu", Some(&mut key)));
assert_eq!(key, 0);
assert!(DynamicMeter_search(Some(&ht), "CPU", None));
}
#[test]
fn search_result_matches_lookup_of_returned_key() {
let ht = registry(&[(3, "alpha"), (17, "beta"), (42, "gamma")]);
for name in ["alpha", "beta", "gamma"] {
let mut key: u32 = 0;
assert!(DynamicMeter_search(Some(&ht), name, Some(&mut key)));
assert_eq!(DynamicMeter_lookup(&ht, key), Some(name));
}
}
}