diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/base.h | 2 | ||||
-rw-r--r-- | include/class.h | 34 | ||||
-rw-r--r-- | include/classbase.h | 376 | ||||
-rw-r--r-- | include/interface.h | 6 | ||||
-rw-r--r-- | include/iterator.h | 2 | ||||
-rw-r--r-- | include/value.h | 2 |
6 files changed, 89 insertions, 333 deletions
diff --git a/include/base.h b/include/base.h index 1aed219..8b3e561 100644 --- a/include/base.h +++ b/include/base.h @@ -271,7 +271,7 @@ private: */ friend class Value; friend class Object; - friend class ClassBase; + friend class ClassImpl; }; diff --git a/include/class.h b/include/class.h index b9295ea..8bc034c 100644 --- a/include/class.h +++ b/include/class.h @@ -18,11 +18,7 @@ /** * Zend/SPL interfaces that we support */ -//extern struct _zend_class_entry *zend_ce_traversable; -//extern struct _zend_class_entry *zend_ce_aggregate; -//extern struct _zend_class_entry *zend_ce_iterator; extern struct _zend_class_entry *zend_ce_arrayaccess; -//extern struct _zend_class_entry *zend_ce_serializable; /** * Set up namespace @@ -132,6 +128,7 @@ public: * @param name Name of the method * @param flags Optional flags * @param args Argument descriptions + * @return Class Same object to allow chaining */ Class<T> &method(const char *name, int flags, const Arguments &args = {}) { ClassBase::method(name, flags | Abstract, args); return *this; } Class<T> &method(const char *name, const Arguments &args = {}) { ClassBase::method(name, Public | Abstract, args); return *this; } @@ -148,6 +145,7 @@ public: * @param name Name of the property * @param value Actual property value * @param flags Optional flags + * @return Class Same object to allow chaining */ Class<T> &property(const char *name, std::nullptr_t value, int flags = Public) { ClassBase::property(name, value, flags); return *this; } Class<T> &property(const char *name, int64_t value, int flags = Public) { ClassBase::property(name, value, flags); return *this; } @@ -178,6 +176,34 @@ public: Class<T> &property(const char *name, Value (T::*getter)() const, void (T::*setter)(const Value &value) ) { ClassBase::property(name, static_cast<getter_callback_1>(getter), static_cast<setter_callback_0>(setter)); return *this; } Class<T> &property(const char *name, Value (T::*getter)() , void (T::*setter)(const Value &value) const) { ClassBase::property(name, static_cast<getter_callback_0>(getter), static_cast<setter_callback_1>(setter)); return *this; } Class<T> &property(const char *name, Value (T::*getter)() const, void (T::*setter)(const Value &value) const) { ClassBase::property(name, static_cast<getter_callback_1>(getter), static_cast<setter_callback_1>(setter)); return *this; } + + /** + * Add a PHP interface to the class + * + * Note that the interface that you supply must already exist! Therefore + * you can only supply interfaces that you created in your own extension. + * + * @param interface Interface object + * @return Class Same object to allow chaining + */ +// Class<T> &implements(const Interface &interface) { ClassBase::implements(interface); return *this; } + + /** + * Add a base class + * + * Because PHP does not allow multiple inheritance, you can only add one + * base class. If you call this method more than once, the earlier base + * class is overridden. + * + * The base class that you supply must already be registered. And because + * your extension is most likely registered before any user space PHP scripts + * run, you can only specify built-in classes, or classes that you created + * in your own extension. + * + * @param name Name of the base class + * @return Class Same object to allow chaining + */ +// Class<T> &extends(const char *name) { ClassBase::extends(name); return *this; } private: /** diff --git a/include/classbase.h b/include/classbase.h index f4a6f22..e399efe 100644 --- a/include/classbase.h +++ b/include/classbase.h @@ -15,16 +15,6 @@ */ /** - * Forward declarations - */ -struct _zend_object_value; -struct _zend_object_handlers; -struct _zend_class_entry; -struct _zend_serialize_data; -struct _zend_unserialize_data; -union _zend_function; - -/** * Set up namespace */ namespace Php { @@ -62,9 +52,7 @@ typedef void (Base::*setter_callback_1)(const Php::Value &value) const; /** * Forward declarations */ -class Method; -class Member; -class Property; +class ClassImpl; /** * Class definition @@ -84,64 +72,31 @@ protected: * @param classname Class name * @param type Class type */ - ClassBase(const char *classname, ClassType type) : _name(classname), _type(type) {} + ClassBase(const char *classname, ClassType type); public: /** * Copy constructor * @param that */ - ClassBase(const ClassBase &that) : - _name(that._name), - _type(that._type), - _entry(that._entry), - _methods(that._methods), - _members(that._members), - _properties(that._properties) {} + ClassBase(const ClassBase &that) : _impl(that._impl) {} /** * Move constructor * @param that */ - ClassBase(ClassBase &&that) : - _name(std::move(that._name)), - _type(that._type), - _entry(that._entry), - _methods(std::move(that._methods)), - _members(std::move(that._members)), - _properties(std::move(that._properties)) - { - // other entry are invalid now (not that it is used..., class objects are - // only moved during extension setup, when the entry pointer has not yet - // been allocated) - that._entry = nullptr; - } + ClassBase(ClassBase &&that) : _impl(std::move(that._impl)) {} /** * Destructor */ - virtual ~ClassBase(); - - /** - * 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. - * - * @param ns Namespace name - * @param tsrm_ls - */ - void initialize(const std::string &ns TSRMLS_DC); + virtual ~ClassBase() {} -protected: /** * Construct a new instance of the object, or to clone the object * @return Base */ - virtual Base* construct() const { return nullptr; } + virtual Base* construct() const { return nullptr; } virtual Base *clone(Base *orig) const { return nullptr; } /** @@ -149,9 +104,9 @@ protected: * constructor is available * @return bool */ - virtual bool traversable() const { return false; } + virtual bool traversable() const { return false; } virtual bool serializable() const { return false; } - virtual bool clonable() const { return false; } + virtual bool clonable() const { return false; } /** * Compare two objects @@ -201,8 +156,12 @@ protected: virtual void callUnset(Base *base, const Value &name) const {} virtual bool callIsset(Base *base, const Value &name) const { return false; } + /** + * Get access to the implementation object + * @return std::shared_ptr + */ + const std::shared_ptr<ClassImpl> &implementation() const { return _impl; } - protected: /** * Function that can be called by a derived method when a certain function @@ -224,16 +183,15 @@ protected: * @param method The actual method * @param flags Optional flags * @param args Description of the supported arguments - * @return ClassBase Same object to allow chaining */ - ClassBase &method(const char *name, const method_callback_0 &method, int flags=0, const Arguments &args = {}); - ClassBase &method(const char *name, const method_callback_1 &method, int flags=0, const Arguments &args = {}); - ClassBase &method(const char *name, const method_callback_2 &method, int flags=0, const Arguments &args = {}); - ClassBase &method(const char *name, const method_callback_3 &method, int flags=0, const Arguments &args = {}); - ClassBase &method(const char *name, const method_callback_4 &method, int flags=0, const Arguments &args = {}); - ClassBase &method(const char *name, const method_callback_5 &method, int flags=0, const Arguments &args = {}); - ClassBase &method(const char *name, const method_callback_6 &method, int flags=0, const Arguments &args = {}); - ClassBase &method(const char *name, const method_callback_7 &method, int flags=0, const Arguments &args = {}); + void method(const char *name, const method_callback_0 &method, int flags=0, const Arguments &args = {}); + void method(const char *name, const method_callback_1 &method, int flags=0, const Arguments &args = {}); + void method(const char *name, const method_callback_2 &method, int flags=0, const Arguments &args = {}); + void method(const char *name, const method_callback_3 &method, int flags=0, const Arguments &args = {}); + void method(const char *name, const method_callback_4 &method, int flags=0, const Arguments &args = {}); + void method(const char *name, const method_callback_5 &method, int flags=0, const Arguments &args = {}); + void method(const char *name, const method_callback_6 &method, int flags=0, const Arguments &args = {}); + void method(const char *name, const method_callback_7 &method, int flags=0, const Arguments &args = {}); /** * Add a static method to the class @@ -246,12 +204,11 @@ protected: * @param method The actual method * @param flags Optional flags * @param args Description of the supported arguments - * @return ClassBase Same object to allow chaining */ - ClassBase &method(const char *name, const native_callback_0 &method, int flags=0, const Arguments &args = {}); - ClassBase &method(const char *name, const native_callback_1 &method, int flags=0, const Arguments &args = {}); - ClassBase &method(const char *name, const native_callback_2 &method, int flags=0, const Arguments &args = {}); - ClassBase &method(const char *name, const native_callback_3 &method, int flags=0, const Arguments &args = {}); + void method(const char *name, const native_callback_0 &method, int flags=0, const Arguments &args = {}); + void method(const char *name, const native_callback_1 &method, int flags=0, const Arguments &args = {}); + void method(const char *name, const native_callback_2 &method, int flags=0, const Arguments &args = {}); + void method(const char *name, const native_callback_3 &method, int flags=0, const Arguments &args = {}); /** * Add an abstract method to the class @@ -259,9 +216,8 @@ protected: * @param name Name of the method * @param flags Optional flags (like public or protected) * @param args Description of the supported arguments - * @return ClassBase Same object to allow chaining */ - ClassBase &method(const char *name, int flags=0, const Arguments &args = {}); + void method(const char *name, int flags=0, const Arguments &args = {}); /** * Add a property to the class @@ -275,279 +231,49 @@ protected: * @param name Name of the property * @param value Actual property value * @param flags Optional flags - * @return ClassBase Same object to allow chaining */ - ClassBase &property(const char *name, std::nullptr_t value, int flags = Php::Public); - ClassBase &property(const char *name, int16_t value, int flags = Php::Public); - ClassBase &property(const char *name, int32_t value, int flags = Php::Public); - ClassBase &property(const char *name, int64_t value, int flags = Php::Public); - ClassBase &property(const char *name, bool value, int flags = Php::Public); - ClassBase &property(const char *name, char value, int flags = Php::Public); - ClassBase &property(const char *name, const std::string &value, int flags = Php::Public); - ClassBase &property(const char *name, const char *value, int flags = Php::Public); - ClassBase &property(const char *name, double value, int flags = Php::Public); + void property(const char *name, std::nullptr_t value, int flags = Php::Public); + void property(const char *name, int16_t value, int flags = Php::Public); + void property(const char *name, int32_t value, int flags = Php::Public); + void property(const char *name, int64_t value, int flags = Php::Public); + void property(const char *name, bool value, int flags = Php::Public); + void property(const char *name, char value, int flags = Php::Public); + void property(const char *name, const std::string &value, int flags = Php::Public); + void property(const char *name, const char *value, int flags = Php::Public); + void property(const char *name, double value, int flags = Php::Public); /** * Set property with callbacks * @param name Name of the property * @param getter Getter method * @param setter Setter method - * @return ClassBase Same object to allow chaining - */ - ClassBase &property(const char *name, const getter_callback_0 &getter); - ClassBase &property(const char *name, const getter_callback_1 &getter); - ClassBase &property(const char *name, const getter_callback_0 &getter, const setter_callback_0 &setter); - ClassBase &property(const char *name, const getter_callback_1 &getter, const setter_callback_0 &setter); - ClassBase &property(const char *name, const getter_callback_0 &getter, const setter_callback_1 &setter); - ClassBase &property(const char *name, const getter_callback_1 &getter, const setter_callback_1 &setter); - -private: - /** - * 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(); - - /** - * Helper method to turn a property into a zval - * @param value - * @param type - * @return Value - */ - static struct _zval_struct *toZval(Value &&value, int type); - - /** - * Static member functions to create or clone objects based on this class - * @param entry Pointer to class information - * @param val The object to be cloned - * @param tsrm_ls - * @return zend_object_value Object info - */ - static struct _zend_object_value createObject(struct _zend_class_entry *entry TSRMLS_DC); - static struct _zend_object_value cloneObject(struct _zval_struct *val TSRMLS_DC); - static void destructObject(struct _zend_object *object, unsigned int handle TSRMLS_DC); - static void freeObject(struct _zend_object *object TSRMLS_DC); - - /** - * Static member function that get called when a method or object is called - * @param ht ?? - * @param return_value Zval holding the variable to store the return value in - * @param return_value_ptr Pointer to the same zval - * @param this_ptr Object being called - * @param return_value_used Is the return value used or not? - * @param tsrm_ls - */ - static void callMethod(int ht, struct _zval_struct *return_value, struct _zval_struct **return_value_ptr, struct _zval_struct *this_ptr, int return_value_used TSRMLS_DC); - static void callInvoke(int ht, struct _zval_struct *return_value, struct _zval_struct **return_value_ptr, struct _zval_struct *this_ptr, int return_value_used TSRMLS_DC); - - /** - * Function that is used to count the number of elements in the object - * If the user has implemented the Countable interface, this method will - * call the count() method - * @param val - * @param count - * @param tsrm_ls - * @return int - */ - static int countElements(struct _zval_struct *object, long *count TSRMLS_DC); - - /** - * Function that is called when the object is used as an array in PHP - * @param object The object on which it is called - * @param offset The name of the property - * @param value The new value - * @param type The type of the variable??? - * @param check_empty ???? - * @return zval - */ - static struct _zval_struct *readDimension(struct _zval_struct *object, struct _zval_struct *offset, int type TSRMLS_DC); - static void writeDimension(struct _zval_struct *object, struct _zval_struct *offset, struct _zval_struct *value TSRMLS_DC); - static int hasDimension(struct _zval_struct *object, struct _zval_struct *offset, int check_empty TSRMLS_DC); - static void unsetDimension(struct _zval_struct *object, struct _zval_struct *offset TSRMLS_DC); - - /** - * Retrieve pointer to our own object handlers - * @return zend_object_handlers - */ - struct _zend_object_handlers *objectHandlers(); - - /** - * Function to create a new iterator to iterate over an object - * @param entry The class entry - * @param object The object to iterate over - * @param by_ref ????? - * @param tsrm_ls - * @return zend_object_iterator* Pointer to the iterator - */ - static struct _zend_object_iterator *getIterator(struct _zend_class_entry *entry, struct _zval_struct *object, int by_ref TSRMLS_DC); - - /** - * Function that is called when a property is being read - * @param object The object on which it is called - * @param offset The name of the property - * @param type The type of the variable??? - * @param key ??? - * @param tsrm_ls - * @return zval - */ - static struct _zval_struct *readProperty(struct _zval_struct *object, struct _zval_struct *name, int type, const struct _zend_literal *key TSRMLS_DC); - static struct _zval_struct *readProperty(struct _zval_struct *object, struct _zval_struct *name, int type TSRMLS_DC); - - /** - * Function that is called when a property is set / updated - * @param object The object on which it is called - * @param name The name of the property - * @param value The new value - * @param key ??? - * @param tsrm_ls - * @return zval */ - static void writeProperty(struct _zval_struct *object, struct _zval_struct *name, struct _zval_struct *value, const struct _zend_literal *key TSRMLS_DC); - static void writeProperty(struct _zval_struct *object, struct _zval_struct *name, struct _zval_struct *value TSRMLS_DC); + void property(const char *name, const getter_callback_0 &getter); + void property(const char *name, const getter_callback_1 &getter); + void property(const char *name, const getter_callback_0 &getter, const setter_callback_0 &setter); + void property(const char *name, const getter_callback_1 &getter, const setter_callback_0 &setter); + void property(const char *name, const getter_callback_0 &getter, const setter_callback_1 &setter); + void property(const char *name, const getter_callback_1 &getter, const setter_callback_1 &setter); /** - * Function that is called to check whether a certain property is set - * @param object The object on which it is called - * @param name The name of the property to check - * @param has_set_exists See above - * @param tsrm_ls - * @return bool - */ - static int hasProperty(struct _zval_struct *object, struct _zval_struct *name, int has_set_exists, const struct _zend_literal *key TSRMLS_DC); - static int hasProperty(struct _zval_struct *object, struct _zval_struct *name, int has_set_exists TSRMLS_DC); - - /** - * Function that is called when a property is removed from the project - * @param object The object on which it is called - * @param member The member to remove - * @param tsrm_ls - */ - static void unsetProperty(struct _zval_struct *object, struct _zval_struct *member, const struct _zend_literal *key TSRMLS_DC); - static void unsetProperty(struct _zval_struct *object, struct _zval_struct *member TSRMLS_DC); - - /** - * Method that returns information about the function signature of a undefined method - * @param object_ptr - * @param method - * @param method_len - * @param key - * @param tsrm_ls - * @return zend_function - */ - static union _zend_function *getMethod(struct _zval_struct **object_ptr, char *method, int method_len TSRMLS_DC); - static union _zend_function *getMethod(struct _zval_struct **object_ptr, char *method, int method_len, const struct _zend_literal *key TSRMLS_DC); - - /** - * Method that returns information about the function signature of an undefined static method - * @param object_ptr - * @param method - * @param method_len - * @param key - * @param tsrm_ls - * @return zend_function - */ - static union _zend_function *getStaticMethod(struct _zend_class_entry *entry, char* method, int method_len TSRMLS_DC); - - /** - * Method that returns information about the __invoke() method - * @param object - * @param entry - * @param func - * @param object_ptr - * @param tsrm_ls - * @return int - */ - static int getClosure(struct _zval_struct *object, struct _zend_class_entry **entry, union _zend_function **func, struct _zval_struct **object_ptr TSRMLS_DC); - - /** - * Function to cast the object to a different type - * @param object - * @param retval - * @param type - * @param tsrm_ls - * @return int - */ - static int cast(struct _zval_struct *object, struct _zval_struct *retval, int type TSRMLS_DC); - - /** - * Function to compare two objects - * @param object1 - * @param object2 - * @param tsrm_ls - * @return int + * Add an interface + * @param interface Interface object */ - static int compare(struct _zval_struct *object1, struct _zval_struct *object2 TSRMLS_DC); +// void implements(const ClassBase &interface) { _interfaces.push_back(&interface); } /** - * Methods that are called to serialize/unserialize an object - * @param object The object to be serialized - * @param entry The class entry to which the object belongs - * @param buffer Buffer in which to store the data - * @param buf_len Size of the bufffer - * @param data Structure describing the serialize/unserialize data - * @param tsrm_ls - * @return int - */ - static int serialize(struct _zval_struct *object, unsigned char **buffer, unsigned int *buf_len, struct _zend_serialize_data *data TSRMLS_DC); - static int unserialize(struct _zval_struct **object, struct _zend_class_entry *entry, const unsigned char *buffer, unsigned int buf_len, struct _zend_unserialize_data *data TSRMLS_DC); - - /** - * Name of the class - * @var string - */ - std::string _name; - - /** - * The comment for reflexion, with a stored pointer to ourselves - * @var char* - */ - char *_comment = nullptr; - - /** - * The class type (this can be values like Php::Abstract and Php::Final) - * @var ClassType + * Set the base class + * @param name Name of the base class */ - ClassType _type = ClassType::Regular; +// void extends(const std::string &name) { _base = name; } - /** - * The class entry - * @var zend_class_entry - */ - struct _zend_class_entry *_entry = nullptr; +private: /** - * Pointer to the entries - * @var zend_function_entry[] - */ - struct _zend_function_entry *_entries = nullptr; - - /** - * All class methods - * @var std::list - */ - std::list<std::shared_ptr<Method>> _methods; - - /** - * All class members (class properties) - * @var std::list - */ - std::list<std::shared_ptr<Member>> _members; - - /** - * Map of dynamically accessible properties - * @var std::map - */ - std::map<std::string,std::shared_ptr<Property>> _properties; - - /** - * Base object has access to the members - * This is needed by the Base::store() method + * Pointer to the actual implementation + * @var std::shared_ptr<ClassImpl> */ - friend class Base; + std::shared_ptr<ClassImpl> _impl; }; /** diff --git a/include/interface.h b/include/interface.h index b0469f4..36f4d50 100644 --- a/include/interface.h +++ b/include/interface.h @@ -31,11 +31,15 @@ public: * Add a - of course abstract - method to the interface * @param name Name of the method * @param arguments Optional description of the arguments + * @return Interface Same object to allow chaining */ - void method(const char *name, const Arguments &arguments = {}) + Interface &method(const char *name, const Arguments &arguments = {}) { // call base ClassBase::method(name, Abstract | Public, arguments); + + // return self + return *this; } private: diff --git a/include/iterator.h b/include/iterator.h index a7d4283..13b30fc 100644 --- a/include/iterator.h +++ b/include/iterator.h @@ -158,7 +158,7 @@ private: /** * Classbase is a friend */ - friend class ClassBase; + friend class ClassImpl; }; /** diff --git a/include/value.h b/include/value.h index 2e1dd84..e7fa825 100644 --- a/include/value.h +++ b/include/value.h @@ -942,7 +942,7 @@ protected: */ friend class Globals; friend class Member; - friend class ClassBase; + friend class ClassImpl; friend class Iterator; friend class Extension; friend class HashIterator; |