blob: 700ae134f48dbf476b6b96c54ae115b750c64e3a (
plain) (
blame)
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
|
use std::ffi::CStr;
use std::os::raw::c_char;
use crate::*;
/// Conversion from [`CStr`] to [`ConstLtPtr`].
impl AsLtPtr for CStr {
/// The target type of this conversion.
type Target = c_char;
/// Returns the inner pointer to this C string.
///
/// The returned pointer points to a contiguous region of memory terminated
/// with a 0 byte to represent the end of the string.
///
/// # Examples
///
/// `ltptr` protects you from dangling pointers: (adapted from
/// [`CStr::as_ptr`])
///
/// ```rust compile_fail
/// use std::ffi::CString;
/// use ltptr::AsLtPtr;
///
/// let ptr = CString::new("Hello").unwrap().as_lt_ptr();
/// unsafe {
/// // would be dangling but the compiler prevents this from compiling
/// ptr.as_raw();
/// }
/// ```
///
/// Which you can fix by adding a binding:
///
/// ```rust
/// use std::ffi::CString;
/// use ltptr::AsLtPtr;
///
/// let hello = CString::new("Hello").unwrap();
/// let ptr = hello.as_lt_ptr();
/// unsafe {
/// // perfectly fine
/// ptr.as_raw();
/// }
/// ```
#[inline]
fn as_lt_ptr(&self) -> ConstLtPtr<'_, c_char> {
unsafe { ConstLtPtr::from_raw(self.as_ptr()) }
}
}
/// Conversion from [`ConstLtPtr`] of [`c_char`] to [`CStr`].
impl FromLtPtr<c_char> for CStr {
/// Wraps a raw C string with a safe C string wrapper.
///
/// # Safety
///
/// See [`CStr::from_ptr`] for the safety requirements.
///
/// # Examples
///
/// ```rust
/// use std::ffi::CStr;
/// use std::ffi::CString;
/// use std::os::raw::c_char;
/// use ltptr::AsLtPtr;
/// use ltptr::ConstLtPtr;
/// use ltptr::FromLtPtr;
///
/// unsafe fn foo(ptr: ConstLtPtr<'_, c_char>) {
/// let first = unsafe { CStr::from_lt_ptr(ptr) }.to_str().to_owned();
/// }
///
/// let hello = CString::new("Hello").unwrap();
/// let ptr = hello.as_lt_ptr();
/// unsafe { foo(ptr) };
/// ```
#[inline]
unsafe fn from_lt_ptr(ptr: ConstLtPtr<'_, c_char>) -> &CStr {
unsafe { CStr::from_ptr(ptr.as_raw()) }
}
}
|