binaryninja/types/
enumeration.rs1use crate::rc::{Ref, RefCountable};
2use crate::string::{raw_to_string, BnString, IntoCStr};
3use binaryninjacore_sys::*;
4use std::fmt::{Debug, Formatter};
5
6#[derive(PartialEq, Eq, Hash)]
7pub struct EnumerationBuilder {
8 pub(crate) handle: *mut BNEnumerationBuilder,
9}
10
11impl EnumerationBuilder {
12 pub fn new() -> Self {
13 Self {
14 handle: unsafe { BNCreateEnumerationBuilder() },
15 }
16 }
17
18 pub(crate) unsafe fn from_raw(handle: *mut BNEnumerationBuilder) -> Self {
19 Self { handle }
20 }
21
22 pub fn finalize(&self) -> Ref<Enumeration> {
23 unsafe { Enumeration::ref_from_raw(BNFinalizeEnumerationBuilder(self.handle)) }
24 }
25
26 pub fn append(&mut self, name: &str) -> &mut Self {
27 let name = name.to_cstr();
28 unsafe {
29 BNAddEnumerationBuilderMember(self.handle, name.as_ref().as_ptr() as _);
30 }
31 self
32 }
33
34 pub fn insert(&mut self, name: &str, value: u64) -> &mut Self {
35 let name = name.to_cstr();
36 unsafe {
37 BNAddEnumerationBuilderMemberWithValue(self.handle, name.as_ref().as_ptr() as _, value);
38 }
39 self
40 }
41
42 pub fn replace(&mut self, id: usize, name: &str, value: u64) -> &mut Self {
43 let name = name.to_cstr();
44 unsafe {
45 BNReplaceEnumerationBuilderMember(self.handle, id, name.as_ref().as_ptr() as _, value);
46 }
47 self
48 }
49
50 pub fn remove(&mut self, id: usize) -> &mut Self {
51 unsafe {
52 BNRemoveEnumerationBuilderMember(self.handle, id);
53 }
54
55 self
56 }
57
58 pub fn members(&self) -> Vec<EnumerationMember> {
59 unsafe {
60 let mut count = 0;
61 let members_raw_ptr = BNGetEnumerationBuilderMembers(self.handle, &mut count);
62 let members_raw: &[BNEnumerationMember] =
63 std::slice::from_raw_parts(members_raw_ptr, count);
64 let members = members_raw
65 .iter()
66 .map(EnumerationMember::from_raw)
67 .collect();
68 BNFreeEnumerationMemberList(members_raw_ptr, count);
69 members
70 }
71 }
72}
73
74impl Default for EnumerationBuilder {
75 fn default() -> Self {
76 Self::new()
77 }
78}
79
80impl From<&Enumeration> for EnumerationBuilder {
81 fn from(enumeration: &Enumeration) -> Self {
82 unsafe {
83 Self::from_raw(BNCreateEnumerationBuilderFromEnumeration(
84 enumeration.handle,
85 ))
86 }
87 }
88}
89
90impl Drop for EnumerationBuilder {
91 fn drop(&mut self) {
92 unsafe { BNFreeEnumerationBuilder(self.handle) };
93 }
94}
95
96#[derive(PartialEq, Eq, Hash)]
97pub struct Enumeration {
98 pub(crate) handle: *mut BNEnumeration,
99}
100
101impl Enumeration {
102 pub(crate) unsafe fn ref_from_raw(handle: *mut BNEnumeration) -> Ref<Self> {
103 debug_assert!(!handle.is_null());
104 Ref::new(Self { handle })
105 }
106
107 pub fn builder() -> EnumerationBuilder {
108 EnumerationBuilder::new()
109 }
110
111 pub fn members(&self) -> Vec<EnumerationMember> {
112 unsafe {
113 let mut count = 0;
114 let members_raw_ptr = BNGetEnumerationMembers(self.handle, &mut count);
115 debug_assert!(!members_raw_ptr.is_null());
116 let members_raw: &[BNEnumerationMember] =
117 std::slice::from_raw_parts(members_raw_ptr, count);
118 let members = members_raw
119 .iter()
120 .map(EnumerationMember::from_raw)
121 .collect();
122 BNFreeEnumerationMemberList(members_raw_ptr, count);
123 members
124 }
125 }
126}
127
128impl Debug for Enumeration {
129 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
130 f.debug_struct("Enumeration")
131 .field("members", &self.members())
132 .finish()
133 }
134}
135
136unsafe impl RefCountable for Enumeration {
137 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
138 Self::ref_from_raw(BNNewEnumerationReference(handle.handle))
139 }
140
141 unsafe fn dec_ref(handle: &Self) {
142 BNFreeEnumeration(handle.handle);
143 }
144}
145
146impl ToOwned for Enumeration {
147 type Owned = Ref<Self>;
148
149 fn to_owned(&self) -> Self::Owned {
150 unsafe { RefCountable::inc_ref(self) }
151 }
152}
153
154#[derive(Debug, Clone, Hash, PartialEq, Eq)]
155pub struct EnumerationMember {
156 pub name: String,
157 pub value: u64,
159 pub default: bool,
161}
162
163impl EnumerationMember {
164 pub(crate) fn from_raw(value: &BNEnumerationMember) -> Self {
165 Self {
166 name: raw_to_string(value.name).unwrap(),
167 value: value.value,
168 default: value.isDefault,
169 }
170 }
171
172 #[allow(unused)]
173 pub(crate) fn from_owned_raw(value: BNEnumerationMember) -> Self {
174 let owned = Self::from_raw(&value);
175 Self::free_raw(value);
176 owned
177 }
178
179 #[allow(unused)]
180 pub(crate) fn into_raw(value: Self) -> BNEnumerationMember {
181 let bn_name = BnString::new(value.name);
182 BNEnumerationMember {
183 name: BnString::into_raw(bn_name),
184 value: value.value,
185 isDefault: value.default,
186 }
187 }
188
189 #[allow(unused)]
190 pub(crate) fn free_raw(value: BNEnumerationMember) {
191 unsafe { BnString::free_raw(value.name) };
192 }
193
194 pub fn new(name: String, value: u64, default: bool) -> Self {
195 Self {
196 name,
197 value,
198 default,
199 }
200 }
201}