diff options
-rw-r--r-- | include/function.h | 2 | ||||
-rw-r--r-- | include/value.h (renamed from include/variable.h) | 54 | ||||
-rw-r--r-- | phpcpp.h | 2 | ||||
-rw-r--r-- | src/callable.cpp | 42 | ||||
-rw-r--r-- | src/callable.h | 14 | ||||
-rw-r--r-- | src/includes.h | 2 | ||||
-rw-r--r-- | src/value.cpp | 405 | ||||
-rw-r--r-- | src/variable.cpp | 286 |
8 files changed, 491 insertions, 316 deletions
diff --git a/include/function.h b/include/function.h index 1a35671..a7dc9b0 100644 --- a/include/function.h +++ b/include/function.h @@ -91,7 +91,7 @@ public: * @param arguments The actual arguments that were passed * @return Variable Return value */ - virtual Variable invoke(const Request *request, const std::initializer_list<Variable> &arguments) + virtual Value invoke(const Request *request, const std::initializer_list<Value> &arguments) { } diff --git a/include/variable.h b/include/value.h index fccab9c..fe370dc 100644 --- a/include/variable.h +++ b/include/value.h @@ -1,7 +1,18 @@ /** - * Variable.h + * Value.h * - * Base class for variables that are stored in the Zend engine. + * Base class for values that are stored in the Zend engine. One instance + * of the value class represents a variable that exists in user space in + * the PHP environment, for example as global variable, local variable + * inside a function or as a member of an object or an array. + * + * A value can be a scalar or a more complicated structure like an object + * or an array. + * + * Internally, the Zend engine works with "zval" objects for this. These "zval" + * object hold a reference counter and a reference setting. The PHP-CPP Value + * class takes care of doing this, so all you need to do is use objects of + * this class. * * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> * @copyright 2013 Copernica BV @@ -20,89 +31,89 @@ namespace PhpCpp { /** * Class definition */ -class Variable +class Value { public: /** * Empty constructor (value = NULL) */ - Variable(); + Value(); /** * Constructor based on integer value * @param value */ - Variable(int value); + Value(int value); /** * Constructor based on boolean value * @param value */ - Variable(bool value); + Value(bool value); /** * Constructor based on string value * @param value */ - Variable(const std::string &value); + Value(const std::string &value); /** * Constructor based on decimal value * @param value */ - Variable(double value); + Value(double value); /** * Wrap object around zval * @param zval */ - Variable(struct _zval_struct *zval); + Value(struct _zval_struct *zval); /** * Copy constructor * @param value */ - Variable(const Variable &that); + Value(const Value &that); /** * Destructor */ - virtual ~Variable(); + virtual ~Value(); /** * Assignment operator * @param value - * @return Variable + * @return Value */ - virtual Variable &operator=(const Variable &value); + virtual Value &operator=(const Value &value); /** * Assignment operator * @param value - * @return Variable + * @return Value */ - Variable &operator=(int value); + Value &operator=(int value); /** * Assignment operator * @param value - * @return Variable + * @return Value */ - Variable &operator=(bool value); + Value &operator=(bool value); /** * Assignment operator * @param value - * @return Variable + * @return Value */ - Variable &operator=(const std::string &value); + Value &operator=(const std::string &value); /** * Assignment operator * @param value - * @return Variable + * @return Value */ - Variable &operator=(double value); + Value &operator=(double value); /** * The type of object @@ -224,7 +235,6 @@ protected: * @var struct zval */ struct _zval_struct *_val; - }; /** @@ -20,7 +20,7 @@ #include <phpcpp/type.h> #include <phpcpp/request.h> #include <phpcpp/argument.h> -#include <phpcpp/variable.h> +#include <phpcpp/value.h> #include <phpcpp/function.h> #include <phpcpp/extension.h> diff --git a/src/callable.cpp b/src/callable.cpp index 05545f1..494e9ed 100644 --- a/src/callable.cpp +++ b/src/callable.cpp @@ -15,7 +15,13 @@ namespace PhpCpp { /** * Function that is called by the Zend engine every time that a function gets called - * @param mixed + * @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) { @@ -26,14 +32,16 @@ void invoke_callable(INTERNAL_FUNCTION_PARAMETERS) // callable right in front of the function name - we retrieve it back Callable *callable = *((Callable **)(function - sizeof(Callable *))); - std::cout << "callable: " << callable << std::endl; - - - return; + // 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) @@ -48,6 +56,10 @@ void Callable::fill(zend_function_entry *entry) /** * 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) @@ -64,6 +76,9 @@ void Callable::fill(zend_internal_function_info *info) /** * 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) @@ -90,6 +105,23 @@ void Callable::process(const std::initializer_list<Argument> &arguments) } /** + * 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) +{ + + + +} + +/** * End of namespace */ } diff --git a/src/callable.h b/src/callable.h index 2af7d41..8bce37e 100644 --- a/src/callable.h +++ b/src/callable.h @@ -96,6 +96,20 @@ public: */ 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); + + +int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC private: /** diff --git a/src/includes.h b/src/includes.h index 0666dc4..ae98c43 100644 --- a/src/includes.h +++ b/src/includes.h @@ -34,7 +34,7 @@ #include "../include/type.h" #include "../include/request.h" #include "../include/argument.h" -#include "../include/variable.h" +#include "../include/value.h" #include "../include/function.h" #include "../include/extension.h" diff --git a/src/value.cpp b/src/value.cpp new file mode 100644 index 0000000..a682dca --- /dev/null +++ b/src/value.cpp @@ -0,0 +1,405 @@ +/** + * Value.cpp + * + * Implementation for the Value class, which wraps a PHP userspace + * value (a 'zval' in Zend's terminology) into a C++ object + * + * Reminder for the implementer: + * + * A 'zval' is an object that represents a _value_ in the PHP user space, + * and thus not a variable. A 'value' or 'zval' can be used by many + * different variables at the same time. The 'refcount' property of the + * zval holds the number of variables ($a, $b, $c, et cetera) that are + * all linked to the same value. With this system, PHP can implement copy + * on write behavior. + * + * Next to the refcount, the zval also holds a is_ref property, which is + * set to true if all variables linked to the value are references of each + * other. Thus is $a, $b and $c all point to the same variable, and is_ref + * is set to true, changing the value means that the $a, $b and $c value + * are all updated. If is_res was false, a change to $a would not mean a + * change to $b, and the zval should have been copied first. + * + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ +#include "includes.h" + +/** + * Set up namespace + */ +namespace PhpCpp { + +/** + * Constructor (value = NULL) + */ +Value::Value() +{ + // create a null zval + MAKE_STD_ZVAL(_val); + ZVAL_NULL(_val); +} + +/** + * Constructor based on integer value + * @param value + */ +Value::Value(int value) +{ + // create an integer zval + MAKE_STD_ZVAL(_val); + ZVAL_LONG(_val, value); +} + +/** + * Constructor based on boolean value + * @param value + */ +Value::Value(bool value) +{ + // create a boolean zval + MAKE_STD_ZVAL(_val); + ZVAL_BOOL(_val, value); +} + +/** + * Constructor based on string value + * @param value + */ +Value::Value(const std::string &value) +{ + // create a string zval + MAKE_STD_ZVAL(_val); + ZVAL_STRINGL(_val, value.c_str(), value.size(), 1); +} + +/** + * Constructor based on decimal value + * @param value + */ +Value::Value(double value) +{ + // create a double zval + MAKE_STD_ZVAL(_val); + ZVAL_DOUBLE(_val, value); +} + +/** + * Wrap object around zval + * @param zval + */ +Value::Value(struct _zval_struct *zval) +{ + // just copy the zval into this object + _val = zval; + + // we see ourselves as reference too + ZVAL_ADDREF_P(_val); +} + +/** + * Copy constructor + * @param value + */ +Value::Value(const Value &that) +{ + // just copy the zval, and the refcounter + _val = that._val; + + // and we have one more reference + ZVAL_ADDREF_P(_val); +} + +/** + * Destructor + */ +Value::~Value() +{ + // destruct the zval (this function will decrement the reference counter, + // and only destruct if there are no other references left) + zval_ptr_dtor(_val); +} + +/** + * Assignment operator + * @param value + * @return Value + */ +Value &Value::operator=(const Value &value) +{ + // skip self assignment + if (this == &value) return *this; + + // destruct the zval (this function will decrement the reference counter, + // and only destruct if there are no other references left) + zval_ptr_dtor(_val); + + // just copy the zval, and the refcounter + _val = that._val; + + // and we have one more reference + ZVAL_ADDREF_P(_val); + + // done + return *this; +} + +/** + * Assignment operator + * @param value + * @return Value + */ +Value &Value::operator=(int value) +{ + // if this is not a reference variable, we should detach it to implement copy on write + SEPARATE_ZVAL_IF_NOT_REF(&_val); + + // deallocate current zval (without cleaning the zval structure) + zval_dtor(_val); + + // set new value + ZVAL_LONG(_val, value); + + // done + return *this; +} + +/** + * Assignment operator + * @param value + * @return Value + */ +Value &Value::operator=(bool value) +{ + // if this is not a reference variable, we should detach it to implement copy on write + SEPARATE_ZVAL_IF_NOT_REF(&_val); + + // deallocate current zval (without cleaning the zval structure) + zval_dtor(_val); + + // set new value + ZVAL_BOOL(_val, value); + + // done + return *this; +} + +/** + * Assignment operator + * @param value + * @return Value + */ +Value &Value::operator=(const std::string &value) +{ + // if this is not a reference variable, we should detach it to implement copy on write + SEPARATE_ZVAL_IF_NOT_REF(&_val); + + // deallocate current zval (without cleaning the zval structure) + zval_dtor(_val); + + // set new value + ZVAL_STRINGL(_val, value.c_str(), value.size(), 1); + + // done + return *this; +} + +/** + * Assignment operator + * @param value + * @return Value + */ +Value &Value::operator=(double value) +{ + // if this is not a reference variable, we should detach it to implement copy on write + SEPARATE_ZVAL_IF_NOT_REF(&_val); + + // deallocate current zval (without cleaning the zval structure) + zval_dtor(_val); + + // set new value + ZVAL_DOUBLE(_val, value); + + // done + return *this; +} + +/** + * The type of object + * @return Type + */ +Type Value::type() +{ + return (Type)Z_TYPE_P(_val); +} + +/** + * Change the internal type + * @param type + */ +void Value::setType(Type type) +{ + // skip if nothing changes + if (this->type() == type) return; + + // run the conversion + switch (type) { + case nullType: convert_to_null(_val); break; + case intType: convert_to_long(_val); break; + case decimalType: convert_to_double(_val); break; + case boolType: convert_to_bool(_val); break; + case arrayType: convert_to_array(_val); break; + case objectType: convert_to_object(_val); break; + case stringType: convert_to_string(_val); break; + case resourceType: convert_to_resource(_val); break; + case constantType: convert_to_constant(_val); break; + case constantArrayType: convert_to_constant_array(_val); break; + case callableType: convert_to_callable(_val); break; + } +} + +/** + * Is this a NULL value? + * @return bool + */ +bool Value::isNull() +{ + return Z_TYPE_P(_val) == IS_NULL; +} + +/** + * Is this an integer value? + * @return bool + */ +bool Value::isInt() +{ + return Z_TYPE_P(_val) == IS_LONG; +} + +/** + * Is this a boolean value? + * @return bool + */ +bool Value::isBool() +{ + return Z_TYPE_P(_val) == IS_BOOL; +} + +/** + * Is this a string value? + * @return bool + */ +bool Value::isString() +{ + return Z_TYPE_P(_val) == IS_STRING; +} + +/** + * Is this a decimal value? + * @return bool + */ +bool Value::isDecimal() +{ + return Z_TYPE_P(_val) == IS_DOUBLE; +} + +/** + * Is this an object value? + * @return bool + */ +bool Value::isObject() +{ + return Z_TYPE_P(_val) == IS_OBJECT; +} + +/** + * Is this an array value? + * @return bool + */ +bool Value::isArray() +{ + return Z_TYPE_P(_val) == IS_ARRAY; +} + +/** + * Retrieve the value as integer + * @return int + */ +int Value::intValue() +{ + // already an int? + if (isInt()) return Z_LVAL_P(_val); + + // make a copy + Value copy(*this); + + // convert the copy to an int + copy.setType(intType); + + // return the int value + return copy.intValue(); +} + +/** + * Retrieve the value as boolean + * @return bool + */ +bool Value::boolValue() +{ + // already a bool? + if (isBool()) return Z_BVAL_P(_val); + + // make a copy + Value copy(*this); + + // convert the copy to an int + copy.setType(boolType); + + // return the int value + return copy.intValue(); +} + +/** + * Retrieve the value as string + * @return string + */ +std::string Value::stringValue() +{ + // already a string? + if (isString()) return std::string(Z_STRVAL_P(_val), Z_STRLEN_T(_val)); + + // make a copy + Value copy(*this); + + // convert the copy to an string + copy.setType(stringType); + + // return the string value + return copy.stringValue(); +} + +/** + * Retrieve the value as decimal + * @return double + */ +double Value::decimalValue() +{ + // already a double + if (isDecimal()) return Z_DVAL_P(_val); + + // make a copy + Value copy(*this); + + // convert the copy to an double + copy.setType(decimalType); + + // return the decimal value + return copy.decimalValue(); +} + +/** + * End of namespace + */ +} + diff --git a/src/variable.cpp b/src/variable.cpp deleted file mode 100644 index 4735267..0000000 --- a/src/variable.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/** - * Variable.cpp - * - * Implementation for the Variable class, which wraps a PHP userspace - * variable (a 'zval' in Zend's terminology) into a C++ object - * - * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> - * @copyright 2013 Copernica BV - */ -#include "includes.h" - -/** - * Set up namespace - */ -namespace PhpCpp { - -/** - * Constructor (value = NULL) - */ -Variable::Variable() -{ - // create a null zval - MAKE_STD_ZVAL(_val); - ZVAL_NULL(_val); -} - -/** - * Constructor based on integer value - * @param value - */ -Variable::Variable(int value) -{ - // create an integer zval - MAKE_STD_ZVAL(_val); - ZVAL_LONG(_val, value); -} - -/** - * Constructor based on boolean value - * @param value - */ -Variable::Variable(bool value) -{ - // create a boolean zval - MAKE_STD_ZVAL(_val); - ZVAL_BOOL(_val, value); -} - -/** - * Constructor based on string value - * @param value - */ -Variable::Variable(const std::string &value) -{ - // create a string zval - MAKE_STD_ZVAL(_val); - ZVAL_STRINGL(_val, value.c_str(), value.size(), 1); -} - -/** - * Constructor based on decimal value - * @param value - */ -Variable::Variable(double value) -{ - // create a double zval - MAKE_STD_ZVAL(_val); - ZVAL_DOUBLE(_val, value); -} - -/** - * Wrap object around zval - * @param zval - */ -Variable::Variable(struct _zval_struct *zval) -{ - // just copy the zval into this object - _val = zval; -} - -/** - * Copy constructor - * @param value - */ -Variable::Variable(const Variable &that) -{ - // @todo implementation, what should we do - - -} - -/** - * Destructor - */ -Variable::~Variable() -{ - // @todo implementation - -} - -/** - * Assignment operator - * @param value - * @return Variable - */ -Variable &Variable::operator=(const Variable &value) -{ - // skip self assignment - if (this == &value) return *this; - - // @todo implementation - - - // done - return *this; -} - -/** - * Assignment operator - * @param value - * @return Variable - */ -Variable &Variable::operator=(int value) -{ - // @todo implementation - - // done - return *this; -} - -/** - * Assignment operator - * @param value - * @return Variable - */ -Variable &Variable::operator=(bool value) -{ - // @todo implementation - - - // done - return *this; -} - -/** - * Assignment operator - * @param value - * @return Variable - */ -Variable &Variable::operator=(const std::string &value) -{ - // @todo implementation - - - // done - return *this; -} - -/** - * Assignment operator - * @param value - * @return Variable - */ -Variable &Variable::operator=(double value) -{ - // @todo implementation - - - // done - return *this; -} - -/** - * The type of object - * @return Type - */ -Type Variable::type() -{ - return (Type)Z_TYPE_P(_val); -} - -/** - * Change the internal type - * @param type - */ -void Variable::setType(Type type) -{ - // @todo implementation - -} - -/** - * Is this a NULL value? - * @return bool - */ -bool Variable::isNull() -{ - return Z_TYPE_P(_val) == IS_NULL; -} - -/** - * Is this an integer value? - * @return bool - */ -bool Variable::isInt() -{ - return Z_TYPE_P(_val) == IS_LONG; -} - -/** - * Is this a boolean value? - * @return bool - */ -bool Variable::isBool() -{ - return Z_TYPE_P(_val) == IS_BOOL; -} - -/** - * Is this a string value? - * @return bool - */ -bool Variable::isString() -{ - return Z_TYPE_P(_val) == IS_STRING; -} - -/** - * Is this a decimal value? - * @return bool - */ -bool Variable::isDecimal() -{ - return Z_TYPE_P(_val) == IS_DOUBLE; -} - -/** - * Is this an object value? - * @return bool - */ -bool Variable::isObject() -{ - return Z_TYPE_P(_val) == IS_OBJECT; -} - -/** - * Is this an array value? - * @return bool - */ -bool Variable::isArray() -{ - return Z_TYPE_P(_val) == IS_ARRAY; -} - -/** - * Retrieve the value as integer - * @return int - */ -int Variable::intValue() -{ - // @todo implementation -} - -/** - * Retrieve the value as boolean - * @return bool - */ -bool Variable::boolValue() -{ - // @todo implementation -} - -/** - * Retrieve the value as string - * @return string - */ -std::string Variable::stringValue() -{ - // @todo implementation -} - -/** - * End of namespace - */ -} - |