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