Skip to content

Commit b9aa4f2

Browse files
committed
Pass the ini api.
1 parent cc66842 commit b9aa4f2

File tree

3 files changed

+158
-39
lines changed

3 files changed

+158
-39
lines changed

examples/hello/src/lib.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -137,27 +137,26 @@ fn test_func() {}
137137

138138
#[no_mangle]
139139
pub extern "C" fn get_module() -> *const ::phper::sys::zend_module_entry {
140-
// static module: Lazy<Module> = Lazy::new(|| {
141-
// let mut module = Module::new(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
142-
// module
143-
// });
144-
// unsafe {
145-
// module.create_zend_module_entry()
146-
// }
147-
148140
let f = |module: &mut Module| {
149141
module.set_name(env!("CARGO_PKG_NAME"));
150142
module.set_version(env!("CARGO_PKG_VERSION"));
151143

152-
module.add_ini("hello.enable", "off", Policy::All);
144+
module.add_bool_ini("hello.enable", false, Policy::All);
145+
module.add_long_ini("hello.len", 100, Policy::All);
146+
module.add_real_ini("hello.ratio", 1.5, Policy::All);
147+
module.add_str_ini("hello.description", "empty", Policy::All);
153148

154149
module.on_module_init(module_init);
155150
module.on_module_shutdown(module_shutdown);
156151
module.on_request_init(request_init);
157152
module.on_request_shutdown(request_shutdown);
158153

159154
module.add_function("hello_fuck", || {
160-
println!("Fuck you!");
155+
let hello_enable = Module::get_bool_ini("hello.enable");
156+
dbg!(hello_enable);
157+
158+
let hello_description = Module::get_str_ini("hello.description");
159+
dbg!(hello_description);
161160
});
162161
module.add_function("test_func", test_func);
163162

phper/src/ini.rs

Lines changed: 81 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::sys::{
22
zend_ini_entry, zend_ini_entry_def, zend_string, OnUpdateString, PHP_INI_ALL, PHP_INI_PERDIR,
3-
PHP_INI_SYSTEM, PHP_INI_USER,
3+
PHP_INI_SYSTEM, PHP_INI_USER, OnUpdateBool, OnUpdateLong, OnUpdateReal,
44
};
55
use std::{
66
cell::Cell,
@@ -9,6 +9,20 @@ use std::{
99
ptr::null_mut,
1010
sync::atomic::AtomicPtr,
1111
};
12+
use std::os::raw::c_char;
13+
use std::ffi::CStr;
14+
use std::str;
15+
16+
type OnModify = Option<
17+
unsafe extern "C" fn(
18+
*mut zend_ini_entry,
19+
*mut zend_string,
20+
*mut c_void,
21+
*mut c_void,
22+
*mut c_void,
23+
c_int,
24+
) -> c_int,
25+
>;
1226

1327
#[repr(u32)]
1428
#[derive(Copy, Clone)]
@@ -19,50 +33,96 @@ pub enum Policy {
1933
System = PHP_INI_SYSTEM,
2034
}
2135

22-
pub(crate) struct IniEntity {
36+
pub(crate) struct StrPtrBox {
37+
inner: Box<*mut c_char>,
38+
}
39+
40+
impl StrPtrBox {
41+
pub(crate) unsafe fn to_string(&self) -> Result<String, str::Utf8Error> {
42+
Ok(CStr::from_ptr(*self.inner).to_str()?.to_string() )
43+
}
44+
}
45+
46+
impl Default for StrPtrBox {
47+
fn default() -> Self {
48+
Self {
49+
inner: Box::new(null_mut()),
50+
}
51+
}
52+
}
53+
54+
pub trait IniValue: Default {
55+
fn on_modify() -> OnModify;
56+
57+
fn arg2(&mut self) -> *mut c_void {
58+
&mut *self as *mut _ as *mut c_void
59+
}
60+
}
61+
62+
impl IniValue for bool {
63+
fn on_modify() -> OnModify {
64+
Some(OnUpdateBool)
65+
}
66+
}
67+
68+
impl IniValue for i64 {
69+
fn on_modify() -> OnModify {
70+
Some(OnUpdateLong)
71+
}
72+
}
73+
74+
impl IniValue for f64 {
75+
fn on_modify() -> OnModify {
76+
Some(OnUpdateReal)
77+
}
78+
}
79+
80+
impl IniValue for StrPtrBox {
81+
fn on_modify() -> OnModify {
82+
Some(OnUpdateString)
83+
}
84+
85+
fn arg2(&mut self) -> *mut c_void {
86+
Box::as_mut(&mut self.inner) as *mut _ as *mut c_void
87+
}
88+
}
89+
90+
pub(crate) struct IniEntity<T: IniValue> {
2391
name: String,
24-
value: usize,
92+
value: T,
2593
default_value: String,
2694
policy: Policy,
2795
}
2896

29-
impl IniEntity {
97+
impl<T: IniValue> IniEntity<T> {
3098
pub(crate) fn new(name: impl ToString, default_value: impl ToString, policy: Policy) -> Self {
3199
Self {
32100
name: name.to_string(),
33-
value: 0,
101+
value: Default::default(),
34102
default_value: default_value.to_string(),
35103
policy,
36104
}
37105
}
38106

39-
// TODO Pass the logic of multi type item.
40-
pub(crate) fn ini_entry_def(&self) -> zend_ini_entry_def {
41-
let arg2: Box<*mut c_void> = Box::new(null_mut());
42-
let arg2 = Box::into_raw(arg2);
107+
pub(crate) fn value(&self) -> &T {
108+
&self.value
109+
}
110+
111+
pub(crate) unsafe fn ini_entry_def(&mut self) -> zend_ini_entry_def {
43112
create_ini_entry_ex(
44113
&self.name,
45114
&self.default_value,
46-
Some(OnUpdateString),
115+
<T>::on_modify(),
47116
self.policy as u32,
48-
arg2.cast(),
117+
self.value.arg2(),
49118
)
50119
}
51120
}
52121

53122
pub(crate) fn create_ini_entry_ex(
54123
name: &str,
55124
default_value: &str,
56-
on_modify: Option<
57-
unsafe extern "C" fn(
58-
*mut zend_ini_entry,
59-
*mut zend_string,
60-
*mut c_void,
61-
*mut c_void,
62-
*mut c_void,
63-
c_int,
64-
) -> c_int,
65-
>,
125+
on_modify: OnModify,
66126
modifiable: u32,
67127
arg2: *mut c_void,
68128
) -> zend_ini_entry_def {

phper/src/modules.rs

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::{
66
zend_class_entry, zend_function_entry, zend_ini_entry_def, zend_internal_arg_info,
77
zend_module_entry, zend_register_ini_entries, zend_string, zend_unregister_ini_entries,
88
PHP_MODULE_BUILD_ID, USING_ZTS, ZEND_DEBUG, ZEND_MODULE_API_NO,
9+
OnUpdateBool, OnUpdateLong, OnUpdateReal, OnUpdateString,
910
},
1011
};
1112
use once_cell::sync::Lazy;
@@ -19,6 +20,9 @@ use std::{
1920
ptr::{null, null_mut},
2021
sync::{atomic::AtomicPtr, Arc, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard},
2122
};
23+
use std::ffi::CStr;
24+
use crate::ini::{StrPtrBox, IniValue};
25+
use std::thread::LocalKey;
2226

2327
static GLOBAL_MODULE: Lazy<RwLock<Module>> = Lazy::new(Default::default);
2428

@@ -79,12 +83,18 @@ pub struct Module {
7983
module_shutdown: Option<Box<dyn Fn(ModuleArgs) -> bool + Send + Sync>>,
8084
request_init: Option<Box<dyn Fn(ModuleArgs) -> bool + Send + Sync>>,
8185
request_shutdown: Option<Box<dyn Fn(ModuleArgs) -> bool + Send + Sync>>,
82-
ini_entities: HashMap<String, IniEntity>,
8386
function_entities: Vec<FunctionEntity>,
8487
class_entities: Vec<ClassEntity>,
8588
}
8689

8790
impl Module {
91+
thread_local! {
92+
static BOOL_INI_ENTITIES: RefCell<HashMap<String, IniEntity<bool>>> = Default::default();
93+
static LONG_INI_ENTITIES: RefCell<HashMap<String, IniEntity<i64>>> = Default::default();
94+
static REAL_INI_ENTITIES: RefCell<HashMap<String, IniEntity<f64>>> = Default::default();
95+
static STR_INI_ENTITIES: RefCell<HashMap<String, IniEntity<StrPtrBox>>> = Default::default();
96+
}
97+
8898
pub fn set_name(&mut self, name: impl ToString) {
8999
let mut name = name.to_string();
90100
name.push('\0');
@@ -119,9 +129,52 @@ impl Module {
119129
self.request_shutdown = Some(Box::new(func));
120130
}
121131

122-
pub fn add_ini(&mut self, name: impl ToString, value: impl ToString, policy: Policy) {
123-
self.ini_entities
124-
.insert(name.to_string(), IniEntity::new(name, value, policy));
132+
pub fn add_bool_ini(&mut self, name: impl ToString, default_value: bool, policy: Policy) {
133+
Self::BOOL_INI_ENTITIES.with(|entities| {
134+
entities.borrow_mut().insert(name.to_string(), IniEntity::new(name, default_value, policy));
135+
})
136+
}
137+
138+
pub fn get_bool_ini(name: &str) -> Option<bool> {
139+
Self::BOOL_INI_ENTITIES.with(|entities| {
140+
entities.borrow().get(name).map(|entity| *entity.value())
141+
})
142+
}
143+
144+
pub fn add_long_ini(&mut self, name: impl ToString, default_value: i64, policy: Policy) {
145+
Self::LONG_INI_ENTITIES.with(|entities| {
146+
entities.borrow_mut().insert(name.to_string(), IniEntity::new(name, default_value, policy));
147+
})
148+
}
149+
150+
pub fn get_long_ini(name: &str) -> Option<i64> {
151+
Self::LONG_INI_ENTITIES.with(|entities| {
152+
entities.borrow().get(name).map(|entity| *entity.value())
153+
})
154+
}
155+
156+
pub fn add_real_ini(&mut self, name: impl ToString, default_value: f64, policy: Policy) {
157+
Self::REAL_INI_ENTITIES.with(|entities| {
158+
entities.borrow_mut().insert(name.to_string(), IniEntity::new(name, default_value, policy));
159+
})
160+
}
161+
162+
pub fn get_real_ini(name: &str) -> Option<f64> {
163+
Self::REAL_INI_ENTITIES.with(|entities| {
164+
entities.borrow().get(name).map(|entity| *entity.value())
165+
})
166+
}
167+
168+
pub fn add_str_ini(&mut self, name: impl ToString, default_value: impl ToString, policy: Policy) {
169+
Self::STR_INI_ENTITIES.with(|entities| {
170+
entities.borrow_mut().insert(name.to_string(), IniEntity::new(name, default_value, policy));
171+
})
172+
}
173+
174+
pub fn get_str_ini(name: &str) -> Option<String> {
175+
Self::STR_INI_ENTITIES.with(|entities| {
176+
entities.borrow().get(name).and_then(|entity| unsafe { entity.value().to_string() }.ok())
177+
})
125178
}
126179

127180
pub fn add_function(&mut self, name: impl ToString, handler: impl Function + 'static) {
@@ -207,17 +260,24 @@ impl Module {
207260
Box::into_raw(entries.into_boxed_slice()).cast()
208261
}
209262

210-
fn ini_entries(&self) -> *const zend_ini_entry_def {
263+
unsafe fn ini_entries(&self) -> *const zend_ini_entry_def {
211264
let mut entries = Vec::new();
212265

213-
for (_, ini) in &self.ini_entities {
214-
entries.push(ini.ini_entry_def());
215-
}
266+
Self::BOOL_INI_ENTITIES.with(|entities| Self::push_ini_entry(&mut entries, &mut *entities.borrow_mut()));
267+
Self::LONG_INI_ENTITIES.with(|entities| Self::push_ini_entry(&mut entries, &mut *entities.borrow_mut()));
268+
Self::REAL_INI_ENTITIES.with(|entities| Self::push_ini_entry(&mut entries, &mut *entities.borrow_mut()));
269+
Self::STR_INI_ENTITIES.with(|entities| Self::push_ini_entry(&mut entries, &mut *entities.borrow_mut()));
216270

217271
entries.push(unsafe { zeroed::<zend_ini_entry_def>() });
218272

219273
Box::into_raw(entries.into_boxed_slice()).cast()
220274
}
275+
276+
unsafe fn push_ini_entry<T: IniValue>(entries: &mut Vec<zend_ini_entry_def>, entities: &mut HashMap<String, IniEntity<T>>) {
277+
for (_, entry) in &mut *entities.borrow_mut() {
278+
entries.push(entry.ini_entry_def());
279+
}
280+
}
221281
}
222282

223283
pub struct ModuleArgs {

0 commit comments

Comments
 (0)