summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-02-28 10:25:01 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-02-28 10:25:01 +0100
commit71055ebdea1e8eec30747a04f36e0c10e750bff5 (patch)
tree18ed63d5fe64a936c284a38d4f72921a4ddc97df /src
parent85349bbb642a83012a7d0dbccde8b7c1eea1b914 (diff)
a lot of refactoring, to make it much easier to define classes in an extension
Diffstat (limited to 'src')
-rw-r--r--src/Makefile2
-rw-r--r--src/callable.cpp (renamed from src/function.cpp)52
-rw-r--r--src/callable.h121
-rw-r--r--src/class.cpp10
-rw-r--r--src/classbase.cpp (renamed from src/classinfo.cpp)131
-rw-r--r--src/extension.cpp71
-rw-r--r--src/function.h (renamed from src/nativefunction.h)16
-rw-r--r--src/includes.h9
-rw-r--r--src/member.cpp7
-rw-r--r--src/members.cpp140
-rw-r--r--src/method.h104
-rw-r--r--src/methodbase.cpp24
-rw-r--r--src/methodmember.h111
-rw-r--r--src/methods.h114
14 files changed, 675 insertions, 237 deletions
diff --git a/src/Makefile b/src/Makefile
index 069024d..64b4eb1 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,7 +1,7 @@
CPP = g++
RM = rm -f
PHP_DIR = /usr/include/php5
-CPP_FLAGS = -c -I. -I${PHP_DIR} -I${PHP_DIR}/main -I${PHP_DIR}/ext -I${PHP_DIR}/Zend -I${PHP_DIR}/TSRM -O2 -std=c++11
+CPP_FLAGS = -c -I. -I${PHP_DIR} -I${PHP_DIR}/main -I${PHP_DIR}/ext -I${PHP_DIR}/Zend -I${PHP_DIR}/TSRM -g -std=c++11
LD = g++
LD_FLAGS = -Wall -shared -O2
diff --git a/src/function.cpp b/src/callable.cpp
index ba37022..d410c0b 100644
--- a/src/function.cpp
+++ b/src/callable.cpp
@@ -23,13 +23,13 @@ namespace Php {
* @param tsrm_ls
* @return integer
*/
-void invoke_function(INTERNAL_FUNCTION_PARAMETERS)
+static void invoke_callable(INTERNAL_FUNCTION_PARAMETERS)
{
// find the function name
const char *name = get_active_function_name(TSRMLS_C);
// uncover the hidden pointer inside the function name
- Function *function = HiddenPointer<Function>(name);
+ Callable *callable = HiddenPointer<Callable>(name);
// wrap the return value
Value result(return_value, true);
@@ -41,7 +41,7 @@ void invoke_function(INTERNAL_FUNCTION_PARAMETERS)
try
{
// get the result
- result = function->invoke(params);
+ result = callable->invoke(params);
}
catch (Php::OrigException &exception)
{
@@ -58,40 +58,6 @@ 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
@@ -101,18 +67,18 @@ Function::~Function()
* @param classname Optional class name
* @param flags Is this a public property?
*/
-void Function::fill(zend_function_entry *entry, const char *classname, MemberModifier flags) const
+void Callable::initialize(zend_function_entry *entry, const char *classname, int flags) 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->fname = (const char *)_ptr;
+ entry->handler = invoke_callable;
entry->arg_info = _argv;
entry->num_args = _argc;
entry->flags = flags;
// we should fill the first argument as well
#if PHP_VERSION_ID >= 50400
- fill((zend_internal_function_info *)entry->arg_info, classname);
+ initialize((zend_internal_function_info *)entry->arg_info, classname);
#endif
}
@@ -122,7 +88,7 @@ void Function::fill(zend_function_entry *entry, const char *classname, MemberMod
* @param classname Optional classname
*/
#if PHP_VERSION_ID >= 50400
-void Function::fill(zend_internal_function_info *info, const char *classname) const
+void Callable::initialize(zend_internal_function_info *info, const char *classname) const
{
// fill in all the members, note that return reference is false by default,
// because we do not support returning references in PHP-CPP, although Zend
@@ -133,7 +99,7 @@ void Function::fill(zend_internal_function_info *info, const char *classname) co
// number of required arguments, and the expected return type
info->required_num_args = _required;
- info->_type_hint = _type;
+ info->_type_hint = _return;
// we do not support return-by-reference
info->return_reference = false;
diff --git a/src/callable.h b/src/callable.h
new file mode 100644
index 0000000..1b761ae
--- /dev/null
+++ b/src/callable.h
@@ -0,0 +1,121 @@
+/**
+ * Callable.h
+ *
+ * Object represents a callable function or method that is defined with the CPP
+ * API.
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Forward definitions
+ */
+struct _zend_function_entry;
+struct _zend_internal_function_info;
+
+/**
+ * Set up namespace
+ */
+namespace Php {
+
+/**
+ * Class definition
+ */
+class Callable
+{
+public:
+ /**
+ * Constructor
+ * @param name Function or method name
+ * @param arguments Information about the arguments
+ */
+ Callable(const char *name, const Arguments &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
+ */
+ virtual ~Callable()
+ {
+ delete[] _argv;
+ }
+
+ /**
+ * Method that gets called every time the function is executed
+ * @param params The parameters that were passed
+ * @return Variable Return value
+ */
+ virtual Value invoke(Parameters &params) = 0;
+
+ /**
+ * Fill a function entry
+ * @param entry Entry to be filled
+ * @param classname Optional class name
+ * @param flags Access flags
+ */
+ void initialize(struct _zend_function_entry *entry, const char *classname = nullptr, int flags = 0) const;
+
+ /**
+ * Fill function info
+ * @param info Info object to be filled
+ * @param classname Optional class name
+ */
+ void initialize(struct _zend_internal_function_info *info, const char *classname = nullptr) const;
+
+
+protected:
+ /**
+ * Hidden pointer to the name and the function
+ * @var HiddenPointer
+ */
+ HiddenPointer<Callable> _ptr;
+
+ /**
+ * Suggestion for the return type
+ * @var Type
+ */
+ Type _return = nullType;
+
+ /**
+ * Required number of arguments
+ * @var integer
+ */
+ int _required = 0;
+
+ /**
+ * Total number of arguments
+ * @var integer
+ */
+ int _argc = 0;
+
+ /**
+ * The arguments
+ * @var zend_arg_info[]
+ */
+ struct _zend_arg_info *_argv = nullptr;
+
+};
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/src/class.cpp b/src/class.cpp
deleted file mode 100644
index 6263147..0000000
--- a/src/class.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Class.cpp
- *
- * Implementation for the class entry
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
- */
-#include "includes.h"
-
diff --git a/src/classinfo.cpp b/src/classbase.cpp
index f96d724..2ad51b1 100644
--- a/src/classinfo.cpp
+++ b/src/classbase.cpp
@@ -1,10 +1,10 @@
/**
- * ClassInfo.cpp
+ * ClassBase.cpp
*
- * Implementation for the class info
+ * Implementation of the ClassBase class.
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
+ * @copyright 2014 Copernica BV
*/
#include "includes.h"
@@ -62,9 +62,9 @@ static zend_object_value create_object(zend_class_entry *type TSRMLS_DC)
// retrieve the classinfo object
#if PHP_VERSION_ID >= 50400
- _ClassInfo *info = (_ClassInfo *)base->info.user.doc_comment;
+ ClassBase *info = (ClassBase *)base->info.user.doc_comment;
#else
- _ClassInfo *info = *((_ClassInfo **)base->doc_comment);
+ ClassBase *info = *((ClassBase **)base->doc_comment);
#endif
// store the class
@@ -102,31 +102,70 @@ static zend_object_value create_object(zend_class_entry *type TSRMLS_DC)
}
/**
- * Constructor
- * @param name
+ * Destructor
*/
-_ClassInfo::_ClassInfo(const char *name) : _name(name), _entry(NULL)
+ClassBase::~ClassBase()
{
+ // destruct the entries
+ if (_entries) delete[] _entries;
}
/**
- * Destructor
+ * Retrieve an array of zend_function_entry objects that hold the
+ * properties for each method. This method is called at extension
+ * startup time to register all methods.
+ *
+ * @param classname The class name
+ * @return zend_function_entry[]
*/
-_ClassInfo::~_ClassInfo()
+const struct _zend_function_entry *ClassBase::entries()
{
+ // already initialized?
+ if (_entries) return _entries;
+
+ // allocate memory for the functions
+ _entries = new zend_function_entry[_methods.size() + 1];
+
+ // keep iterator counter
+ int i = 0;
+
+ // loop through the functions
+ for (auto &method : _methods)
+ {
+ // retrieve entry
+ zend_function_entry *entry = &_entries[i++];
+
+ // let the function fill the entry
+ // @todo check flags for the method
+ method->initialize(entry, _name);
+ }
+
+ // last entry should be set to all zeros
+ zend_function_entry *last = &_entries[i];
+
+ // all should be set to zero
+ memset(last, 0, sizeof(zend_function_entry));
+
+ // done
+ return _entries;
}
/**
- * Initialize the class
- * @param mixed Optional threading ID
+ * Initialize the class, given its name
+ *
+ * The module functions are registered on module startup, but classes are
+ * initialized afterwards. The Zend engine is a strange thing. Nevertheless,
+ * this means that this method is called after the module is already available.
+ * This function will inform the Zend engine about the existence of the
+ * class.
*/
-void _ClassInfo::initialize(TSRMLS_DC)
+void ClassBase::initialize()
{
// the class entry
zend_class_entry entry;
// initialize the class entry
- INIT_CLASS_ENTRY_EX(entry, _name.c_str(), _name.size(), methods());
+ INIT_CLASS_ENTRY_EX(entry, _name.c_str(), _name.size(), entries());
// we need a special constructor
entry.create_object = create_object;
@@ -159,19 +198,69 @@ void _ClassInfo::initialize(TSRMLS_DC)
_entry->doc_comment = (char *)wrapper;
#endif
- // initialize the entry
- initialize(_entry);
+ // set access types flags for class
+ // @todo something with the flags, but before or after the register_internal_class?
+ //setFlags(entry, _type.getFlags());
+
+ // declare all properties
+ // @todo enable this
+// _properties.initialize(_entry);
+}
+
+/**
+ * Add a method to the class
+ * @param name Name of the method
+ * @param method The actual method
+ * @param flags Optional flags
+ * @param args Description of the supported arguments
+ */
+void ClassBase::add(const char *name, method_callback_0 callback, int flags, const Arguments &args)
+{
+ // add the method
+ _methods.insert(std::make_shared<Method>(name, callback, flags, args));
+}
+
+/**
+ * Add a method to the class
+ * @param name Name of the method
+ * @param method The actual method
+ * @param flags Optional flags
+ * @param args Description of the supported arguments
+ */
+void ClassBase::add(const char *name, method_callback_1 callback, int flags, const Arguments &args)
+{
+ // add the method
+ _methods.insert(std::make_shared<Method>(name, callback, flags, args));
}
/**
- * set access types flags for class
+ * Add a method to the class
+ * @param name Name of the method
+ * @param method The actual method
+ * @param flags Optional flags
+ * @param args Description of the supported arguments
*/
-void _ClassInfo::setFlags(struct _zend_class_entry *entry, int flags) {
- entry->ce_flags |= flags;
+void ClassBase::add(const char *name, method_callback_2 callback, int flags, const Arguments &args)
+{
+ // add the method
+ _methods.insert(std::make_shared<Method>(name, callback, flags, args));
}
/**
- * End of namespace
+ * Add a method to the class
+ * @param name Name of the method
+ * @param method The actual method
+ * @param flags Optional flags
+ * @param args Description of the supported arguments
*/
+void ClassBase::add(const char *name, method_callback_3 callback, int flags, const Arguments &args)
+{
+ // add the method
+ _methods.insert(std::make_shared<Method>(name, callback, flags, args));
}
-
+
+/**
+ * End namespace
+ */
+}
+
diff --git a/src/extension.cpp b/src/extension.cpp
index 5c5292e..dae5051 100644
--- a/src/extension.cpp
+++ b/src/extension.cpp
@@ -191,7 +191,7 @@ Extension::Extension(const char *name, const char *version, request_callback sta
_entry->type = 0; // temporary or persistent module, will be filled by Zend engine
_entry->handle = NULL; // dlopen() handle, will be filled by Zend engine
_entry->module_number = 0; // module number will be filled in by Zend engine
- _entry->build_id = ZEND_MODULE_BUILD_ID; // check if extension and zend engine are compatible
+ _entry->build_id = (char *)ZEND_MODULE_BUILD_ID; // check if extension and zend engine are compatible
// things that only need to be initialized
#ifdef ZTS
@@ -215,29 +215,52 @@ Extension::~Extension()
}
/**
- * Add a function to the library
- * @param function Function object
- * @return Function
+ * Add a native function directly to the extension
+ * @param name Name of the function
+ * @param function The function to add
+ * @param arguments Optional argument specification
*/
-Function *Extension::add(Function *function)
+void Extension::add(const char *name, native_callback_0 function, const Arguments &arguments)
{
- // add the function to the map
- _functions.insert(std::unique_ptr<Function>(function));
-
- // the result is a pair with an iterator
- return function;
+ // add a function
+ _functions.insert(std::unique_ptr<Function>(new Function(name, function, arguments)));
+}
+
+/**
+ * Add a native function directly to the extension
+ * @param name Name of the function
+ * @param function The function to add
+ * @param arguments Optional argument specification
+ */
+void Extension::add(const char *name, native_callback_1 function, const Arguments &arguments)
+{
+ // add a function
+ _functions.insert(std::unique_ptr<Function>(new Function(name, function, arguments)));
}
/**
* Add a native function directly to the extension
* @param name Name of the function
* @param function The function to add
- * @return Function The added function
+ * @param arguments Optional argument specification
*/
-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)); }
+void Extension::add(const char *name, native_callback_2 function, const Arguments &arguments)
+{
+ // add a function
+ _functions.insert(std::unique_ptr<Function>(new Function(name, function, arguments)));
+}
+
+/**
+ * Add a native function directly to the extension
+ * @param name Name of the function
+ * @param function The function to add
+ * @param arguments Optional argument specification
+ */
+void Extension::add(const char *name, native_callback_3 function, const Arguments &arguments)
+{
+ // add a function
+ _functions.insert(std::unique_ptr<Function>(new Function(name, function, arguments)));
+}
/**
* Retrieve the module entry
@@ -249,29 +272,29 @@ zend_module_entry *Extension::module()
if (_entry->functions || _functions.size() == 0) return _entry;
// allocate memory for the functions
- zend_function_entry *functions = new zend_function_entry[_functions.size() + 1];
+ zend_function_entry *entries = new zend_function_entry[_functions.size() + 1];
// keep iterator counter
int i = 0;
// loop through the functions
- for (auto it = begin(_functions); it != _functions.end(); it++)
+ for (auto &function : _functions)
{
// retrieve entry
- zend_function_entry *entry = &functions[i++];
+ zend_function_entry *entry = &entries[i++];
// let the function fill the entry
- (*it)->fill(entry);
+ function->initialize(entry);
}
// last entry should be set to all zeros
- zend_function_entry *last = &functions[i];
+ zend_function_entry *last = &entries[i];
// all should be set to zero
memset(last, 0, sizeof(zend_function_entry));
// store functions in entry object
- _entry->functions = functions;
+ _entry->functions = entries;
// return the entry
return _entry;
@@ -284,11 +307,7 @@ zend_module_entry *Extension::module()
bool Extension::initialize()
{
// loop through the classes
- for (auto iter = _classes.begin(); iter != _classes.end(); iter++)
- {
- // initialize the class
- (*iter)->initialize();
- }
+ for (auto &iter : _classes) iter->initialize();
// done
return true;
diff --git a/src/nativefunction.h b/src/function.h
index 8b946a3..84d7dcc 100644
--- a/src/nativefunction.h
+++ b/src/function.h
@@ -1,7 +1,7 @@
/**
- * NativeFunction.h
+ * Function.h
*
- * The NativeFunction class is an extension of the Function class that
+ * The Function class is an extension of the Callable class that
* forwards the function call directly to a native function in C/C++
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
@@ -16,7 +16,7 @@ namespace Php {
/**
* Class definition
*/
-class NativeFunction : public Function
+class Function : public Callable
{
public:
/**
@@ -24,15 +24,15 @@ public:
* @param name Function name
* @param function The native C function
*/
- 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; }
+ Function(const char *name, native_callback_0 function, const Arguments &arguments = {}) : Callable(name, arguments), _type(0) { _function.f0 = function; }
+ Function(const char *name, native_callback_1 function, const Arguments &arguments = {}) : Callable(name, arguments), _type(1) { _function.f1 = function; }
+ Function(const char *name, native_callback_2 function, const Arguments &arguments = {}) : Callable(name, arguments), _type(2) { _function.f2 = function; }
+ Function(const char *name, native_callback_3 function, const Arguments &arguments = {}) : Callable(name, arguments), _type(3) { _function.f3 = function; }
/**
* Destructor
*/
- virtual ~NativeFunction() {}
+ virtual ~Function() {}
/**
* Method that gets called every time the function is executed
diff --git a/src/includes.h b/src/includes.h
index 5b97e03..4e6e583 100644
--- a/src/includes.h
+++ b/src/includes.h
@@ -30,6 +30,7 @@
/**
* PHP includes
*/
+#pragma GCC system_header
#include <php.h>
#include "zend_exceptions.h"
#include "zend_interfaces.h"
@@ -54,10 +55,8 @@
#include "../include/hashmember.h"
#include "../include/parameters.h"
#include "../include/membermodifier.h"
-#include "../include/function.h"
#include "../include/properties.h"
#include "../include/base.h"
-#include "../include/method.h"
#include "../include/member.h"
#include "../include/public.h"
#include "../include/protected.h"
@@ -65,8 +64,8 @@
#include "../include/const.h"
#include "../include/members.h"
#include "../include/classmodifier.h"
+#include "../include/classbase.h"
#include "../include/class.h"
-#include "../include/classinfo.h"
#include "../include/extension.h"
#include "../include/exception.h"
#include "../include/init.h"
@@ -75,7 +74,9 @@
* Interface files for internal use only
*/
#include "mixedobject.h"
-#include "nativefunction.h"
+#include "callable.h"
+#include "function.h"
+#include "method.h"
#include "internalfunction.h"
#include "memberinfo.h"
#include "nullmember.h"
diff --git a/src/member.cpp b/src/member.cpp
index 85990cc..e3e7ff2 100644
--- a/src/member.cpp
+++ b/src/member.cpp
@@ -5,6 +5,9 @@
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2013 Copernica BV
+ *
+ *
+ * @todo refactor this class to a property
*/
#include "includes.h"
@@ -13,6 +16,8 @@
*/
namespace Php {
+#ifdef XXXX
+
/**
* Constructor
* @param name Name of the member
@@ -218,6 +223,8 @@ void Member::fill(struct _zend_function_entry *entry, const char *classname)
_info->fill(entry, classname, _flags);
}
+#endif
+
/**
* End of namespace
*/
diff --git a/src/members.cpp b/src/members.cpp
index 4ff1b60..1965807 100644
--- a/src/members.cpp
+++ b/src/members.cpp
@@ -13,76 +13,76 @@
*/
namespace Php {
-/**
- * Destructor
- */
-Members::~Members()
-{
- // check if there are methods
- if (_methods) delete[] _methods;
-}
-
-/**
- * Number of methods
- * @return integer
- */
-int Members::methods()
-{
- // result variable
- int result = 0;
-
- // loop through the functions
- for (auto it = begin(); it != end(); it++)
- {
- // check if this is a method
- if (it->isMethod()) result++;
- }
-
- // done
- return result;
-}
-
-/**
- * Get access to the methods
- * @return Methods
- */
-struct _zend_function_entry *Members::methods(const char *classname)
-{
- // already set?
- if (_methods) return _methods;
-
- // the number of methods
- int count = methods();
-
- // allocate memory for the functions
- _methods = new zend_function_entry[count + 1];
-
- // keep iterator counter
- int i = 0;
-
- // loop through the functions
- for (auto it = begin(); it != end(); it++)
- {
- // skip if this is not a method
- if (!it->isMethod()) continue;
-
- // retrieve entry
- zend_function_entry *entry = &_methods[i++];
-
- // let the function fill the entry
- it->fill(entry, classname);
- }
-
- // last entry should be set to all zeros
- zend_function_entry *last = &_methods[i];
-
- // all should be set to zero
- memset(last, 0, sizeof(zend_function_entry));
-
- // done
- return _methods;
-}
-
+///**
+// * Destructor
+// */
+//Members::~Members()
+//{
+// // check if there are methods
+// if (_methods) delete[] _methods;
+//}
+//
+///**
+// * Number of methods
+// * @return integer
+// */
+//int Members::methods()
+//{
+// // result variable
+// int result = 0;
+//
+// // loop through the functions
+// for (auto it = begin(); it != end(); it++)
+// {
+// // check if this is a method
+// if (it->isMethod()) result++;
+// }
+//
+// // done
+// return result;
+//}
+//
+///**
+// * Get access to the methods
+// * @return Methods
+// */
+//struct _zend_function_entry *Members::methods(const char *classname)
+//{
+// // already set?
+// if (_methods) return _methods;
+//
+// // the number of methods
+// int count = methods();
+//
+// // allocate memory for the functions
+// _methods = new zend_function_entry[count + 1];
+//
+// // keep iterator counter
+// int i = 0;
+//
+// // loop through the functions
+// for (auto it = begin(); it != end(); it++)
+// {
+// // skip if this is not a method
+// if (!it->isMethod()) continue;
+//
+// // retrieve entry
+// zend_function_entry *entry = &_methods[i++];
+//
+// // let the function fill the entry
+// it->initialize(classname, entry);
+// }
+//
+// // last entry should be set to all zeros
+// zend_function_entry *last = &_methods[i];
+//
+// // all should be set to zero
+// memset(last, 0, sizeof(zend_function_entry));
+//
+// // done
+// return _methods;
+//}
+//
/**
* End of namespace
*/
diff --git a/src/method.h b/src/method.h
new file mode 100644
index 0000000..cc9f973
--- /dev/null
+++ b/src/method.h
@@ -0,0 +1,104 @@
+/**
+ * Method.h
+ *
+ * Internal class that represents a native class method, that can be called
+ * from PHP scripts.
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2014 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace Php {
+
+/**
+ * Class definition
+ */
+class Method : public Callable
+{
+public:
+ /**
+ * Constructor
+ *
+ * @param name Method name
+ * @param callback Native callback
+ * @param flags Access flags
+ * @param args Argument description
+ */
+ Method(const char *name, method_callback_0 callback, int flags, const Arguments &args) : Callable(name, args), _type(0), _flags(flags) { _callback.m0 = callback; }
+ Method(const char *name, method_callback_1 callback, int flags, const Arguments &args) : Callable(name, args), _type(1), _flags(flags) { _callback.m1 = callback; }
+ Method(const char *name, method_callback_2 callback, int flags, const Arguments &args) : Callable(name, args), _type(2), _flags(flags) { _callback.m2 = callback; }
+ Method(const char *name, method_callback_3 callback, int flags, const Arguments &args) : Callable(name, args), _type(3), _flags(flags) { _callback.m3 = callback; }
+
+ /**
+ * Destructor
+ * @param type
+ * @param callback
+ */
+ virtual ~Method() {}
+
+ /**
+ * Internal method to fill a function entry
+ * @param zend_function_entry
+ * @param classname
+ */
+ void initialize(struct _zend_function_entry *entry, const std::string &classname)
+ {
+ // call base
+ Callable::initialize(entry, classname.c_str(), _flags);
+ }
+
+ /**
+ * Invoke the method
+ * @param parameters
+ * @return Value
+ */
+ virtual Value invoke(Parameters &parameters) override
+ {
+ // the object to call a method on
+ Base *base = parameters.object();
+
+ // find out which method to call, and call it
+ switch (_type) {
+ case 0: (base->*_callback.m0)(); return Value();
+ case 1: (base->*_callback.m1)(parameters); return Value();
+ case 2: return (base->*_callback.m2)();
+ case 3: return (base->*_callback.m3)(parameters);
+ default: return Value();
+ }
+ }
+
+
+private:
+ /**
+ * Callback type
+ * @var int
+ */
+ int _type;
+
+ /**
+ * Access flags (protected, public, abstract, final, private, etc)
+ * @var int
+ * @todo use this
+ */
+ int _flags;
+
+ /**
+ * The actual callback
+ * @var void*
+ */
+ union {
+ method_callback_0 m0;
+ method_callback_1 m1;
+ method_callback_2 m2;
+ method_callback_3 m3;
+ } _callback;
+};
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/src/methodbase.cpp b/src/methodbase.cpp
new file mode 100644
index 0000000..81ce40a
--- /dev/null
+++ b/src/methodbase.cpp
@@ -0,0 +1,24 @@
+/**
+ * MethodBase.cpp
+ *
+ * Implementation of the MethodBase class
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2014 Copernica BV
+ */
+#include "includes.h"
+
+/**
+ * Set up namespace
+ *
+ * @todo remove file
+ */
+namespace Php {
+
+/**
+ * End namespace
+ */
+}
+
+
+ \ No newline at end of file
diff --git a/src/methodmember.h b/src/methodmember.h
index 709aec9..5d903e9 100644
--- a/src/methodmember.h
+++ b/src/methodmember.h
@@ -5,6 +5,9 @@
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2013 Copernica BV
+ *
+ * @todo remove this class
+ * @todo but do implement this for properties
*/
/**
@@ -12,60 +15,60 @@
*/
namespace Php {
-/**
- * Class definition
- */
-class MethodMember : public MemberInfo, public Function
-{
-public:
- /**
- * Constructor
- * @param name
- * @param method
- * @param arguments
- */
- MethodMember(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _method(method) {}
-
- /**
- * Destructor
- */
- virtual ~MethodMember() {}
-
- /**
- * Is this a method member
- * @return bool
- */
- virtual bool isMethod() { return true; }
-
- /**
- * Fill a function entry object
- * @param entry Function entry
- * @param classname Name of the class
- * @param method Is this a public entry
- */
- virtual void fill(struct _zend_function_entry *entry, const char *classname, MemberModifier flags) override
- {
- // call function object
- Function::fill(entry, classname, flags);
- }
-
- /**
- * Method that gets called every time the function is executed
- * @param params The parameters that were passed
- * @return Variable Return value
- */
- virtual Value invoke(Parameters &params)
- {
- return _method.invoke(params);
- }
-
-private:
- /**
- * The method pointer
- * @var _Method
- */
- _Method _method;
-};
+///**
+// * Class definition
+// */
+//class MethodMember : public MemberInfo, public Function
+//{
+//public:
+// /**
+// * Constructor
+// * @param name
+// * @param method
+// * @param arguments
+// */
+// MethodMember(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _method(method) {}
+//
+// /**
+// * Destructor
+// */
+// virtual ~MethodMember() {}
+//
+// /**
+// * Is this a method member
+// * @return bool
+// */
+// virtual bool isMethod() { return true; }
+//
+// /**
+// * Fill a function entry object
+// * @param entry Function entry
+// * @param classname Name of the class
+// * @param method Is this a public entry
+// */
+// virtual void fill(struct _zend_function_entry *entry, const char *classname, MemberModifier flags) override
+// {
+// // call function object
+// Function::fill(entry, classname, flags);
+// }
+//
+// /**
+// * Method that gets called every time the function is executed
+// * @param params The parameters that were passed
+// * @return Variable Return value
+// */
+// virtual Value invoke(Parameters &params)
+// {
+// return _method.invoke(params);
+// }
+//
+//private:
+// /**
+// * The method pointer
+// * @var _Method
+// */
+// _Method _method;
+//};
/**
* End of namespace
diff --git a/src/methods.h b/src/methods.h
new file mode 100644
index 0000000..08c129b
--- /dev/null
+++ b/src/methods.h
@@ -0,0 +1,114 @@
+/**
+ * Methods.h
+ *
+ * Class in which all methods are stored. This is a class that is used
+ * internally by the PHP-CPP library, and that you do not have to use
+ * as an extension writer.
+ *
+ * Essentially, it is std::map that is a littlebit extended with features
+ * to initialize the methods in the Zend engine
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2014 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace Php {
+
+/**
+ * Class definition
+ */
+class Methods
+{
+public:
+ /**
+ * Constructor
+ */
+ Methods() {}
+
+ /**
+ * Destructor
+ */
+ virtual ~Methods()
+ {
+ // destruct the entries
+ if (_entries) delete[] _entries;
+ }
+
+ /**
+ * Retrieve an array of zend_function_entry objects that hold the
+ * properties for each method. This method is called at extension
+ * startup time to register all methods.
+ *
+ * @param classname The class name
+ * @return zend_function_entry[]
+ */
+ const struct _zend_function_entry *entries(const std::string &classname)
+ {
+ // already initialized?
+ if (_entries) return _entries;
+
+ // allocate memory for the functions
+ _entries = new zend_function_entry[_methods.size() + 1];
+
+ // keep iterator counter
+ int i = 0;
+
+ // loop through the functions
+ for (auto &method : _methods)
+ {
+ // retrieve entry
+ zend_function_entry *entry = &_entries[i++];
+
+ // let the function fill the entry
+ // @todo check flags for the method
+ method->initialize(entry, classname);
+ }
+
+ // last entry should be set to all zeros
+ zend_function_entry *last = &_entries[i];
+
+ // all should be set to zero
+ memset(last, 0, sizeof(zend_function_entry));
+
+ // done
+ return _entries;
+ }
+
+ /**
+ * Add a method
+ * @param name
+ * @param method
+ */
+ void add(MethodBase *method)
+ {
+ // add the method
+ _methods.insert(std::shared_ptr<MethodBase>(method));
+ }
+
+
+private:
+ /**
+ * Pointer to the entries
+ * @var zend_function_entry[]
+ */
+ struct _zend_function_entry *_entries = nullptr;
+
+ /**
+ * Map of all methods
+ *
+ * A unique_ptr would have been cooler, but that somehow does not compile
+ *
+ * @var std::set
+ */
+ std::set<std::shared_ptr<MethodBase>> _methods;
+
+};
+
+/**
+ * End namespace
+ */
+}
+