summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/extension.h33
-rw-r--r--include/function.h15
-rw-r--r--include/functions.h71
-rw-r--r--include/hiddenpointer.h264
-rw-r--r--include/request.h2
-rw-r--r--phpcpp.h1
-rw-r--r--src/arginfo.h105
-rw-r--r--src/callable.cpp175
-rw-r--r--src/callable.h157
-rw-r--r--src/extension.cpp67
-rw-r--r--src/function.cpp5
-rw-r--r--src/includes.h4
-rw-r--r--src/nativefunction.h88
-rw-r--r--tests/simple/simple.cpp14
-rw-r--r--tests/simple/simple.php2
-rw-r--r--tests/simple/test.cpp298
16 files changed, 325 insertions, 976 deletions
diff --git a/include/extension.h b/include/extension.h
index 5dabb8e..ad00593 100644
--- a/include/extension.h
+++ b/include/extension.h
@@ -11,8 +11,8 @@
* as module in a webserver) many requests are handled by the same extension
* instance.
*
- * This is a template class. You need to pass in the type of an object
- * that you use for storing request specific state information.
+ * This is a template class. You need to pass in the type of an object
+ * that you use for storing request specific state information.
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2013 Copernica BV
@@ -29,6 +29,20 @@ struct _zend_module_entry;
namespace Php {
/**
+ * A couple of predefined native callback functions that can be registered.
+ * These are functions that optional accept a Request and/or Parameters object,
+ * and that either return void or a Value object.
+ */
+typedef void (*native_callback_0)();
+typedef void (*native_callback_1)(Parameters &);
+typedef void (*native_callback_2)(Request &);
+typedef void (*native_callback_3)(Request &, Parameters &);
+typedef Value (*native_callback_4)();
+typedef Value (*native_callback_5)(Parameters &);
+typedef Value (*native_callback_6)(Request &);
+typedef Value (*native_callback_7)(Request &, Parameters &);
+
+/**
* Class definition
*/
class Extension
@@ -159,6 +173,21 @@ public:
Function &add(const char *name, const Function &function);
/**
+ * 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
+ */
+ Function &add(const char *name, native_callback_0 function);
+ Function &add(const char *name, native_callback_1 function);
+ Function &add(const char *name, native_callback_2 function);
+ Function &add(const char *name, native_callback_3 function);
+ Function &add(const char *name, native_callback_4 function);
+ Function &add(const char *name, native_callback_5 function);
+ Function &add(const char *name, native_callback_6 function);
+ Function &add(const char *name, native_callback_7 function);
+
+ /**
* Retrieve the module entry
*
* This is the memory address that should be exported by the get_module()
diff --git a/include/function.h b/include/function.h
index 67d2332..daf8572 100644
--- a/include/function.h
+++ b/include/function.h
@@ -26,6 +26,18 @@ namespace Php {
class Function
{
public:
+
+// Function(std::function<Value()> &function);
+// Function(std::function<Value(Value&)> &function);
+// Function(std::function<Value(Value&,Value&)> &function);
+// Function(std::function<Value(Value&,Value&,Value&)> &function);
+// Function(std::function<Value(Value&,Value&,Value&,Value&)> &function);
+// Function(std::function<void()> &function);
+// Function(std::function<void(Value&)> &function);
+// Function(std::function<void(Value&,Value&)> &function);
+// Function(std::function<void(Value&,Value&,Value&)> &function);
+// Function(std::function<void(Value&,Value&,Value&,Value&)> &function);
+
/**
* Constructor
* @param min Min number of arguments
@@ -87,10 +99,11 @@ public:
/**
* Method that gets called every time the function is executed
+ * @param request Request object
* @param params The parameters that were passed
* @return Variable Return value
*/
- virtual Value invoke(Parameters &params)
+ virtual Value invoke(Request &request, Parameters &params)
{
return 0;
}
diff --git a/include/functions.h b/include/functions.h
deleted file mode 100644
index 69653b4..0000000
--- a/include/functions.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * Functions.h
- *
- * Internal helper class that parses the functions initializer list, and
- * that converts it into a zend_function_entry array.
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
- */
-
-/**
- * Define structures
- */
-struct _zend_function_entry;
-
-/**
- * Set up namespace
- */
-namespace Php {
-
-/**
- * Class definition
- */
-class Functions
-{
-public:
- /**
- * Constructor
- * @param functions The functions to parse
- */
- Functions(const std::initializer_list<Function> &functions);
-
- /**
- * Destructor
- */
- virtual ~Functions();
-
-private:
- /**
- * Retrieve the internal data
- * @return zend_function_entry*
- */
- _zend_function_entry *internal() const
- {
- return _entries;
- }
-
- /**
- * The internal entries
- * @var zend_function_entry*
- */
- _zend_function_entry *_entries;
-
- /**
- * Vector of functions (we need this because the function objects must
- * remain in memory, so that we can call the invoke methods on them)
- * @var vector
- */
- std::vector<Function> _functions;
-
- /**
- * The extension has access to the private elements
- */
- friend class Extension;
-};
-
-/**
- * End of namespace
- */
-}
-
diff --git a/include/hiddenpointer.h b/include/hiddenpointer.h
index bcb44ba..f29082f 100644
--- a/include/hiddenpointer.h
+++ b/include/hiddenpointer.h
@@ -1,50 +1,50 @@
/**
- * HiddenPointer.h
+ * HiddenPointer.h
*
- * Helper class that we use to hide a pointer in a string. We do this
- * by creating a string buffer that is a littlebit bigger, and put
- * the hidden pointer in front of the name
+ * Helper class that we use to hide a pointer in a string. We do this
+ * by creating a string buffer that is a littlebit bigger, and put
+ * the hidden pointer in front of the name
*
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
*/
/**
- * Set up namespace
+ * Set up namespace
*/
namespace Php {
/**
- * Class definition
+ * Class definition
*/
template <typename Type>
class HiddenPointer
{
public:
- /**
- * Constructor to hide the pointer in a buffer
- * @param pointer The pointer to hide
- * @param text The visible text
- * @param size Optional text size
- */
- HiddenPointer(Type *pointer, const char *text, int size=-1)
- {
- // calculate size
- if (size < 0) size = strlen(text);
+ /**
+ * Constructor to hide the pointer in a buffer
+ * @param pointer The pointer to hide
+ * @param text The visible text
+ * @param size Optional text size
+ */
+ HiddenPointer(Type *pointer, const char *text, int size=-1)
+ {
+ // calculate size
+ if (size < 0) size = strlen(text);
- // reserve enough room for the text and the pointer
- _data.reserve(size + sizeof(Type *));
-
- // store the pointer
- _data.assign(std::string((const char *)&pointer, sizeof(Type *)));
-
- // append the text
- _data.append(text, size);
-
- // store pointers
- _pointer = pointer;
- _text = _data.c_str() + sizeof(Type *);
- }
+ // reserve enough room for the text and the pointer
+ _data.reserve(size + sizeof(Type *));
+
+ // store the pointer
+ _data.assign(std::string((const char *)&pointer, sizeof(Type *)));
+
+ // append the text
+ _data.append(text, size);
+
+ // store pointers
+ _pointer = pointer;
+ _text = _data.c_str() + sizeof(Type *);
+ }
/**
* Hide pointer in buffer
@@ -53,114 +53,114 @@ public:
*/
HiddenPointer(Type *pointer, const std::string &text) : HiddenPointer(pointer, text.c_str(), text.size()) {}
- /**
- * Constructor to retrieve the object given a buffer
- * @param text The visible text
- * @param size Size of the text
- */
- HiddenPointer(const char *text, int size=-1)
- {
- // calculate size
- if (size < 0) size = strlen(text);
-
- // the pointer is stored right in front of the name
- _pointer = *((Type **)(text - sizeof(Type *)));
- _text = text;
- }
-
- /**
- * Copy constructor
- * @param that
- */
- HiddenPointer(const HiddenPointer<Type> &that) : _pointer(that._pointer), _text(that._text), _data(that._data)
- {
- // if data is filled, the text is located inside the data
- if (_data.size() > 0) _text = _data.c_str() + sizeof(Type *);
- }
-
- /**
- * Destructor
- */
- virtual ~HiddenPointer() {}
-
- /**
- * Assignment operator
- * @param that
- * @return HiddenPointer
- */
- HiddenPointer<Type> operator=(const HiddenPointer &that)
- {
- // skip self assignment
- if (&that == this) return *this;
-
- // copy members
- _pointer = that._pointer;
- _text = that._text;
- _data = that._data;
+ /**
+ * Constructor to retrieve the object given a buffer
+ * @param text The visible text
+ * @param size Size of the text
+ */
+ HiddenPointer(const char *text, int size=-1)
+ {
+ // calculate size
+ if (size < 0) size = strlen(text);
+
+ // the pointer is stored right in front of the name
+ _pointer = *((Type **)(text - sizeof(Type *)));
+ _text = text;
+ }
+
+ /**
+ * Copy constructor
+ * @param that
+ */
+ HiddenPointer(const HiddenPointer<Type> &that) : _pointer(that._pointer), _text(that._text), _data(that._data)
+ {
+ // if data is filled, the text is located inside the data
+ if (_data.size() > 0) _text = _data.c_str() + sizeof(Type *);
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~HiddenPointer() {}
+
+ /**
+ * Assignment operator
+ * @param that
+ * @return HiddenPointer
+ */
+ HiddenPointer<Type> operator=(const HiddenPointer &that)
+ {
+ // skip self assignment
+ if (&that == this) return *this;
+
+ // copy members
+ _pointer = that._pointer;
+ _text = that._text;
+ _data = that._data;
- // if data is filled, the text is located inside the data
- if (_data.size() > 0) _text = _data.c_str() + sizeof(Type *);
- }
-
- /**
- * Retrieve the pointer
- * @return Type*
- */
- Type *pointer()
- {
- return _pointer;
- }
-
- /**
- * Retrieve the text
- * @return const char *
- */
- const char *text()
- {
- return _text;
- }
-
- /**
- * Cast to the pointer
- * @return Type*
- */
- operator Type* ()
- {
- return _pointer;
- }
-
- /**
- * Cast to text
- * @return const char *
- */
- operator const char * ()
- {
- return _text;
- }
+ // if data is filled, the text is located inside the data
+ if (_data.size() > 0) _text = _data.c_str() + sizeof(Type *);
+ }
+
+ /**
+ * Retrieve the pointer
+ * @return Type*
+ */
+ Type *pointer()
+ {
+ return _pointer;
+ }
+
+ /**
+ * Retrieve the text
+ * @return const char *
+ */
+ const char *text()
+ {
+ return _text;
+ }
+
+ /**
+ * Cast to the pointer
+ * @return Type*
+ */
+ operator Type* ()
+ {
+ return _pointer;
+ }
+
+ /**
+ * Cast to text
+ * @return const char *
+ */
+ operator const char * ()
+ {
+ return _text;
+ }
private:
- /**
- * The actual pointer
- * @var Type*
- */
- Type *_pointer;
-
- /**
- * The original text
- * @var text
- */
- const char *_text;
-
- /**
- * Optional data buffer
- * @var string
- */
- std::string _data;
+ /**
+ * The actual pointer
+ * @var Type*
+ */
+ Type *_pointer;
+
+ /**
+ * The original text
+ * @var text
+ */
+ const char *_text;
+
+ /**
+ * Optional data buffer
+ * @var string
+ */
+ std::string _data;
};
/**
- * End of namespace
+ * End of namespace
*/
}
diff --git a/include/request.h b/include/request.h
index 4183966..d204e85 100644
--- a/include/request.h
+++ b/include/request.h
@@ -77,7 +77,7 @@ protected:
/**
* Optional extra data
- * @var Type
+ * @var Type
*/
Type _data;
};
diff --git a/phpcpp.h b/phpcpp.h
index 55234e9..13307be 100644
--- a/phpcpp.h
+++ b/phpcpp.h
@@ -29,7 +29,6 @@
#include <phpcpp/arguments.h>
#include <phpcpp/parameters.h>
#include <phpcpp/function.h>
-#include <phpcpp/functions.h>
#include <phpcpp/extension.h>
/**
diff --git a/src/arginfo.h b/src/arginfo.h
deleted file mode 100644
index 39e0e99..0000000
--- a/src/arginfo.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * ArgInfo.h
- *
- * Internal class that wraps the Zend information about an argument
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
- */
-
-/**
- * Set up namespace
- */
-namespace Php {
-
-/**
- * Class definition
- */
-class ArgInfo
-{
-public:
- /**
- * Constructor if this argument should be an instance of a certain class
- * @param name Name of the argument
- * @param classname If a specific class is required, the class type
- * @param null Are NULL values allowed in stead of an instance?
- * @param ref Is this a pass-by-reference argument?
- */
- ArgInfo(const std::string &name, const std::string &classname, bool null = true, bool ref = false) :
- _name(name), _classname(name), _type(objectType), _null(null), _ref(ref) {}
-
- /**
- * Constructor if this argument can be anything
- * @param name Name of the argument
- * @param type Type hint (arrayType or callableType)
- * @param ref Is this a pass-by-reference argument?
- */
- ArgInfo(const std::string &name, Type type = nullType, bool ref = false) :
- _name(name), _type(type), _null(false), _ref(ref) {}
-
- /**
- * Constructor if this argument can be anything
- * @param name Name of the argument
- * @param ref Is this a pass-by-reference argument?
- */
- ArgInfo(const std::string &name, bool ref = false) :
- _name(name), _type(nullType), _null(false), _ref(ref) {}
-
- /**
- * Destructor
- */
- virtual ~ArgInfo() {}
-
- /**
- * Fill a zend_arg_info structure
- * @param info
- */
- void fill(zend_arg_info *info)
- {
- // fill all members
- info->name = _name.c_str();
- info->name_len = _name.size();
- info->class_name = _classname.size() ? _classname.c_str() : NULL;
- info->class_name_len = _classname.size();
- info->type_hint = _type;
- info->allow_null = _null;
- info->pass_by_reference = _ref;
- }
-
-private:
- /**
- * The argument name
- * @var string
- */
- std::string _name;
-
- /**
- * The class name
- * @var string
- */
- std::string _classname;
-
- /**
- * Type of the argument
- * @var Type
- */
- Type _type;
-
- /**
- * Can this argument be set to NULL?
- * @var bool
- */
- bool _null;
-
- /**
- * Is this a pass-by-reference argument?
- * @var bool
- */
- bool _ref;
-};
-
-/**
- * End of namespace
- */
-}
-
diff --git a/src/callable.cpp b/src/callable.cpp
deleted file mode 100644
index 4db463c..0000000
--- a/src/callable.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * Callable.cpp
- *
- * Implementation for the Callable class
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
- */
-#include "includes.h"
-
-/**
- * Namespace
- */
-namespace Php {
-
-/**
- * Function that is called by the Zend engine every time that a function gets called
- * @param ht
- * @param return_value
- * @param return_value_ptr
- * @param this_ptr
- * @param return_value_used
- * @param tsrm_ls
- * @return integer
- */
-void invoke_callable(INTERNAL_FUNCTION_PARAMETERS)
-{
- // find the function name
- const char *function = get_active_function_name(TSRMLS_C);
-
- // uncover the hidden pointer inside the function name
- Callable *callable = HiddenPointer<Callable>(function);
-
- // call the appropriate object
- callable->invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-}
-
-/**
- * Fill a function entry
- *
- * This method is called when the extension is registering itself, when the
- * function or method introces himself
- *
- * @param entry
- */
-void Callable::fill(zend_function_entry *entry)
-{
- // fill the members of the entity, and hide a pointer to the current object in the name
- entry->fname = HiddenPointer<Callable>(this, _name);
- entry->handler = invoke_callable;
- entry->arg_info = _argv;
- entry->num_args = _argc;
- entry->flags = _flags;
-}
-
-/**
- * Another attempt to fill internal function info
- *
- * This method is called when the extension is registering itself, when the
- * function or method introces himself
- *
- * @param entry
- */
-void Callable::fill(zend_internal_function_info *info)
-{
- // fill in all the members, note that return reference is false by default,
- // because we do want to return references, inside the name we hide a pointer
- // to the current object
- info->_name = HiddenPointer<Callable>(this, _name);
- info->_name_len = _name.size();
- info->_class_name = _classname.size() ? _classname.c_str() : NULL;
- info->required_num_args = _required;
- info->_type_hint = _type;
- info->return_reference = false;
- info->pass_rest_by_reference = false;
-}
-
-/**
- * Process the arguments
- *
- * The arguments are called by the user of the PhpCpp library when he
- *
- * @param arguments
- */
-void Callable::process(const std::initializer_list<Argument> &arguments)
-{
- // store counters
- _argc = arguments.size();
- _required = arguments.size();
-
- // allocate memory for the arguments, with one extra record to hold information
- _argv = new zend_arg_info[_argc + 1];
-
- // fill the info
- fill((zend_internal_function_info *)_argv);
-
- // iteration counter
- int i = 0;
-
- // loop through the arguments
- for (auto it = begin(arguments); it != arguments.end(); it++)
- {
- // fill the argument structure
-// it->internal()->fill(&_argv[++i]);
- }
-}
-
-int do_test(int a, int b)
-{
- std::cout << "do_test: " << a << " " << b << std::endl;
-
- return 77;
-}
-
-/**
- * Invoke the method
- * @param ht
- * @param return_value
- * @param return_value_ptr
- * @param this_ptr
- * @param return_value_used
- * @param tsrm_ls
- * @return integer
- */
-int Callable::invoke(INTERNAL_FUNCTION_PARAMETERS)
-{
- std::cout << "args: " << ZEND_NUM_ARGS() << std::endl;
- std::cout << "required: " << _required << std::endl;
- std::cout << "argc: " << _argc << std::endl;
-
- // number of arguments should be sufficient // @todo show error message
-// if (ZEND_NUM_ARGS() < _required) return FAILURE;
-
- // and not be too much // @todo show error message
-// if (ZEND_NUM_ARGS() > _argc) return FAILURE;
-
- // number of arguments on the stack
- int arg_count = (int)(zend_uintptr_t) *(zend_vm_stack_top(TSRMLS_C) - 1);
-
-// // loop through the arguments
-// Arguments args(ZEND_NUM_ARGS());
-//
-// for (auto iter = args.begin(); iter != args.end(); iter++)
-// {
-// Value val = *iter;
-//
-// val = 1234;
-// }
-//
-// int result = do_test(args[1], args[2]);
-//
- Value ret(return_value, true);
-
- std::cout << "set property 1" << std::endl;
-
-// ret["b"] = "hallo";
-
- ret["x"]["c"]["d"] = "test 123";
-
- std::cout << "done setting properties" << std::endl;
-
-
-//
-// // done
- return SUCCESS;
-}
-
-
-
-
-/**
- * End of namespace
- */
-}
-
diff --git a/src/callable.h b/src/callable.h
deleted file mode 100644
index 293e3aa..0000000
--- a/src/callable.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- * Callable.h
- *
- * This is an internal class that is used internally by the Function and Method
- * classes, and that wraps the Zend function entry into a CPP object.
- *
- * This is an internal class, that is not supposed to be used or called from
- * outside the PhpCpp library.
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
- */
-
-/**
- * Set up namespace
- */
-namespace Php {
-
-/**
- * Class definition
- */
-class Callable
-{
-public:
- /**
- * Constructor
- * @param classname Name of the class
- * @param function Name of the function or method
- * @param type Hint for the return type
- * @param arguments The arguments that are passed to the function
- * @param flags Optional flags to be passed to the function
- */
- Callable(const std::string &classname, const std::string &function, Type type = nullType, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
- _classname(classname), _name(function), _type(type), _flags(flags)
- {
- // process the arguments
- process(arguments);
- }
-
- /**
- * Constructor
- * @param classname Name of the class
- * @param function Name of the function or method
- * @param type Hint for the return type
- * @param arguments The arguments that are passed to the function
- * @param flags Optional flags to be passed to the function
- */
- Callable(const std::string &classname, const std::string &function, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
- Callable(classname, function, nullType, arguments, flags) {}
-
- /**
- * Constructor
- * @param function Name of the function or method
- * @param type Hint for the return type
- * @param arguments The arguments that are passed to the function
- * @param flags Optional flags to be passed to the function
- */
- Callable(const std::string &function, Type type = nullType, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
- Callable("", function, type, arguments, flags) {}
-
- /**
- * Constructor
- * @param function Name of the function or method
- * @param type Hint for the return type
- * @param arguments The arguments that are passed to the function
- * @param flags Optional flags to be passed to the function
- */
- Callable(const std::string &function, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
- Callable("", function, nullType, arguments, flags) {}
-
- /**
- * Destructor
- */
- virtual ~Callable()
- {
- delete[] _argv;
- }
-
- /**
- * Fill a function entry
- * @param entry
- */
- void fill(zend_function_entry *entry);
-
- /**
- * Invoke the method
- * @param ht
- * @param return_value
- * @param return_value_ptr
- * @param this_ptr
- * @param return_value_used
- * @param tsrm_ls
- * @return integer
- */
- int invoke(INTERNAL_FUNCTION_PARAMETERS);
-
-private:
- /**
- * Classname (in case of a member function)
- * @var string
- */
- std::string _classname;
-
- /**
- * The function name
- * @var string
- */
- std::string _name;
-
- /**
- * The return type
- * @var Type
- */
- Type _type;
-
- /**
- * Function flags (like deprecated, abstract, private, etc)
- * @var int
- */
- int _flags;
-
- /**
- * The number of arguments
- * @var int
- */
- int _argc;
-
- /**
- * The number of required arguments
- * @var int
- */
- int _required;
-
- /**
- * The arguments
- * @var zend_arg_info[]
- */
- zend_arg_info *_argv;
-
- /**
- * Another attempt to fill internal function info
- * @param entry
- */
- void fill(zend_internal_function_info *info);
-
- /**
- * Process the arguments
- * @param arguments
- */
- void process(const std::initializer_list<Argument> &arguments);
-};
-
-/**
- * End of namespace
- */
-}
-
diff --git a/src/extension.cpp b/src/extension.cpp
index 2d9ef9f..1fd4b65 100644
--- a/src/extension.cpp
+++ b/src/extension.cpp
@@ -23,13 +23,13 @@ namespace Php {
* 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
- * instantiated for each parallel running request, and for which the
- * PHP engine allocates a certain amount of memory, and a magic
+ * instantiated for each parallel running request, and for which the
+ * PHP engine allocates a certain amount of memory, and a magic
* pointer that is passed and should be forwarded to every thinkable
- * PHP function.
+ * PHP function.
*
- * We don't like this architecture. We have our own request object
- * that makes much more sense, and that we use. However, we need
+ * We don't like this architecture. We have our own request object
+ * that makes much more sense, and that we use. However, we need
* to assign this object somewhere, so that's what we do in this
* one and only global variable
*/
@@ -39,7 +39,7 @@ ZEND_END_MODULE_GLOBALS(phpcpp)
/**
* And now we're going to define a macro. This also is a ridiculous
- * architecture from PHP to get access to a variable from the
+ * architecture from PHP to get access to a variable from the
* structure above.
*/
#ifdef ZTS
@@ -61,7 +61,7 @@ static ZEND_DECLARE_MODULE_GLOBALS(phpcpp)
* Function that must be defined to initialize the "globals"
* We do not have to initialize anything, but PHP needs to call this
* method (crazy)
- * @param globals
+ * @param globals
*/
static void php_phpcpp_init_globals(zend_phpcpp_globals *globals) {}
@@ -69,17 +69,17 @@ static void php_phpcpp_init_globals(zend_phpcpp_globals *globals) {}
/**
* Helper method to get back the current extension object
- * @return Extension
+ * @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);
+ // 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);
+ // the pointer to the extension is hidden in front of the name
+ return HiddenPointer<Extension>(module->name);
}
/**
@@ -90,12 +90,12 @@ static Extension *get_extension()
*/
static int extension_startup(INIT_FUNC_ARGS)
{
-
-
-
- // initialize and allocate the "global" variables
-// ZEND_INIT_MODULE_GLOBALS(hello, php_phpcpp_init_globals, NULL);
-
+
+
+
+ // initialize and allocate the "global" variables
+// ZEND_INIT_MODULE_GLOBALS(hello, php_phpcpp_init_globals, NULL);
+
// initialize the extension
return BOOL2SUCCESS(get_extension()->initialize());
}
@@ -108,6 +108,11 @@ static int extension_startup(INIT_FUNC_ARGS)
*/
static int extension_shutdown(SHUTDOWN_FUNC_ARGS)
{
+ std::cout << "extension_shutdown" << std::endl;
+
+ // @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());
}
@@ -132,6 +137,11 @@ static int request_startup(INIT_FUNC_ARGS)
*/
static int request_shutdown(INIT_FUNC_ARGS)
{
+ std::cout << "request_shutdown" << std::endl;
+
+ // @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());
}
@@ -190,6 +200,8 @@ Extension::Extension(const char *name, const char *version) : _ptr(this, name)
*/
Extension::~Extension()
{
+ std::cout << "destruct extension" << std::endl;
+
// deallocate functions
if (_entry->functions) delete[] _entry->functions;
@@ -210,6 +222,21 @@ Function &Extension::add(const char *name, const Function &function)
}
/**
+ * 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
+ */
+Function &Extension::add(const char *name, native_callback_0 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_1 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_2 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_3 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_4 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_5 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_6 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_7 function) { add(name, NativeFunction(function)); }
+
+/**
* Retrieve the module entry
* @return zend_module_entry
*/
diff --git a/src/function.cpp b/src/function.cpp
index 8612cf1..13d4d27 100644
--- a/src/function.cpp
+++ b/src/function.cpp
@@ -37,8 +37,11 @@ void invoke_function(INTERNAL_FUNCTION_PARAMETERS)
// construct parameters
Parameters params(ZEND_NUM_ARGS());
+ // @todo get the appropriate request (or environment)
+ Request request(NULL);
+
// call the appropriate object
- ret = function->invoke(params);
+ ret = function->invoke(request, params);
}
/**
diff --git a/src/includes.h b/src/includes.h
index 1a464e0..8d83752 100644
--- a/src/includes.h
+++ b/src/includes.h
@@ -42,11 +42,9 @@
#include "../include/arguments.h"
#include "../include/parameters.h"
#include "../include/function.h"
-#include "../include/functions.h"
#include "../include/extension.h"
/**
* Interface files for internal use only
*/
-#include "callable.h"
-#include "arginfo.h"
+#include "nativefunction.h"
diff --git a/src/nativefunction.h b/src/nativefunction.h
new file mode 100644
index 0000000..7f36608
--- /dev/null
+++ b/src/nativefunction.h
@@ -0,0 +1,88 @@
+/**
+ * NativeFunction.h
+ *
+ * The NativeFunction class is an extension of the Function class that
+ * forwards the function call directly to a native function in C/C++
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace Php {
+
+/**
+ * Class definition
+ */
+class NativeFunction : public Function
+{
+public:
+ /**
+ * Constructor
+ * @param function
+ */
+ NativeFunction(native_callback_0 function) : _type(0) { _function.f0 = function; }
+ NativeFunction(native_callback_1 function) : _type(1) { _function.f1 = function; }
+ NativeFunction(native_callback_2 function) : _type(2) { _function.f2 = function; }
+ NativeFunction(native_callback_3 function) : _type(3) { _function.f3 = function; }
+ NativeFunction(native_callback_4 function) : _type(4) { _function.f4 = function; }
+ NativeFunction(native_callback_5 function) : _type(5) { _function.f5 = function; }
+ NativeFunction(native_callback_6 function) : _type(6) { _function.f6 = function; }
+ NativeFunction(native_callback_7 function) : _type(7) { _function.f7 = function; }
+
+ /**
+ * Destructor
+ */
+ virtual ~NativeFunction() {}
+
+ /**
+ * Method that gets called every time the function is executed
+ * @param request Request environment
+ * @param params The parameters that were passed
+ * @return Variable Return value
+ */
+ virtual Value invoke(Request &request, Parameters &params)
+ {
+ switch (_type) {
+ case 0: _function.f0(); return Value();
+ case 1: _function.f1(params); return Value();
+ case 2: _function.f2(request); return Value();
+ case 3: _function.f3(request, params); return Value();
+ case 4: return _function.f4();
+ case 5: return _function.f5(params);
+ case 6: return _function.f6(request);
+ case 7: return _function.f7(request, params);
+ default: return Value();
+ }
+ }
+
+private:
+ /**
+ * Union of supported callbacks
+ * One of the callbacks will be set
+ */
+ union {
+ native_callback_0 f0;
+ native_callback_1 f1;
+ native_callback_2 f2;
+ native_callback_3 f3;
+ native_callback_4 f4;
+ native_callback_5 f5;
+ native_callback_6 f6;
+ native_callback_7 f7;
+ } _function;
+
+ /**
+ * The callback that is set
+ * @var integer
+ */
+ int _type;
+};
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/tests/simple/simple.cpp b/tests/simple/simple.cpp
index a33b220..311ce4c 100644
--- a/tests/simple/simple.cpp
+++ b/tests/simple/simple.cpp
@@ -15,14 +15,12 @@
*/
using namespace std;
-static int my_plus(int a, int b)
+static Php::Value my_plus(Php::Parameters &params)
{
- return a + b;
-}
-
-static std::string my_concat(std::string &a, std::string &b)
-{
- return a + b;
+ string p1 = params[0];
+ string p2 = params[1];
+
+ return p1 + p2;
}
class MyCustomFunction : public Php::Function
@@ -45,7 +43,7 @@ extern "C"
cout << "b" << endl;
// define the functions
-// extension.add("my_plus", my_plus);
+ extension.add("my_plus", my_plus);
// extension.add("my_concat", my_concat);
extension.add("my_custom", MyCustomFunction());
diff --git a/tests/simple/simple.php b/tests/simple/simple.php
index bdf2b74..fc552fd 100644
--- a/tests/simple/simple.php
+++ b/tests/simple/simple.php
@@ -10,7 +10,7 @@ class XXX
$myvar = "hoi";
-$result = hallo($myvar, 1, 2, 3, "blabla", new XXX());
+$result = my_plus($myvar, 1, 2, 3, "blabla", new XXX());
echo("myvar = $myvar\n");
diff --git a/tests/simple/test.cpp b/tests/simple/test.cpp
deleted file mode 100644
index dbae91e..0000000
--- a/tests/simple/test.cpp
+++ /dev/null
@@ -1,298 +0,0 @@
-#include <iostream>
-#include <functional>
-#include <sstream>
-#include <vector>
-#include <map>
-#include <stdlib.h>
-
-using namespace std;
-
-/**
- * Example function that adds numbers
- * @param a A number
- * @param b A different number
- * @return Sum of both parameters
- */
-int my_plus(int a, int b)
-{
- cout << "my_plus(" << a << ", " << b << ")" << endl;
-
- return a + b;
-}
-
-/**
- * Another example function that concatenates strings
- * @param a A text
- * @param b A different text
- * @return Concattenation
- */
-const string my_concat(const string &a, const string &b)
-{
- cout << "my_concat(" << a << ", " << b << ")" << endl;
-
- return a + b;
-}
-
-/**
- * Value class that can automatically convert objects between many
- * different types
- */
-class Value
-{
-private:
- /**
- * Internal representation
- * @var _value
- */
- string _value;
-
-public:
- /**
- * Constructor based on string
- * @param text
- */
- Value(const string &text) : _value(text) {}
-
- /**
- * Constructor based on string
- * @param text
- */
- Value(const char *text) : _value(text) {}
-
- /**
- * Constructor based on int
- * @param integer
- */
- Value(int value)
- {
- ostringstream s;
- s << value;
- _value = s.str();
- }
-
- /**
- * Destructor
- */
- virtual ~Value() {}
-
- /**
- * Cast to integer
- * @return Numeric representation
- */
- operator int ()
- {
- return atoi(_value.c_str());
- }
-
- /**
- * Cast to string
- * @return String representation
- */
- operator const string& ()
- {
- return _value;
- }
-};
-
-/**
- * Simple wrapper around a function
- */
-class Function
-{
-private:
- /**
- * The actual function
- *
- * Note: there must be a much smarter way to achieve the same thing,
- * we just want to have a single member that holds the function
- *
- * @var _function
- */
- union F {
- // union members
- function<Value()> r0;
- function<Value(Value&)> r1;
- function<Value(Value&,Value&)> r2;
- function<void()> v0;
- function<void(Value&)> v1;
- function<void(Value&,Value&)> v2;
-
- // constructors
- F() {}
- F(function<Value()> &f) { r0 = f; }
- F(function<Value(Value&)> &f) { r1 = f; }
- F(function<Value(Value&,Value&)> &f) { r2 = f; }
- F(function<void()> &f) { v0 = f; }
- F(function<void(Value&)> &f) { v1 = f; }
- F(function<void(Value&,Value&)> &f) { v2 = f; }
-
- // destructor
- ~F();
-
- // assignment operator
-// F &operator=(function<Value()> &f) { r0 = f; return *this; }
-// F &operator=(function<Value(Value&)> &f) { r1 = f; return *this; }
-// F &operator=(function<Value(Value&,Value&)> &f) { r2 = f; return *this; }
-
- } _function;
-
- /**
- * Is the object in a valid state
- * @var bool
- */
- bool _valid;
-
- /**
- * The number of arguments that the function required
- * @var _argc
- */
- int _argc;
-
- /**
- * Does the function return something?
- * @var _return;
- */
- bool _return;
-
-public:
- /**
- * Contructor
- * @param f
- */
- Function(function<Value()> &f) : _function(f)
- {
- _argc = 0;
- _return = true;
- _valid = true;
- }
-
- /**
- * Contructor
- * @param f
- */
- Function(function<Value(Value&)> &f) : _function(f)
- {
- _argc = 1;
- _return = true;
- }
-
- /**
- * Contructor
- * @param f
- */
- Function(function<Value(Value&,Value&)> &f) : _function(f)
- {
- _argc = 2;
- _return = true;
- }
-
- /**
- * Move constructor
- * @param f
- */
- Function(const Function &&f)
- {
- // copy params
- _argc = f._argc;
- _return = f._return;
-
- switch (_argc) {
- case 0: _function.r0 = f._function.r0; break;
- case 1: _function.r1 = f._function.r1; break;
- case 2: _function.r2 = f._function.r2; break;
- }
- }
-
- /**
- * Destructor
- */
- virtual ~Function() {}
-
- /**
- * Operator to call the function
- * @param args
- */
- void operator()(vector<Value> args)
- {
- switch (_argc) {
- case 0: _function.r0();
- case 1: _function.r1(args[0]);
- case 2: _function.r2(args[0], args[1]);
- }
- }
-};
-
-/**
- * Class that stores pointers to functions
- */
-class Functions
-{
-private:
- /**
- * Map of functions
- * @var map
- */
- map<string,Function> _functions;
-
-public:
- /**
- * Constructor
- */
- Functions() {}
-
- /**
- * Destructor
- */
- virtual ~Functions() {}
-
- /**
- * Add a function
- * @param name The function name
- * @param func The function to call
- */
- void add(const string &name, function<Value(Value&,Value&)> f)
- {
- _functions.insert(pair<string,Function>(name, Function(f)));
- }
-
- /**
- * Call the functions
- * @param args
- */
- Value operator()(vector<Value> args)
- {
- for (auto it = _functions.begin(); it != _functions.end(); it++)
- {
- it->second(args);
- }
-
- return Value(123);
- }
-
-};
-
-/**
- * Main function
- * @param argc
- * @param argv
- */
-int main(int argc, char *argv[])
-{
- // create a vector of arguments
- vector<Value> arguments;
-
- // fill the arguments
- for (int i=1; i<argc-1; i++) arguments.push_back(argv[i]);
-
- // now register all functions
- Functions functions;
- functions.add("plus", my_plus);
- functions.add("concat", my_concat);
-
- // call all functions
- functions(arguments);
-
- // done
- return 0;
-}
-