binaryninja/
repository.rs1mod manager;
4mod plugin;
5
6use std::ffi::c_char;
7use std::fmt::Debug;
8use std::path::{Path, PathBuf};
9use std::ptr::NonNull;
10
11use binaryninjacore_sys::*;
12
13use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable};
14use crate::repository::plugin::RepositoryPlugin;
15use crate::string::{BnString, IntoCStr};
16
17pub use manager::RepositoryManager;
18
19pub type PluginType = BNPluginType;
20pub type PluginStatus = BNPluginStatus;
21
22#[repr(transparent)]
23pub struct Repository {
24 handle: NonNull<BNRepository>,
25}
26
27impl Repository {
28 pub(crate) unsafe fn from_raw(handle: NonNull<BNRepository>) -> Self {
29 Self { handle }
30 }
31
32 pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNRepository>) -> Ref<Self> {
33 Ref::new(Self { handle })
34 }
35
36 pub fn url(&self) -> String {
38 let result = unsafe { BNRepositoryGetUrl(self.handle.as_ptr()) };
39 assert!(!result.is_null());
40 unsafe { BnString::into_string(result as *mut c_char) }
41 }
42
43 pub fn path(&self) -> PathBuf {
45 let result = unsafe { BNRepositoryGetRepoPath(self.handle.as_ptr()) };
46 assert!(!result.is_null());
47 let result_str = unsafe { BnString::into_string(result as *mut c_char) };
48 PathBuf::from(result_str)
49 }
50
51 pub fn plugins(&self) -> Array<RepositoryPlugin> {
53 let mut count = 0;
54 let result = unsafe { BNRepositoryGetPlugins(self.handle.as_ptr(), &mut count) };
55 assert!(!result.is_null());
56 unsafe { Array::new(result, count, ()) }
57 }
58
59 pub fn plugin_by_path(&self, path: &Path) -> Option<Ref<RepositoryPlugin>> {
60 let path = path.to_cstr();
61 let result = unsafe { BNRepositoryGetPluginByPath(self.handle.as_ptr(), path.as_ptr()) };
62 NonNull::new(result).map(|h| unsafe { RepositoryPlugin::ref_from_raw(h) })
63 }
64
65 pub fn full_path(&self) -> PathBuf {
67 let result = unsafe { BNRepositoryGetPluginsPath(self.handle.as_ptr()) };
68 assert!(!result.is_null());
69 let result_str = unsafe { BnString::into_string(result as *mut c_char) };
70 PathBuf::from(result_str)
71 }
72}
73
74impl Debug for Repository {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 f.debug_struct("Repository")
77 .field("url", &self.url())
78 .field("path", &self.path())
79 .field("full_path", &self.full_path())
80 .field("plugins", &self.plugins().to_vec())
81 .finish()
82 }
83}
84
85impl ToOwned for Repository {
86 type Owned = Ref<Self>;
87
88 fn to_owned(&self) -> Self::Owned {
89 unsafe { <Self as RefCountable>::inc_ref(self) }
90 }
91}
92
93unsafe impl RefCountable for Repository {
94 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
95 Self::ref_from_raw(NonNull::new(BNNewRepositoryReference(handle.handle.as_ptr())).unwrap())
96 }
97
98 unsafe fn dec_ref(handle: &Self) {
99 BNFreeRepository(handle.handle.as_ptr())
100 }
101}
102
103impl CoreArrayProvider for Repository {
104 type Raw = *mut BNRepository;
105 type Context = ();
106 type Wrapped<'a> = Guard<'a, Self>;
107}
108
109unsafe impl CoreArrayProviderInner for Repository {
110 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
111 BNFreeRepositoryManagerRepositoriesList(raw)
112 }
113
114 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
115 Guard::new(Self::from_raw(NonNull::new(*raw).unwrap()), context)
116 }
117}
118
119impl CoreArrayProvider for PluginType {
120 type Raw = BNPluginType;
121 type Context = ();
122 type Wrapped<'a> = Self;
123}
124
125unsafe impl CoreArrayProviderInner for PluginType {
126 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
127 BNFreePluginTypes(raw)
128 }
129
130 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
131 *raw
132 }
133}