Skip to content

Commit 2c26dd6

Browse files
rbranemesare
authored andcommitted
impl rust Collaboration and Remote API
1 parent ddad2bb commit 2c26dd6

File tree

14 files changed

+4932
-0
lines changed

14 files changed

+4932
-0
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
use core::{ffi, mem, ptr};
2+
3+
use binaryninjacore_sys::*;
4+
5+
use super::{RemoteFile, User};
6+
7+
use crate::database::Database;
8+
use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner};
9+
use crate::string::{BnStrCompatible, BnString};
10+
11+
/// Class representing a collection of snapshots in a local database
12+
#[repr(transparent)]
13+
pub struct Changeset {
14+
handle: ptr::NonNull<BNCollaborationChangeset>,
15+
}
16+
17+
impl Drop for Changeset {
18+
fn drop(&mut self) {
19+
unsafe { BNFreeCollaborationChangeset(self.as_raw()) }
20+
}
21+
}
22+
23+
impl Clone for Changeset {
24+
fn clone(&self) -> Self {
25+
unsafe {
26+
Self::from_raw(
27+
ptr::NonNull::new(BNNewCollaborationChangesetReference(self.as_raw())).unwrap(),
28+
)
29+
}
30+
}
31+
}
32+
33+
impl Changeset {
34+
pub(crate) unsafe fn from_raw(handle: ptr::NonNull<BNCollaborationChangeset>) -> Self {
35+
Self { handle }
36+
}
37+
38+
pub(crate) unsafe fn ref_from_raw(handle: &*mut BNCollaborationChangeset) -> &Self {
39+
assert!(!handle.is_null());
40+
mem::transmute(handle)
41+
}
42+
43+
#[allow(clippy::mut_from_ref)]
44+
pub(crate) unsafe fn as_raw(&self) -> &mut BNCollaborationChangeset {
45+
&mut *self.handle.as_ptr()
46+
}
47+
48+
/// Owning database for snapshots
49+
pub fn database(&self) -> Result<Database, ()> {
50+
let result = unsafe { BNCollaborationChangesetGetDatabase(self.as_raw()) };
51+
let raw = ptr::NonNull::new(result).ok_or(())?;
52+
Ok(unsafe { Database::from_raw(raw) })
53+
}
54+
55+
/// Relevant remote File object
56+
pub fn file(&self) -> Result<RemoteFile, ()> {
57+
let result = unsafe { BNCollaborationChangesetGetFile(self.as_raw()) };
58+
ptr::NonNull::new(result)
59+
.map(|raw| unsafe { RemoteFile::from_raw(raw) })
60+
.ok_or(())
61+
}
62+
63+
/// List of snapshot ids in the database
64+
pub fn snapshot_ids(&self) -> Result<Array<SnapshotId>, ()> {
65+
let mut count = 0;
66+
let result = unsafe { BNCollaborationChangesetGetSnapshotIds(self.as_raw(), &mut count) };
67+
(!result.is_null())
68+
.then(|| unsafe { Array::new(result, count, ()) })
69+
.ok_or(())
70+
}
71+
72+
/// Relevant remote author User
73+
pub fn author(&self) -> Result<User, ()> {
74+
let result = unsafe { BNCollaborationChangesetGetAuthor(self.as_raw()) };
75+
ptr::NonNull::new(result)
76+
.map(|raw| unsafe { User::from_raw(raw) })
77+
.ok_or(())
78+
}
79+
80+
/// Changeset name
81+
pub fn name(&self) -> BnString {
82+
let result = unsafe { BNCollaborationChangesetGetName(self.as_raw()) };
83+
assert!(!result.is_null());
84+
unsafe { BnString::from_raw(result) }
85+
}
86+
87+
/// Set the name of the changeset, e.g. in a name changeset function.
88+
pub fn set_name<S: BnStrCompatible>(&self, value: S) -> bool {
89+
let value = value.into_bytes_with_nul();
90+
unsafe {
91+
BNCollaborationChangesetSetName(
92+
self.as_raw(),
93+
value.as_ref().as_ptr() as *const ffi::c_char,
94+
)
95+
}
96+
}
97+
}
98+
99+
impl CoreArrayProvider for Changeset {
100+
type Raw = *mut BNCollaborationChangeset;
101+
type Context = ();
102+
type Wrapped<'a> = &'a Self;
103+
}
104+
105+
unsafe impl CoreArrayProviderInner for Changeset {
106+
unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
107+
BNFreeCollaborationChangesetList(raw, count)
108+
}
109+
110+
unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
111+
Self::ref_from_raw(raw)
112+
}
113+
}
114+
115+
pub struct SnapshotId;
116+
impl CoreArrayProvider for SnapshotId {
117+
type Raw = i64;
118+
type Context = ();
119+
type Wrapped<'a> = i64;
120+
}
121+
122+
unsafe impl CoreArrayProviderInner for SnapshotId {
123+
unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
124+
BNCollaborationFreeSnapshotIdList(raw, count)
125+
}
126+
127+
unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
128+
*raw
129+
}
130+
}

0 commit comments

Comments
 (0)