1use cfg_if::cfg_if;
5
6use crate::ffi::{_efree, _emalloc, _estrdup};
7use std::{
8 alloc::Layout,
9 ffi::{CString, c_char, c_void},
10};
11
12#[must_use]
22pub fn emalloc(layout: Layout) -> *mut u8 {
23 let size = layout.size();
25
26 (unsafe {
27 cfg_if! {
28 if #[cfg(php_debug)] {
29 #[allow(clippy::used_underscore_items)]
30 _emalloc(size as _, std::ptr::null_mut(), 0, std::ptr::null_mut(), 0)
31 } else {
32 #[allow(clippy::used_underscore_items)]
33 _emalloc(size as _)
34 }
35 }
36 })
37 .cast::<u8>()
38}
39
40pub unsafe fn efree(ptr: *mut u8) {
52 cfg_if! {
53 if #[cfg(php_debug)] {
54 #[allow(clippy::used_underscore_items)]
55 unsafe {
56 _efree(
57 ptr.cast::<c_void>(),
58 std::ptr::null_mut(),
59 0,
60 std::ptr::null_mut(),
61 0,
62 );
63 }
64 } else {
65 #[allow(clippy::used_underscore_items)]
66 unsafe {
67 _efree(ptr.cast::<c_void>());
68 }
69 }
70 }
71}
72
73pub fn estrdup(string: impl Into<Vec<u8>>) -> *mut c_char {
84 let string = unsafe { CString::from_vec_unchecked(string.into()) }.into_raw();
85
86 let result = unsafe {
87 cfg_if! {
88 if #[cfg(php_debug)] {
89 #[allow(clippy::used_underscore_items)]
90 _estrdup(string, std::ptr::null_mut(), 0, std::ptr::null_mut(), 0)
91 } else {
92 #[allow(clippy::used_underscore_items)]
93 _estrdup(string)
94 }
95 }
96 };
97
98 drop(unsafe { CString::from_raw(string) });
99 result
100}
101
102#[cfg(test)]
103#[cfg(feature = "embed")]
104mod test {
105 use super::*;
106 use crate::embed::Embed;
107 use std::ffi::CStr;
108
109 #[test]
110 fn test_emalloc() {
111 Embed::run(|| {
112 let layout = Layout::from_size_align(16, 8).expect("should create layout");
113 let ptr = emalloc(layout);
114 assert!(!ptr.is_null());
115 unsafe { efree(ptr) };
116 });
117 }
118
119 #[test]
120 fn test_estrdup() {
121 Embed::run(|| {
122 let original = "Hello, world!";
123 let duplicated = estrdup(original);
124 assert!(!duplicated.is_null());
125
126 let duplicated_str = unsafe { CStr::from_ptr(duplicated) };
127 assert_eq!(
128 duplicated_str.to_str().expect("should convert to str"),
129 original
130 );
131
132 unsafe { efree(duplicated.cast::<u8>()) }
133 });
134 }
135}