pub use binaryninjacore_sys::BNSettingsScope as SettingsScope;
use binaryninjacore_sys::*;
use std::os::raw::c_char;
use crate::binaryview::BinaryView;
use crate::rc::*;
use crate::string::{BnStrCompatible, BnString};
use std::ptr;
#[derive(PartialEq, Eq, Hash)]
pub struct Settings {
pub(crate) handle: *mut BNSettings,
}
unsafe impl Send for Settings {}
unsafe impl Sync for Settings {}
impl Settings {
pub(crate) unsafe fn from_raw(handle: *mut BNSettings) -> Ref<Self> {
debug_assert!(!handle.is_null());
Ref::new(Self { handle })
}
pub fn new<S: BnStrCompatible>(instance_id: S) -> Ref<Self> {
let instance_id = instance_id.into_bytes_with_nul();
unsafe {
let handle = BNCreateSettings(instance_id.as_ref().as_ptr() as *mut _);
debug_assert!(!handle.is_null());
Ref::new(Self { handle })
}
}
pub fn set_resource_id<S: BnStrCompatible>(&self, resource_id: S) {
let resource_id = resource_id.into_bytes_with_nul();
unsafe { BNSettingsSetResourceId(self.handle, resource_id.as_ref().as_ptr() as *mut _) };
}
pub fn serialize_schema(&self) -> BnString {
unsafe { BnString::from_raw(BNSettingsSerializeSchema(self.handle)) }
}
pub fn deserialize_schema<S: BnStrCompatible>(&self, schema: S) -> bool {
let schema = schema.into_bytes_with_nul();
unsafe {
BNSettingsDeserializeSchema(
self.handle,
schema.as_ref().as_ptr() as *mut _,
BNSettingsScope::SettingsAutoScope,
true,
)
}
}
pub fn contains<S: BnStrCompatible>(&self, key: S) -> bool {
let key = key.into_bytes_with_nul();
unsafe { BNSettingsContains(self.handle, key.as_ref().as_ptr() as *mut _) }
}
pub fn get_bool<S: BnStrCompatible>(
&self,
key: S,
view: Option<&BinaryView>,
scope: Option<Box<SettingsScope>>,
) -> bool {
let key = key.into_bytes_with_nul();
let view_handle = match view {
Some(view) => view.handle,
_ => ptr::null_mut() as *mut _,
};
let scope_ptr = match scope {
Some(mut scope) => scope.as_mut(),
_ => ptr::null_mut() as *mut _,
};
unsafe {
BNSettingsGetBool(
self.handle,
key.as_ref().as_ptr() as *mut _,
view_handle,
std::ptr::null_mut(),
scope_ptr,
)
}
}
pub fn get_double<S: BnStrCompatible>(
&self,
key: S,
view: Option<&BinaryView>,
scope: Option<Box<SettingsScope>>,
) -> f64 {
let key = key.into_bytes_with_nul();
let view_handle = match view {
Some(view) => view.handle,
_ => ptr::null_mut() as *mut _,
};
let scope_ptr = match scope {
Some(mut scope) => scope.as_mut(),
_ => ptr::null_mut() as *mut _,
};
unsafe {
BNSettingsGetDouble(
self.handle,
key.as_ref().as_ptr() as *mut _,
view_handle,
std::ptr::null_mut(),
scope_ptr,
)
}
}
pub fn get_integer<S: BnStrCompatible>(
&self,
key: S,
view: Option<&BinaryView>,
scope: Option<Box<SettingsScope>>,
) -> u64 {
let key = key.into_bytes_with_nul();
let view_handle = match view {
Some(view) => view.handle,
_ => ptr::null_mut() as *mut _,
};
let scope_ptr = match scope {
Some(mut scope) => scope.as_mut(),
_ => ptr::null_mut() as *mut _,
};
unsafe {
BNSettingsGetUInt64(
self.handle,
key.as_ref().as_ptr() as *mut _,
view_handle,
std::ptr::null_mut(),
scope_ptr,
)
}
}
pub fn get_string<S: BnStrCompatible>(
&self,
key: S,
view: Option<&BinaryView>,
scope: Option<Box<SettingsScope>>,
) -> BnString {
let key = key.into_bytes_with_nul();
let view_handle = match view {
Some(view) => view.handle,
_ => ptr::null_mut() as *mut _,
};
let scope_ptr = match scope {
Some(mut scope) => scope.as_mut(),
_ => ptr::null_mut() as *mut _,
};
unsafe {
BnString::from_raw(BNSettingsGetString(
self.handle,
key.as_ref().as_ptr() as *mut _,
view_handle,
std::ptr::null_mut(),
scope_ptr,
))
}
}
pub fn get_string_list<S: BnStrCompatible>(
&self,
key: S,
view: Option<&BinaryView>,
scope: Option<Box<SettingsScope>>,
) -> Array<BnString> {
let key = key.into_bytes_with_nul();
let view_handle = match view {
Some(view) => view.handle,
_ => ptr::null_mut() as *mut _,
};
let scope_ptr = match scope {
Some(mut scope) => scope.as_mut(),
_ => ptr::null_mut() as *mut _,
};
let mut size: usize = 0;
unsafe {
Array::new(
BNSettingsGetStringList(
self.handle,
key.as_ref().as_ptr() as *mut _,
view_handle,
std::ptr::null_mut(),
scope_ptr,
&mut size,
) as *mut *mut c_char,
size,
(),
)
}
}
pub fn get_json<S: BnStrCompatible>(
&self,
key: S,
view: Option<&BinaryView>,
scope: Option<Box<SettingsScope>>,
) -> BnString {
let key = key.into_bytes_with_nul();
let view_handle = match view {
Some(view) => view.handle,
_ => ptr::null_mut() as *mut _,
};
let scope_ptr = match scope {
Some(mut scope) => scope.as_mut(),
_ => ptr::null_mut() as *mut _,
};
unsafe {
BnString::from_raw(BNSettingsGetJson(
self.handle,
key.as_ref().as_ptr() as *mut _,
view_handle,
std::ptr::null_mut(),
scope_ptr,
))
}
}
pub fn set_bool<S: BnStrCompatible>(
&self,
key: S,
value: bool,
view: Option<&BinaryView>,
scope: Option<SettingsScope>,
) {
let key = key.into_bytes_with_nul();
let view_handle = match view {
Some(view) => view.handle,
_ => ptr::null_mut() as *mut _,
};
let scope = match scope {
Some(scope) => scope,
_ => SettingsScope::SettingsAutoScope,
};
unsafe {
BNSettingsSetBool(
self.handle,
view_handle,
std::ptr::null_mut(),
scope,
key.as_ref().as_ptr() as *mut _,
value,
);
}
}
pub fn set_double<S: BnStrCompatible>(
&self,
key: S,
value: f64,
view: Option<&BinaryView>,
scope: Option<SettingsScope>,
) {
let key = key.into_bytes_with_nul();
let view_handle = match view {
Some(view) => view.handle,
_ => ptr::null_mut() as *mut _,
};
let scope = match scope {
Some(scope) => scope,
_ => SettingsScope::SettingsAutoScope,
};
unsafe {
BNSettingsSetDouble(
self.handle,
view_handle,
std::ptr::null_mut(),
scope,
key.as_ref().as_ptr() as *mut _,
value,
);
}
}
pub fn set_integer<S: BnStrCompatible>(
&self,
key: S,
value: u64,
view: Option<&BinaryView>,
scope: Option<SettingsScope>,
) {
let key = key.into_bytes_with_nul();
let view_handle = match view {
Some(view) => view.handle,
_ => ptr::null_mut() as *mut _,
};
let scope = match scope {
Some(scope) => scope,
_ => SettingsScope::SettingsAutoScope,
};
unsafe {
BNSettingsSetUInt64(
self.handle,
view_handle,
std::ptr::null_mut(),
scope,
key.as_ref().as_ptr() as *mut _,
value,
);
}
}
pub fn set_string<S1: BnStrCompatible, S2: BnStrCompatible>(
&self,
key: S1,
value: S2,
view: Option<&BinaryView>,
scope: Option<SettingsScope>,
) {
let key = key.into_bytes_with_nul();
let value = value.into_bytes_with_nul();
let view_handle = match view {
Some(view) => view.handle,
_ => ptr::null_mut() as *mut _,
};
let scope = match scope {
Some(scope) => scope,
_ => SettingsScope::SettingsAutoScope,
};
unsafe {
BNSettingsSetString(
self.handle,
view_handle,
std::ptr::null_mut(),
scope,
key.as_ref().as_ptr() as *mut _,
value.as_ref().as_ptr() as *mut _,
);
}
}
pub fn set_string_list<S1: BnStrCompatible, S2: BnStrCompatible, I: Iterator<Item = S2>>(
&self,
key: S1,
value: I,
view: Option<&BinaryView>,
scope: Option<SettingsScope>,
) -> bool {
let key = key.into_bytes_with_nul();
let mut list: Vec<_> = value
.map(|s| s.into_bytes_with_nul().as_ref().as_ptr() as *const c_char)
.collect();
let view_handle = match view {
Some(view) => view.handle,
None => ptr::null_mut() as *mut _,
};
let scope = match scope {
Some(scope) => scope,
None => SettingsScope::SettingsAutoScope,
};
unsafe {
BNSettingsSetStringList(
self.handle,
view_handle,
std::ptr::null_mut(),
scope,
key.as_ref().as_ptr() as *mut _,
list.as_mut_ptr(),
list.len(),
)
}
}
pub fn set_json<S1: BnStrCompatible, S2: BnStrCompatible>(
&self,
key: S1,
value: S2,
view: Option<&BinaryView>,
scope: Option<SettingsScope>,
) -> bool {
let key = key.into_bytes_with_nul();
let value = value.into_bytes_with_nul();
let view_handle = match view {
Some(view) => view.handle,
None => ptr::null_mut() as *mut _,
};
let scope = match scope {
Some(scope) => scope,
None => SettingsScope::SettingsAutoScope,
};
unsafe {
BNSettingsSetJson(
self.handle,
view_handle,
std::ptr::null_mut(),
scope,
key.as_ref().as_ptr() as *mut _,
value.as_ref().as_ptr() as *mut _,
)
}
}
pub fn update_bool_property<S: BnStrCompatible>(&self, key: S, property: S, value: bool) {
let key = key.into_bytes_with_nul();
let property = property.into_bytes_with_nul();
unsafe {
BNSettingsUpdateBoolProperty(
self.handle,
key.as_ref().as_ptr() as *mut _,
property.as_ref().as_ptr() as *mut _,
value,
);
}
}
pub fn update_integer_property<S: BnStrCompatible>(&self, key: S, property: S, value: u64) {
let key = key.into_bytes_with_nul();
let property = property.into_bytes_with_nul();
unsafe {
BNSettingsUpdateUInt64Property(
self.handle,
key.as_ref().as_ptr() as *mut _,
property.as_ref().as_ptr() as *mut _,
value,
);
}
}
pub fn update_double_property<S: BnStrCompatible>(&self, key: S, property: S, value: f64) {
let key = key.into_bytes_with_nul();
let property = property.into_bytes_with_nul();
unsafe {
BNSettingsUpdateDoubleProperty(
self.handle,
key.as_ref().as_ptr() as *mut _,
property.as_ref().as_ptr() as *mut _,
value,
);
}
}
pub fn update_string_property<S: BnStrCompatible>(&self, key: S, property: S, value: S) {
let key = key.into_bytes_with_nul();
let property = property.into_bytes_with_nul();
let value = value.into_bytes_with_nul();
unsafe {
BNSettingsUpdateStringProperty(
self.handle,
key.as_ref().as_ptr() as *mut _,
property.as_ref().as_ptr() as *mut _,
value.as_ref().as_ptr() as *mut _,
);
}
}
pub fn update_string_list_property<S: BnStrCompatible, I: Iterator<Item = S>>(
&self,
key: S,
property: S,
value: I,
) {
let key = key.into_bytes_with_nul();
let property = property.into_bytes_with_nul();
let mut list: Vec<_> = value
.map(|s| s.into_bytes_with_nul().as_ref().as_ptr() as *const c_char)
.collect();
unsafe {
BNSettingsUpdateStringListProperty(
self.handle,
key.as_ref().as_ptr() as *mut _,
property.as_ref().as_ptr() as *mut _,
list.as_mut_ptr(),
list.len(),
);
}
}
pub fn register_group<S1: BnStrCompatible, S2: BnStrCompatible>(
&self,
group: S1,
title: S2,
) -> bool {
let group = group.into_bytes_with_nul();
let title = title.into_bytes_with_nul();
unsafe {
BNSettingsRegisterGroup(
self.handle,
group.as_ref().as_ptr() as *mut _,
title.as_ref().as_ptr() as *mut _,
)
}
}
pub fn register_setting_json<S1: BnStrCompatible, S2: BnStrCompatible>(
&self,
group: S1,
properties: S2,
) -> bool {
let group = group.into_bytes_with_nul();
let properties = properties.into_bytes_with_nul();
unsafe {
BNSettingsRegisterSetting(
self.handle,
group.as_ref().as_ptr() as *mut _,
properties.as_ref().as_ptr() as *mut _,
)
}
}
}
impl ToOwned for Settings {
type Owned = Ref<Self>;
fn to_owned(&self) -> Self::Owned {
unsafe { RefCountable::inc_ref(self) }
}
}
unsafe impl RefCountable for Settings {
unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
Ref::new(Self {
handle: BNNewSettingsReference(handle.handle),
})
}
unsafe fn dec_ref(handle: &Self) {
BNFreeSettings(handle.handle);
}
}