syslog_ng_common/logmsg/
mod.rs1use syslog_ng_sys::{LogTagId, logmsg};
10use syslog_ng_sys::types::*;
11
12use std::collections::BTreeMap;
13use std::str;
14use std::mem;
15use std::slice::from_raw_parts;
16use std::ffi::{CStr, CString};
17
18#[cfg(test)]
19mod test;
20
21pub struct NVHandle(logmsg::NVHandle);
22pub struct LogMessage(*mut logmsg::LogMessage);
23
24impl Drop for LogMessage {
25 fn drop(&mut self) {
26 unsafe { logmsg::log_msg_unref(self.0) }
27 }
28}
29
30unsafe impl Send for LogMessage {}
31
32impl Clone for LogMessage {
33 fn clone(&self) -> LogMessage {
34 LogMessage::wrap_raw(self.0)
35 }
36}
37
38impl LogMessage {
39 pub fn new() -> LogMessage {
40 unsafe {
41 let msg = logmsg::log_msg_new_empty();
42 assert!(msg != ::std::ptr::null_mut());
43 LogMessage(msg)
44 }
45 }
46
47 pub fn wrap_raw(raw: *mut ::sys::LogMessage) -> LogMessage {
48 let referenced = unsafe {logmsg::log_msg_ref(raw)};
49 LogMessage(referenced)
50 }
51
52 pub fn into_raw(self) -> *mut ::sys::LogMessage {
53 unsafe {logmsg::log_msg_ref(self.0)}
56 }
57
58 unsafe fn c_char_to_str<'a>(value: *const c_char, len: ssize_t) -> &'a str {
59 let slce = from_raw_parts(value, len as usize);
60 str::from_utf8(mem::transmute(slce)).unwrap()
61 }
62
63 pub fn get_value_handle(value_name: &str) -> NVHandle {
64 unsafe {
65 let name = CString::new(value_name).unwrap();
66 NVHandle(logmsg::log_msg_get_value_handle(name.as_ptr()))
67 }
68 }
69
70 pub fn get<K: Into<NVHandle>>(&self, key: K) -> &str {
71 let handle = key.into();
72 unsafe {
73 let mut size: ssize_t = 0;
74 let value = logmsg::__log_msg_get_value(self.0, handle.0, &mut size);
75 LogMessage::c_char_to_str(value, size)
76 }
77 }
78
79 pub fn insert<K: Into<NVHandle>>(&mut self, key: K, value: &str) {
80 let handle = key.into();
81 unsafe {
82 logmsg::log_msg_set_value(self.0, handle.0, value.as_ptr() as *const i8, value.len() as isize);
83 }
84 }
85
86 pub fn set_tag(&mut self, tag: &str) {
87 unsafe {
88 let c_tag = CString::new(tag).unwrap();
89 logmsg::log_msg_set_tag_by_name(self.0, c_tag.as_ptr());
90 }
91 }
92
93 pub fn values(&self) -> BTreeMap<String, String> {
94 let mut values = BTreeMap::new();
95 unsafe {
96 let user_data = mem::transmute::<&mut BTreeMap<String, String>,
97 *mut c_void>(&mut values);
98 logmsg::log_msg_values_foreach(self.0, insert_kvpair_to_map, user_data);
99 }
100 values
101 }
102
103 pub fn tags(&self) -> Vec<String> {
104 let mut tags = Vec::new();
105 unsafe {
106 let user_data = mem::transmute::<&mut Vec<String>, *mut c_void>(&mut tags);
107 logmsg::log_msg_tags_foreach(self.0, insert_tag_to_vec, user_data);
108 }
109 tags
110 }
111}
112
113fn c_char_to_string(value: *const c_char) -> String {
114 let bytes = unsafe { CStr::from_ptr(value).to_bytes() };
115 let str_slice: &str = str::from_utf8(bytes).unwrap();
116 str_slice.to_owned()
117}
118
119extern "C" fn insert_tag_to_vec(_: *const logmsg::LogMessage,
120 _: LogTagId,
121 name: *const c_char,
122 user_data: *mut c_void)
123 -> bool {
124 unsafe {
125 let name = c_char_to_string(name);
126 let mut vec: &mut Vec<String> = mem::transmute(user_data);
127 vec.push(name);
128 }
129 false
130}
131
132extern "C" fn insert_kvpair_to_map(_: logmsg::NVHandle,
133 name: *const c_char,
134 value: *const c_char,
135 value_len: ssize_t,
136 user_data: *mut c_void)
137 -> bool {
138 unsafe {
139 let name = c_char_to_string(name);
140 let value = LogMessage::c_char_to_str(value, value_len).to_string();
141 let mut map: &mut BTreeMap<String, String> = mem::transmute(user_data);
142 map.insert(name, value);
143 }
144 false
145}
146
147impl<'a> Into<NVHandle> for &'a str {
148 fn into(self) -> NVHandle {
149 let name = CString::new(self).unwrap();
150 let handle = unsafe { logmsg::log_msg_get_value_handle(name.as_ptr()) };
151 NVHandle(handle)
152 }
153}