diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/argument.cpp | 104 | ||||
-rw-r--r-- | src/arguments.cpp | 85 | ||||
-rw-r--r-- | src/extension.cpp | 62 | ||||
-rw-r--r-- | src/function.cpp | 40 | ||||
-rw-r--r-- | src/includes.h | 5 | ||||
-rw-r--r-- | src/nativefunction.h | 16 |
6 files changed, 145 insertions, 167 deletions
diff --git a/src/argument.cpp b/src/argument.cpp index 387151a..7dbf624 100644 --- a/src/argument.cpp +++ b/src/argument.cpp @@ -14,62 +14,102 @@ namespace Php { /** - * Move constructor - * @param argument + * Constructor + * @param name Name of the argument + * @param type Argument type + * @param required Is this argument required? + * @param byref Is this a reference argument */ -Argument::Argument(Argument &&argument) +Argument::Argument(const char *name, Type type, bool required, bool byref) { - // copy data - _info = argument._info; + // construct object + _info = new zend_arg_info; + + // fill members + _info->name = name; + _info->name_len = strlen(name); + _info->type_hint = type == arrayType || type == callableType ? type : 0; + _info->class_name = NULL; + _info->class_name_len = 0; + _info->allow_null = false; + _info->pass_by_reference = byref; + + // store if required + _required = required; } /** - * Change the name - * @param name - * @return Argument + * Constructor + * @param name Name of the argument + * @param classname Name of the class + * @param nullable Can it be null? + * @param required Is this argument required? + * @param byref Is this a reference argument? */ -Argument &Argument::name(const char *name) +Argument::Argument(const char *name, const char *classname, bool nullable, bool required, bool byref) { + // construct object + _info = new zend_arg_info; + + // fill members _info->name = name; _info->name_len = strlen(name); - return *this; + _info->type_hint = objectType; + _info->class_name = classname; + _info->class_name_len = strlen(classname); + _info->allow_null = nullable; + _info->pass_by_reference = byref; + + // store if required + _required = required; +} + +/** + * Copy constructor + * @param argument + */ +Argument::Argument(const Argument &argument) +{ + // construct object + _info = new zend_arg_info; + + // fill members + *_info = *argument._info; + + // store if required + _required = argument._required; } /** - * Change the type - * @param type - * @return Argument + * Move constructor + * @param argument */ -Argument &Argument::type(Type type) +Argument::Argument(Argument &&argument) { - _info->type_hint = type; - return *this; + // copy memory pointer + _info = argument._info; + + // forget in other object + argument._info = nullptr; } /** - * Require the parameter to be a certain class - * @param name Name of the class - * @param null Are null values allowed? - * @return Argument + * Destructor */ -Argument &Argument::object(const char *classname, bool null) +Argument::~Argument() { - _info->type_hint = objectType; - _info->class_name = classname; - _info->class_name_len = strlen(classname); - _info->allow_null = null; - return *this; + if (_info) delete _info; } /** - * Is this a by-ref argument? - * @param bool Mark as by-ref variable - * @return Argument + * Fill an arg_info structure with data + * @param info + * @internal */ -Argument &Argument::byref(bool value) +void Argument::fill(struct _zend_arg_info *info) const { - _info->pass_by_reference = value; - return *this; + // copy all data + *info = *_info; } /** diff --git a/src/arguments.cpp b/src/arguments.cpp deleted file mode 100644 index 53f030b..0000000 --- a/src/arguments.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Arguments.cpp - * - * Implementation of the arguments class - * - * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> - * @copyright 2013 Copernica BV - */ -#include "includes.h" - -/** - * Set up namespace - */ -namespace Php { - -/** - * Constructor - * @param min The min number of arguments - * @param max The max number of arguments - */ -Arguments::Arguments(int min, int max) -{ - // copy arguments - _min = min; - _max = max; - - // max should be appropriate - if (_max < _min) _max = _min; - - // allocate memory for the arguments, with one extra record to hold information - _argv = new zend_arg_info[_max + 1]; - - // initialize the arguments - for (int i=1; i<_max+1; i++) - { - // initialize the argument - _argv[i].name = NULL; - _argv[i].name_len = 0; - _argv[i].class_name = NULL; - _argv[i].class_name_len = 0; - _argv[i].type_hint = nullType; - _argv[i].allow_null = false; - _argv[i].pass_by_reference = false; - } -} - -/** - * Destructor - */ -Arguments::~Arguments() -{ - // deallocate arguments - delete[] _argv; -} - -/** - * Constructor - * @param argc Number of arguments - * @param tsrm_ls - */ -/* - -Arguments::Arguments(int argc TSRMLS_DC) -{ - // reserve plenty of space - reserve(argc); - - // loop through the arguments - for (int i=0; i<argc; i++) - { - // get the argument - zval **arg = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 - (argc-i)); - - // append value - push_back(Value(*arg)); - } -} -* -*/ - -/** - * End of namespace - */ -} - diff --git a/src/extension.cpp b/src/extension.cpp index a084763..9323bd3 100644 --- a/src/extension.cpp +++ b/src/extension.cpp @@ -20,6 +20,12 @@ namespace Php { #endif /** + * Pointer to the one and only extension object + * @var Extension + */ +static Extension *extension = nullptr; + +/** * The way how PHP C API deals with "global" variables is stupid. * * This is supposed to turn into a structure that is going to be @@ -68,21 +74,6 @@ static void php_phpcpp_init_globals(zend_phpcpp_globals *globals) {} /** - * Helper method to get back the current extension object - * @return Extension - */ -static Extension *get_extension() -{ - // retrieve the extension or module name (because PHP of course does - // not pass such extremely useful information as they've no clue how - // to make a decent API - zend_module_entry *module = EG(current_module); - - // the pointer to the extension is hidden in front of the name - return HiddenPointer<Extension>(module->name); -} - -/** * Function that is called when the extension initializes * @param type Module type * @param number Module number @@ -97,7 +88,7 @@ static int extension_startup(INIT_FUNC_ARGS) // ZEND_INIT_MODULE_GLOBALS(hello, php_phpcpp_init_globals, NULL); // initialize the extension - return BOOL2SUCCESS(get_extension()->initialize()); + return BOOL2SUCCESS(extension->initialize()); } /** @@ -108,11 +99,8 @@ static int extension_startup(INIT_FUNC_ARGS) */ static int extension_shutdown(SHUTDOWN_FUNC_ARGS) { - // @todo the get_extension() call crashes, we need a different way to find the extension - return 0; - // finalize the extension - return BOOL2SUCCESS(get_extension()->finalize()); + return BOOL2SUCCESS(extension->finalize()); } /** @@ -124,7 +112,7 @@ static int extension_shutdown(SHUTDOWN_FUNC_ARGS) static int request_startup(INIT_FUNC_ARGS) { // create the request - return BOOL2SUCCESS(get_extension()->startRequest()); + return BOOL2SUCCESS(extension->startRequest()); } /** @@ -135,11 +123,8 @@ static int request_startup(INIT_FUNC_ARGS) */ static int request_shutdown(INIT_FUNC_ARGS) { - // @todo the get_extension() call crashes, we need a different way to find the extension - return 0; - // end the request - return BOOL2SUCCESS(get_extension()->endRequest()); + return BOOL2SUCCESS(extension->endRequest()); } @@ -148,8 +133,11 @@ static int request_shutdown(INIT_FUNC_ARGS) * @param name Name of the extension * @param version Version number */ -Extension::Extension(const char *name, const char *version) : _ptr(this, name) +Extension::Extension(const char *name, const char *version) { + // store extension variable + extension = this; + // allocate memory (we allocate this on the heap so that the size of the // entry does not have to be defined in the .h file. We pay a performance // price for this, but we pay this price becuase the design goal of the @@ -163,7 +151,7 @@ Extension::Extension(const char *name, const char *version) : _ptr(this, name) _entry->zts = USING_ZTS; // is thread safety enabled? _entry->ini_entry = NULL; // the php.ini record _entry->deps = NULL; // dependencies on other modules - _entry->name = _ptr; // extension name, with a hidden pointer to the extension object + _entry->name = name; // extension name _entry->functions = NULL; // functions supported by this module (none for now) _entry->module_startup_func = extension_startup; // startup function for the whole extension _entry->module_shutdown_func = extension_shutdown; // shutdown function for the whole extension @@ -208,13 +196,13 @@ Extension::~Extension() * @param function Function object * @return Function */ -Function &Extension::add(Function *function) +Function *Extension::add(Function *function) { // add the function to the map _functions.insert(std::unique_ptr<Function>(function)); // the result is a pair with an iterator - return *function; + return function; } /** @@ -223,14 +211,14 @@ Function &Extension::add(Function *function) * @param function The function to add * @return Function The added function */ -Function &Extension::add(const char *name, native_callback_0 function) { return add(new NativeFunction(name, function)); } -Function &Extension::add(const char *name, native_callback_1 function) { return add(new NativeFunction(name, function)); } -Function &Extension::add(const char *name, native_callback_2 function) { return add(new NativeFunction(name, function)); } -Function &Extension::add(const char *name, native_callback_3 function) { return add(new NativeFunction(name, function)); } -Function &Extension::add(const char *name, native_callback_4 function) { return add(new NativeFunction(name, function)); } -Function &Extension::add(const char *name, native_callback_5 function) { return add(new NativeFunction(name, function)); } -Function &Extension::add(const char *name, native_callback_6 function) { return add(new NativeFunction(name, function)); } -Function &Extension::add(const char *name, native_callback_7 function) { return add(new NativeFunction(name, function)); } +Function *Extension::add(const char *name, native_callback_0 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); } +Function *Extension::add(const char *name, native_callback_1 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); } +Function *Extension::add(const char *name, native_callback_2 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); } +Function *Extension::add(const char *name, native_callback_3 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); } +Function *Extension::add(const char *name, native_callback_4 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); } +Function *Extension::add(const char *name, native_callback_5 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); } +Function *Extension::add(const char *name, native_callback_6 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); } +Function *Extension::add(const char *name, native_callback_7 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); } /** * Retrieve the module entry diff --git a/src/function.cpp b/src/function.cpp index f15bffd..755bb48 100644 --- a/src/function.cpp +++ b/src/function.cpp @@ -45,6 +45,40 @@ void invoke_function(INTERNAL_FUNCTION_PARAMETERS) } /** + * Constructor + * @param name Name of the function + * @param min Min number of arguments + * @param max Max number of arguments + */ +Function::Function(const char *name, const std::initializer_list<Argument> &arguments) : _ptr(this, name) +{ + // construct vector for arguments + _argc = arguments.size(); + _argv = new zend_arg_info[_argc+1]; + + // counter + int i=1; + + // loop through the arguments + for (auto it = arguments.begin(); it != arguments.end(); it++) + { + // fill the arg info + it->fill(&_argv[i++]); + } + + // @todo find out number of required arguments + _required = _argc; +} + +/** + * Destructor + */ +Function::~Function() +{ + delete[] _argv; +} + +/** * Fill a function entry * * This method is called when the extension is registering itself, when the @@ -57,8 +91,8 @@ void Function::fill(zend_function_entry *entry) const // fill the members of the entity, and hide a pointer to the current object in the name entry->fname = _ptr; entry->handler = invoke_function; - entry->arg_info = _arguments->internal(); - entry->num_args = _arguments->argc(); + entry->arg_info = _argv; + entry->num_args = _argc; // there are no flags like deprecated, private or protected entry->flags = 0; @@ -81,7 +115,7 @@ void Function::fill(zend_internal_function_info *info) const info->_class_name = NULL; // number of required arguments, and the expected return type - info->required_num_args = _arguments->required(); + info->required_num_args = _required; info->_type_hint = _type; // we do not support return-by-reference diff --git a/src/includes.h b/src/includes.h index 3c1f26f..22f2891 100644 --- a/src/includes.h +++ b/src/includes.h @@ -24,7 +24,7 @@ /** * PHP includes */ -#include "php.h" +#include <php.h> /** * Macro to convert results to success status @@ -38,9 +38,10 @@ #include "../include/type.h" #include "../include/request.h" #include "../include/argument.h" +#include "../include/byval.h" +#include "../include/byref.h" #include "../include/value.h" #include "../include/member.h" -#include "../include/arguments.h" #include "../include/parameters.h" #include "../include/function.h" #include "../include/extension.h" diff --git a/src/nativefunction.h b/src/nativefunction.h index 40b8539..e8281ce 100644 --- a/src/nativefunction.h +++ b/src/nativefunction.h @@ -24,14 +24,14 @@ public: * @param name Function name * @param function The native C function */ - NativeFunction(const char *name, native_callback_0 function) : Function(name), _type(0) { _function.f0 = function; _ptr.setPointer(this); } - NativeFunction(const char *name, native_callback_1 function) : Function(name), _type(1) { _function.f1 = function; _ptr.setPointer(this); } - NativeFunction(const char *name, native_callback_2 function) : Function(name), _type(2) { _function.f2 = function; _ptr.setPointer(this); } - NativeFunction(const char *name, native_callback_3 function) : Function(name), _type(3) { _function.f3 = function; _ptr.setPointer(this); } - NativeFunction(const char *name, native_callback_4 function) : Function(name), _type(4) { _function.f4 = function; _ptr.setPointer(this); } - NativeFunction(const char *name, native_callback_5 function) : Function(name), _type(5) { _function.f5 = function; _ptr.setPointer(this); } - NativeFunction(const char *name, native_callback_6 function) : Function(name), _type(6) { _function.f6 = function; _ptr.setPointer(this); } - NativeFunction(const char *name, native_callback_7 function) : Function(name), _type(7) { _function.f7 = function; _ptr.setPointer(this); } + NativeFunction(const char *name, native_callback_0 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(0) { _function.f0 = function; } + NativeFunction(const char *name, native_callback_1 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(1) { _function.f1 = function; } + NativeFunction(const char *name, native_callback_2 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(2) { _function.f2 = function; } + NativeFunction(const char *name, native_callback_3 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(3) { _function.f3 = function; } + NativeFunction(const char *name, native_callback_4 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(4) { _function.f4 = function; } + NativeFunction(const char *name, native_callback_5 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(5) { _function.f5 = function; } + NativeFunction(const char *name, native_callback_6 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(6) { _function.f6 = function; } + NativeFunction(const char *name, native_callback_7 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(7) { _function.f7 = function; } /** * Destructor |