1use std;
2use std::mem;
3use libc::*;
4
5use super::types::*;
6
7type StartupFunc = extern fn (type_: c_int, module_number: c_int) -> c_int;
8type ShutdownFunc = extern fn (type_: c_int, module_number: c_int) -> c_int;
9type InfoFunc = extern fn () ;
10type GlobalsCtorFunc = extern fn (global: *const c_void) -> c_void;
11type GlobalsDtorFunc = extern fn (global: *const c_void) -> c_void;
12type PostDeactivateFunc = extern fn () -> c_int;
13type HandlerFunc = extern fn (execute_data: &ExecuteData, retval: &mut Zval);
14
15#[repr(C)]
16pub struct ArgInfo {
17 name: *const c_char,
18 class_name: *const c_char,
19 type_hint: c_char,
20 pass_by_reference: c_char,
21 allow_null: c_char,
22 is_variadic: c_char,
23}
24
25impl ArgInfo {
27 pub fn new(name: *const c_char, allow_null: c_char, is_variadic: c_char, by_reference: c_char) -> ArgInfo {
28 ArgInfo {
29 name: name,
30 class_name: std::ptr::null(),
31 type_hint: 0,
32 pass_by_reference: by_reference,
33 allow_null: allow_null,
34 is_variadic: is_variadic,
35 }
36 }
37}
38
39#[repr(C)]
41pub struct Function {
42 fname: *const c_char,
43 handler: Option<HandlerFunc>,
44 arg_info: *const ArgInfo,
45 num_args: u32,
46 flags: u32,
47}
48
49impl Function {
50 pub fn end() -> Function {
51 Function {
52 fname: std::ptr::null(),
53 handler: None,
54 arg_info: std::ptr::null(),
55 num_args: 0,
56 flags: 0,
57 }
58 }
59}
60
61pub struct FunctionBuilder {
62 function: Function,
63 args: Vec<ArgInfo>,
64}
65
66impl FunctionBuilder {
67 pub fn new(name: *const c_char, handler: HandlerFunc) -> Self {
69 FunctionBuilder {
70 function: Function {
71 fname: name,
72 handler: Some(handler),
73 arg_info: std::ptr::null(),
74 num_args: 0,
75 flags: 0,
76 },
77 args: Vec::new(),
78 }
79 }
80
81 pub fn with_arg(mut self, arg: ArgInfo) -> Self {
83 self.args.push(arg);
84 self
85 }
86
87 pub fn build(mut self)-> Function {
89 if self.args.is_empty() {
90 return self.function;
91 }
92 self.function.num_args = self.args.len() as u32 - 1;
93 self.function.arg_info = Box::into_raw(self.args.into_boxed_slice()) as *mut ArgInfo;
94 self.function
95 }
96}
97
98pub struct INI {}
99
100#[repr(C)]
102pub struct Module {
103 size: c_ushort,
104 zend_api: c_uint,
105 zend_debug: c_uchar,
106 zts: c_uchar,
107 ini_entry: *const INI,
108 deps: *const ModuleDep,
109 name: *const c_char,
110 functions: *const Function,
111 module_startup_func: Option<StartupFunc>,
112 module_shutdown_func: Option<ShutdownFunc>,
113 request_startup_func: Option<StartupFunc>,
114 request_shutdown_func: Option<ShutdownFunc>,
115 info_func: Option<InfoFunc>,
116 version: *const c_char,
117 globals_size: size_t,
118 globals_ptr: *const c_void,
119 globals_ctor: Option<GlobalsCtorFunc>,
120 globals_dtor: Option<GlobalsDtorFunc>,
121 post_deactivate_func: Option<PostDeactivateFunc>,
122 module_started: c_int,
123 type_: c_uchar,
124 handle: *const c_void,
125 module_number: c_int,
126 build_id: *const c_char,
127}
128
129impl Module {
130 pub fn into_raw(self) -> *mut Self {
131 Box::into_raw(Box::new(self))
132 }
133}
134
135pub struct ModuleBuilder {
136 module: Module,
137 functions: Vec<Function>,
138}
139
140impl ModuleBuilder {
141 pub fn new(name: *const c_char, version: *const c_char) -> ModuleBuilder {
143 ModuleBuilder {
144 module: Module {
145 size: mem::size_of::<Module>() as u16,
146 zend_api: env!("PHP_API_VERSION").parse::<u32>().unwrap(),
147 zend_debug: 0,
148 zts: 0,
149 ini_entry: std::ptr::null(),
150 deps: std::ptr::null(),
151 name: name,
152 functions: std::ptr::null(),
153 module_startup_func: None,
154 module_shutdown_func: None,
155 request_startup_func: None,
156 request_shutdown_func: None,
157 info_func: None,
158 version: version,
159 globals_size: 0,
160 globals_ptr: std::ptr::null(),
161 globals_ctor: None,
162 globals_dtor: None,
163 post_deactivate_func: None,
164 module_started: 0,
165 type_: 0,
166 handle: std::ptr::null(),
167 module_number: 0,
168 build_id: c_str!(env!("PHP_EXTENSION_BUILD")),
169 },
170 functions: Vec::new(),
171 }
172 }
173
174 pub fn with_startup_function(mut self, func: StartupFunc) -> Self {
176 self.module.module_startup_func = Some(func);
177 self
178 }
179
180 pub fn with_shutdown_function(mut self, func: ShutdownFunc) -> Self {
182 self.module.module_shutdown_func = Some(func);
183 self
184 }
185
186 pub fn with_info_function(mut self, func: InfoFunc) -> Self {
188 self.module.info_func = Some(func);
189 self
190 }
191
192 pub fn with_function(mut self, function: Function) -> Self {
194 self.functions.push(function);
195 self
196 }
197
198 pub fn build(mut self) -> Module {
199 self.functions.push(Function::end());
200 self.module.functions = Box::into_raw(self.functions.into_boxed_slice()) as *const Function;
201 self.module
202 }
203}
204
205unsafe impl Sync for Module {}