diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2013-09-08 16:26:11 -0700 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2013-09-08 16:26:11 -0700 |
commit | df2520e4b2c87e2302ee4c6cec1e672091efebfb (patch) | |
tree | f3bcd4fa7c4d0c6ee601268ceca4d6841ed90d0d /include | |
parent | eb86ac350756afeffa0e2db8be87876d35bc40a8 (diff) |
Refactoring function class, and making it even more easy to directly enable native C functions in PHP
Diffstat (limited to 'include')
-rw-r--r-- | include/argument.h | 127 | ||||
-rw-r--r-- | include/arguments.h | 69 | ||||
-rw-r--r-- | include/extension.h | 45 | ||||
-rw-r--r-- | include/function.h | 108 | ||||
-rw-r--r-- | include/functions.h | 2 | ||||
-rw-r--r-- | include/hiddenpointer.h | 166 | ||||
-rw-r--r-- | include/member.h | 2 | ||||
-rw-r--r-- | include/parameters.h | 38 | ||||
-rw-r--r-- | include/request.h | 2 | ||||
-rw-r--r-- | include/type.h | 2 | ||||
-rw-r--r-- | include/value.h | 2 |
11 files changed, 435 insertions, 128 deletions
diff --git a/include/argument.h b/include/argument.h index 5c0c23f..7a95f7d 100644 --- a/include/argument.h +++ b/include/argument.h @@ -9,14 +9,14 @@ */ /** - * Set up namespace + * Forward declaration */ -namespace PhpCpp { +struct _zend_arg_info; /** - * Forward definitions + * Set up namespace */ -class ArgInfo; +namespace Php { /** * Class definition @@ -25,105 +25,72 @@ class Argument { 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? + * Prevent copying + * @param argument */ - Argument(const std::string &name, const std::string &classname, bool null = true, bool ref = false); - + Argument(const Argument &argument) = delete; + /** - * Constructor if the argument can be anything - * Note that only arrayType and callableType are supported type-hints - * @param name Name of the argument - * @param type Type hint (arrayType or callableType) - * @param ref Is this a pass-by-reference argument? + * Move constructor + * @param argument */ - Argument(const std::string &name, Type type = nullType, bool ref = false); - + Argument(Argument &&argument); + /** - * Constructor if the argument can be anything - * @param name Name of the argument - * @param ref Is this a pass-by-reference argument? + * Destructor */ - Argument(const std::string &name, bool ref = false); + virtual ~Argument() {}; /** - * Copy constructor - * @param argument The argument to copy + * Change the name + * @param name + * @return Argument */ - Argument(const Argument &argument) - { - // copy members - _refcount = argument._refcount; - _info = argument._info; - - // increase references - (*_refcount)++; - } + Argument &name(const char *name); /** - * Destructor + * Change the type + * @param type + * @return Argument */ - virtual ~Argument() - { - // cleanup current object - cleanup(); - } - + Argument &type(Type type = nullType); + /** - * Copy operator - * @param argument The argument to copy + * Require the parameter to be a certain class + * @param name Name of the class + * @param null Are null values allowed? * @return Argument */ - Argument &operator=(const Argument &argument) - { - // skip self assignment - if (this == &argument) return *this; - - // clean up current object - cleanup(); - - // copy members - _refcount = argument._refcount; - _info = argument._info; - - // increase references - (*_refcount)++; - - // done - return *this; - } + Argument &object(const char *classname, bool null = true); /** - * Retrieve argument info - * @return ArgInfo - * @internal + * Is this a by-ref argument? + * @param bool Mark as by-ref variable + * @return Argument */ - ArgInfo *internal() const - { - return _info; - } - -private: + Argument &byref(bool value = true); + /** - * Number of references - * @var int + * Prevent copy + * @param argument The argument to copy + * @return Argument */ - int *_refcount; - + Argument &operator=(const Argument &argument) = delete; + +protected: /** - * Pointer to the implementation - * @var ArgInfo + * Protected constructor, to prevent that users can instantiate the + * argument object themselves + * @param info */ - ArgInfo *_info; - + Argument(struct _zend_arg_info *info) : _info(info) {} + +private: /** - * Remove one reference from the object + * The argument info + * @var zend_arg_info */ - void cleanup(); - + struct _zend_arg_info *_info; }; /** diff --git a/include/arguments.h b/include/arguments.h index 65476c3..e57903f 100644 --- a/include/arguments.h +++ b/include/arguments.h @@ -9,26 +9,85 @@ */ /** + * Forward declaration + */ +struct _zend_arg_info; + +/** * Set up namespace */ -namespace PhpCpp { +namespace Php { /** * Class definition */ -class Arguments : public std::vector<Value> +class Arguments { public: /** * Constructor - * @param argc The number of arguments + * @param min The min number of arguments + * @param max The max number of arguments + */ + Arguments(int min, int max); + + /** + * No copy or move operations + * @param arguments */ - Arguments(int argc); + Arguments(const Arguments &arguments) = delete; + Arguments(Arguments &&arguments) = delete; /** * Destructor */ - virtual ~Arguments() {} + virtual ~Arguments(); + + /** + * Number of arguments + * @return int + */ + int argc() + { + return _max; + } + + /** + * Number of required arguments + * @return int + */ + int required() + { + return _min; + } + + /** + * Get access to internal data + * @return zend_arg_info* + */ + struct _zend_arg_info *internal() + { + return _argv; + } + +private: + /** + * Min number of arguments + * @var integer + */ + int _min; + + /** + * Max number of arguments + * @var integer + */ + int _max; + + /** + * The arguments + * @var zend_arg_info[] + */ + struct _zend_arg_info *_argv; }; diff --git a/include/extension.h b/include/extension.h index 1962fd7..5dabb8e 100644 --- a/include/extension.h +++ b/include/extension.h @@ -26,7 +26,7 @@ struct _zend_module_entry; /** * Set up namespace */ -namespace PhpCpp { +namespace Php { /** * Class definition @@ -40,7 +40,7 @@ public: * @param version Extension version string * @param functions The functions that are defined */ - Extension(const char *name, const char *version, const Functions &functions); + Extension(const char *name = NULL, const char *version = NULL); /** * No copy'ing and no moving @@ -51,7 +51,7 @@ public: /** * Destructor */ - virtual ~Extension() { delete _entry; } + virtual ~Extension(); /** * Initialize the extension. @@ -117,6 +117,8 @@ public: // // // and initialize it // return _request->initialize(); + + return true; } /** @@ -140,10 +142,47 @@ public: // // // done // return result; + + return true; } + /** + * Add a function to the extension + * + * It is only possible to create functions during the initialization of + * the library, before the Extension::module() method is called. + * + * @param name Name of the function + * @param function The function to add + * @return Function The added function + */ + Function &add(const char *name, const Function &function); + + /** + * Retrieve the module entry + * + * This is the memory address that should be exported by the get_module() + * function. + * + * @return _zend_module_entry + */ + _zend_module_entry *module(); + + private: /** + * Map of function objects defined in the library + * @var map + */ + std::map<const char *,Function> _functions; + + /** + * Hidden pointer to self + * @var HiddenPointer + */ + HiddenPointer<Extension> _ptr; + + /** * The information that is passed to the Zend engine * * Although it would be slightly faster to not make this a pointer, this diff --git a/include/function.h b/include/function.h index ef185ce..67d2332 100644 --- a/include/function.h +++ b/include/function.h @@ -8,16 +8,17 @@ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> * @copyright 2013 Copernica BV */ - -/** - * Set up namespace - */ -namespace PhpCpp { /** * Forward definitions */ -class Callable; +struct _zend_function_entry; +struct _zend_internal_function_info; + +/** + * Set up namespace + */ +namespace Php { /** * Class definition @@ -27,22 +28,25 @@ class Function public: /** * Constructor - * @param name Name of the function - * @param arguments The arguments that can be passed to the function - */ - Function(const std::string &name, const std::initializer_list<Argument> &arguments); - - /** - * Constructor - * @param name Name of the function + * @param min Min number of arguments + * @param max Max number of arguments */ - Function(const char *name) : Function(name, {}) {} + Function(int min = 0, int max = 0) + { + // construct the arguments + _arguments = std::shared_ptr<Arguments>(new Arguments(min, max)); + } /** * No copy constructor * @param function The other function */ - Function(const Function &function) = delete; + Function(const Function &function) + { + // copy members + _arguments = function._arguments; + _type = function._type; + } /** * Move constructor @@ -50,46 +54,80 @@ public: */ Function(Function &&function) { - _callable = function._callable; - function._callable = nullptr; + // copy arguments + _arguments = function._arguments; + _type = function._type; + + // no longer need the other arguments + function._arguments.reset(); } /** * Destructor */ - virtual ~Function(); + virtual ~Function() {} /** - * No assignment operator + * Assignment operator * @param function The other function * @return Function */ - Function &operator=(const Function &function) {} + Function &operator=(const Function &function) + { + // skip self reference + if (this == &function) return *this; + + // copy members + _arguments = function._arguments; + _type = function._type; + + // done + return *this; + } /** * Method that gets called every time the function is executed - * @param request The request during which the call was made - * @param arguments The actual arguments that were passed + * @param params The parameters that were passed * @return Variable Return value */ - virtual Value invoke(const Request *request, const std::initializer_list<Value> &arguments); - - /** - * Get access to the internal object - * @return Callable - * @internal - */ - Callable *internal() const + virtual Value invoke(Parameters ¶ms) { - return _callable; + return 0; } protected: /** - * Pointer to the callable object - * @var smart_ptr + * Suggestion for the return type + * @var Type + */ + Type _type = nullType; + + /** + * Pointer to the arguments + * @var shared_ptr */ - Callable *_callable; + std::shared_ptr<Arguments> _arguments; + +private: + /** + * Fill a function entry + * @param name Name of the function + * @param entry Entry to be filled + */ + void fill(const char *name, struct _zend_function_entry *entry); + + /** + * Fill function info + * @param name Name of the function + * @param info Info object to be filled + */ + void fill(const char *name, struct _zend_internal_function_info *info); + + /** + * Extension has access to the private members + */ + friend class Extension; + }; /** diff --git a/include/functions.h b/include/functions.h index fc44f1c..69653b4 100644 --- a/include/functions.h +++ b/include/functions.h @@ -16,7 +16,7 @@ struct _zend_function_entry; /** * Set up namespace */ -namespace PhpCpp { +namespace Php { /** * Class definition diff --git a/include/hiddenpointer.h b/include/hiddenpointer.h new file mode 100644 index 0000000..bcb44ba --- /dev/null +++ b/include/hiddenpointer.h @@ -0,0 +1,166 @@ +/** + * 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 + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * 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); + + // 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 + * @param pointer + * @param text + */ + 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; + + // 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; + +}; + +/** + * End of namespace + */ +} + diff --git a/include/member.h b/include/member.h index d56b495..5166535 100644 --- a/include/member.h +++ b/include/member.h @@ -16,7 +16,7 @@ /** * Set up namespace */ -namespace PhpCpp { +namespace Php { /** * Forward definitions diff --git a/include/parameters.h b/include/parameters.h new file mode 100644 index 0000000..138d973 --- /dev/null +++ b/include/parameters.h @@ -0,0 +1,38 @@ +/** + * Parameters.h + * + * Wrapper around parameters that are passed to a + + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ + +/** + * Namespace + */ +namespace Php { + +/** + * Class definition + */ +class Parameters : public std::vector<Value> +{ +public: + /** + * Constructor + * @param argc Number of arguments + * @param tsrm_ls + */ + Parameters(int argc);// TSRMLS_DC); + + /** + * Destructor + */ + virtual ~Parameters() {} +}; + +/** + * End of namespace + */ +} + diff --git a/include/request.h b/include/request.h index f37a449..4183966 100644 --- a/include/request.h +++ b/include/request.h @@ -17,7 +17,7 @@ /** * Set up namespace */ -namespace PhpCpp { +namespace Php { /** * Forward definitions diff --git a/include/type.h b/include/type.h index 200d658..04e488b 100644 --- a/include/type.h +++ b/include/type.h @@ -11,7 +11,7 @@ /** * Set up namespace */ -namespace PhpCpp { +namespace Php { /** * Supported types for variables diff --git a/include/value.h b/include/value.h index 2cc9029..64f92df 100644 --- a/include/value.h +++ b/include/value.h @@ -26,7 +26,7 @@ struct _zval_struct; /** * Set up namespace */ -namespace PhpCpp { +namespace Php { /** * Forward definitions |