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
#![allow(warnings)]
#![allow(unaligned_references)]
include!("ffi/bindings.rs");
pub type SPXPROPERTYBAGHANDLE = AZAC_HANDLE;
pub type SPXHANDLE = AZAC_HANDLE;
pub type SPXHR = AZACHR;
use log::*;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Formatter;
use std::os::raw::c_char;
pub const NULL_C_STR_PTR: *const c_char = 0 as *const c_char;
#[derive(Debug)]
pub struct SmartHandle<T: Copy + Debug> {
inner: T,
release_fn: unsafe extern "C" fn(T) -> SPXHR,
name: &'static str,
}
impl<T: Copy + Debug> SmartHandle<T> {
#[inline(always)]
pub fn create(
name: &'static str,
handle: T,
release_fn: unsafe extern "C" fn(T) -> SPXHR,
) -> SmartHandle<T> {
let result = SmartHandle {
inner: handle,
release_fn,
name,
};
trace!("Create SmartHandle {}.", result);
return result;
}
#[inline(always)]
pub fn inner(&self) -> T {
self.inner
}
}
impl<T: Copy + Debug> Drop for SmartHandle<T> {
fn drop(&mut self) {
trace!("Drop SmartHandle {}.", self);
let hr = unsafe { (self.release_fn)(self.inner) };
if hr != SPX_NOERROR as usize {
panic!("cannot release SmartHandle {}, err={}", self, hr);
}
}
}
impl<T: Copy + Debug> Display for SmartHandle<T> {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
write!(f, "{}{{{:?}}}", self.name, self.inner)
}
}
unsafe impl<T: Copy + Debug> Send for SmartHandle<T> {}