janus_plugin/
utils.rs

1/// Wrapper types and helpers for working with the Janus FFI layer.
2
3use glib_sys as glib;
4use libc;
5use serde::ser::{self, Serialize, Serializer};
6use std::ffi::CStr;
7use std::ops::Deref;
8use std::os::raw::c_char;
9
10/// A C-style string which was allocated using glibc. Derefs to a `CStr`.
11#[derive(Debug)]
12pub struct GLibString {
13    ptr: *const CStr,
14}
15
16impl GLibString {
17    /// Creates a `GLibString` from a glibc-allocated pointer to a C-style string.
18    pub unsafe fn from_chars(chars: *const c_char) -> Option<Self> {
19        chars.as_ref().map(|c| Self { ptr: CStr::from_ptr(c) })
20    }
21}
22
23impl Deref for GLibString {
24    type Target = CStr;
25
26    fn deref(&self) -> &CStr {
27        unsafe { &*self.ptr }
28    }
29}
30
31impl Drop for GLibString {
32    fn drop(&mut self) {
33        unsafe { glib::g_free(self.ptr as *mut _) }
34    }
35}
36
37impl Serialize for GLibString {
38    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
39        match self.to_str() {
40            Ok(s) => serializer.serialize_str(s),
41            Err(e) => Err(ser::Error::custom(e))
42        }
43    }
44}
45
46unsafe impl Send for GLibString {}
47unsafe impl Sync for GLibString {}
48
49/// A C-style string which was allocated using libc. Derefs to a `CStr`.
50#[derive(Debug)]
51pub struct LibcString {
52    ptr: *const CStr,
53}
54
55impl LibcString {
56    /// Creates a `LibcString` from a libc-allocated pointer to a C-style string.
57    pub unsafe fn from_chars(chars: *const c_char) -> Option<Self> {
58        chars.as_ref().map(|c| Self { ptr: CStr::from_ptr(c) })
59    }
60}
61
62impl Deref for LibcString {
63    type Target = CStr;
64
65    fn deref(&self) -> &CStr {
66        unsafe { &*self.ptr }
67    }
68}
69
70impl Drop for LibcString {
71    fn drop(&mut self) {
72        unsafe { libc::free(self.ptr as *mut _) }
73    }
74}
75
76impl Serialize for LibcString {
77    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
78        match self.to_str() {
79            Ok(s) => serializer.serialize_str(s),
80            Err(e) => Err(ser::Error::custom(e))
81        }
82    }
83}
84
85unsafe impl Send for LibcString {}
86unsafe impl Sync for LibcString {}