summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/argument.cpp104
-rw-r--r--src/arguments.cpp85
-rw-r--r--src/extension.cpp62
-rw-r--r--src/function.cpp40
-rw-r--r--src/includes.h5
-rw-r--r--src/nativefunction.h16
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