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
use crate::LogLevel;
use std::ffi::CString;
use std::os::raw::c_char;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
pub type LogCallback = unsafe extern "C" fn(i32, *const c_char, *const c_char);
pub struct LogAdapterState {
stop: Arc<AtomicBool>,
}
struct Logger {
callback: LogCallback,
stop: Arc<AtomicBool>,
}
impl log::Log for Logger {
fn enabled(&self, _metadata: &log::Metadata<'_>) -> bool {
!self.stop.load(Ordering::SeqCst)
}
fn flush(&self) {}
fn log(&self, record: &log::Record<'_>) {
if self.stop.load(Ordering::SeqCst) {
return;
}
let tag = record
.module_path()
.and_then(|mp| CString::new(mp.as_bytes()).ok());
let msg_string = format!("{}", record.args());
let level = LogLevel::from_level_and_message(record.level(), &msg_string);
let msg_cstring = crate::string_to_cstring_lossy(msg_string);
let tag_ptr = tag
.as_ref()
.map(|s| s.as_ptr())
.unwrap_or_else(std::ptr::null);
let msg_ptr = msg_cstring.as_ptr() as *const c_char;
unsafe { (self.callback)(level as i32, tag_ptr, msg_ptr) };
}
}
impl LogAdapterState {
pub fn init(callback: LogCallback) -> Self {
let stop = Arc::new(AtomicBool::new(false));
let log = Logger {
callback,
stop: stop.clone(),
};
crate::settable_log::set_logger(Box::new(log));
log::set_max_level(log::LevelFilter::Debug);
log::info!("rc_log adapter initialized!");
Self { stop }
}
}
impl Drop for LogAdapterState {
fn drop(&mut self) {
self.stop.store(true, Ordering::SeqCst);
}
}
ffi_support::implement_into_ffi_by_pointer!(LogAdapterState);