* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use std::ffi::{CString, c_char, c_int, c_uint, c_ulonglong};
const MAX_LENGTH_OF_PARAM_NAME: usize = 49;
#[repr(C)]
#[derive(Copy, Clone)]
pub union HiSysEventParamValue {
pub b_: bool,
pub i8_: i8,
pub u8_: u8,
pub i16_: i16,
pub u16_: u16,
pub i32_: i32,
pub u32_: u32,
pub i64_: i64,
pub u64_: u64,
pub f32_: f32,
pub f64_: f64,
pub char_ptr_: *const c_char,
pub void_ptr_: *const (),
}
#[derive(Copy, Clone)]
pub enum HiSysEventParamType {
Invalid = 0,
Bool,
Int8,
Uint8,
Int16,
Uint16,
Int32,
Uint32,
Int64,
Uint64,
Float,
Double,
ParamTypeString,
BoolArray,
Int8Array,
Uint8Array,
Int16Array,
Uint16Array,
Int32Array,
Uint32Array,
Int64Array,
Uint64Array,
FloatArray,
DoubleArray,
ParamTypeStringArray,
}
pub struct HiSysEventParam<'a> {
pub param_name: &'a str,
pub param_type: HiSysEventParamType,
pub param_value: HiSysEventParamValue,
pub array_size: usize,
}
#[repr(C)]
#[derive(Copy, Clone)]
struct HiSysEventParamWrapper {
pub param_name: [u8; MAX_LENGTH_OF_PARAM_NAME],
pub param_type: c_int,
pub param_value: HiSysEventParamValue,
pub array_size: c_uint,
}
#[allow(dead_code)]
pub fn parse_type_len<T>(_: T) -> (&'static str, usize) {
let mut value_type = std::any::type_name::<T>();
let mut bytes = value_type.as_bytes();
if bytes[0] == b'&' {
value_type = &value_type[1..];
bytes = value_type.as_bytes();
}
if bytes[0] != b'[' {
if bytes[0] == b'&' {
return (&value_type[1..], 0);
} else {
return (value_type, 0);
}
}
let mut val_end: usize = 0;
let mut len_start: usize = 0;
for (i, &item) in bytes.iter().enumerate() {
if item == b';' {
val_end = i;
}
if item == b' ' {
len_start = i + 1;
break;
}
}
let array_len = value_type[len_start..(bytes.len() - 1)].parse::<usize>().unwrap();
if bytes[1] == b'&' {
(&value_type[2..val_end], array_len)
} else {
(&value_type[1..val_end], array_len)
}
}
#[allow(dead_code)]
pub fn build_string_arrays<'a>(param_name: &'a str, str_arr: &[&'a str]) -> HiSysEventParam<'a> {
let mut dest: Vec<*const c_char> = vec![];
for &item in str_arr {
let str_wrapper = CString::new(item).expect("Need a valid value with &str type.");
dest.push(str_wrapper.into_raw() as *const c_char);
}
HiSysEventParam {
param_name,
param_type: HiSysEventParamType::ParamTypeStringArray,
param_value: HiSysEventParamValue {
void_ptr_: std::boxed::Box::<[*const c_char]>::into_raw(dest.into_boxed_slice()) as *const c_int as *const (),
},
array_size: str_arr.len(),
}
}
pub(crate) fn write(event_domain: &str, event_name: &str, event_type: c_int, event_params: &[HiSysEventParam]) -> i32 {
let mut params_wrapper: Vec<HiSysEventParamWrapper> = vec![];
for i in 0..event_params.len() {
params_wrapper.push(HiSysEventParamWrapper {
param_name: [0; MAX_LENGTH_OF_PARAM_NAME],
param_type: event_params[i].param_type as i32 as c_int,
param_value: event_params[i].param_value,
array_size: event_params[i].array_size as c_uint,
});
crate::utils::trans_slice_to_array(event_params[i].param_name, &mut params_wrapper[i].param_name);
}
let func = CString::new(crate::function!()).expect("Need a valid function name");
let domain = CString::new(event_domain).expect("Need a valid domain name");
let event_name = CString::new(event_name).expect("Need a valid event name");
unsafe {
HiSysEventWriteWrapper(
func.as_ptr() as *const c_char,
line!() as c_ulonglong,
domain.as_ptr() as *const c_char,
event_name.as_ptr() as *const c_char,
event_type,
params_wrapper.as_mut_ptr(),
event_params.len() as c_uint
)
}
}
extern "C" {
fn HiSysEventWriteWrapper(func: *const c_char, line: c_ulonglong, domain: *const c_char,
name: *const c_char, event_type: c_int, params: *const HiSysEventParamWrapper,
size: c_uint) -> c_int;
}