diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-02-28 10:25:01 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-02-28 10:25:01 +0100 |
commit | 71055ebdea1e8eec30747a04f36e0c10e750bff5 (patch) | |
tree | 18ed63d5fe64a936c284a38d4f72921a4ddc97df | |
parent | 85349bbb642a83012a7d0dbccde8b7c1eea1b914 (diff) |
a lot of refactoring, to make it much easier to define classes in an extension
33 files changed, 1342 insertions, 1259 deletions
diff --git a/Examples/CppClassesInPhp/Makefile b/Examples/CppClassesInPhp/Makefile index 76f0bb1..872cce3 100644 --- a/Examples/CppClassesInPhp/Makefile +++ b/Examples/CppClassesInPhp/Makefile @@ -1,10 +1,10 @@ CPP = g++ RM = rm -f -CPP_FLAGS = -Wall -c -I. -O2 -std=c++11 +CPP_FLAGS = -Wall -c -I. -g -std=c++11 PREFIX = /usr #Edit these lines to correspond with your own directories -LIBRARY_DIR = ${PREFIX}/lib/php5/20121212 +LIBRARY_DIR = ${PREFIX}/lib/php5/20090626 PHP_CONFIG_DIR = /etc/php5/cli/conf.d LD = g++ diff --git a/Examples/CppClassesInPhp/cppclassinphp.cpp b/Examples/CppClassesInPhp/cppclassinphp.cpp index a0871fc..1b567e1 100644 --- a/Examples/CppClassesInPhp/cppclassinphp.cpp +++ b/Examples/CppClassesInPhp/cppclassinphp.cpp @@ -48,6 +48,11 @@ public: } }; +void myFunction(Php::Parameters ¶ms) +{ + std::cout << "regular function" << std::endl; +} + // Symbols are exported according to the "C" language extern "C" @@ -58,12 +63,18 @@ extern "C" // create extension static Php::Extension extension("Cpp_classes_in_php","1.0"); - // add the custom class ot the extension - extension.add("MyClass", Php::Class<MyCustomClass>({ - Php::Public("myMethod", Php::Method<MyCustomClass>(&MyCustomClass::myMethod),{ - Php::ByVal("newX", Php::numericType) - }) - })); + // add custom function + extension.add("myFunction", myFunction, { }); + + // we are going to define a class + Php::Class<MyCustomClass> customClass("MyClass"); + + // add methods to it + // @todo support setting parameter properties + customClass.add("myMethod", &MyCustomClass::myMethod, {}); + + // add the class to the extension + extension.add(customClass); // return the extension module return extension.module(); diff --git a/Examples/CppClassesInPhp/cppclassinphp.php b/Examples/CppClassesInPhp/cppclassinphp.php index 1eccf95..1256018 100644 --- a/Examples/CppClassesInPhp/cppclassinphp.php +++ b/Examples/CppClassesInPhp/cppclassinphp.php @@ -5,6 +5,9 @@ * * An example file to show the working of using a C++ class in PHP. */ + +// run the regular function +myFunction(); //create a MyCustomClass object, which is an object of a C++ class $MyCustomClass = new MyClass(); diff --git a/include/argument.h b/include/argument.h index c29073d..c75abc1 100644 --- a/include/argument.h +++ b/include/argument.h @@ -85,6 +85,12 @@ private: */ bool _required; }; + +/** + * A list of arguments can be supplied to methods + * @type Arguments + */ +using Arguments = std::initializer_list<Argument>; /** * End of namespace diff --git a/include/base.h b/include/base.h index 56189e2..df4076b 100644 --- a/include/base.h +++ b/include/base.h @@ -70,13 +70,6 @@ protected: private: }; -/** - * Definition of a method - */ -typedef void (Base::*method_callback_0)(); -typedef void (Base::*method_callback_1)(Parameters &); -typedef Value (Base::*method_callback_2)(); -typedef Value (Base::*method_callback_3)(Parameters &); /** * End of namespace diff --git a/include/class.h b/include/class.h index b440b02..ae66277 100644 --- a/include/class.h +++ b/include/class.h @@ -28,102 +28,89 @@ namespace Php { /** * Class definition of the class */ -template <typename T, ClassModifier _flags = ClassModifier::regular> -class Class +template <typename T> +class Class : private ClassBase { public: /** * Constructor + * + * The flags can be a combination of Php::Final and Php::Abstract. If no + * flags are set, a regular public class will be formed. + * + * @param name Name of the class + * @param flags Optional flags (final, abstract) + * + * @todo make sure flags are used */ - Class() {} - - /** - * Constructor with initializer list to define the properties - * @param members - */ - Class(const std::initializer_list<Member> &members) : _members(members) {} - - /** - * Move constructor - * @param that - */ - Class(Class &&that) : _members(std::move(that._members)) {} - - /** - * Copy constructor - */ - Class(const Class &that) : _members(that._members) {} + Class(const char *name, int flags = 0) : ClassBase(name, flags) {} /** * Destructor */ virtual ~Class() {} - + /** - * Construct an instance - * @return Base + * Add a property to the class + * + * Every instance of this class will have this property. The property + * can be Php::Public, Php::Protected or Php::Private (altough setting + * private properties is odd as the implementation of the class is in CPP, + * so why use private properties while the whole implementation is already + * hidden) + * + * @param name Name of the property + * @param property Actual property value + * @param flags Optional flags */ - Base* construct() - { - // allocate the object - return new T(); - } - +// void add(const char *name, const Property &property, int flags = Php::Public) +// { +// // @todo something with the flags +// _properties[name] = property; +// } + /** - * Initialize the class - * This will declare all members - * @param entry + * Add a method to the class + * + * The method will be accessible as one of the class methods in your PHP + * code. When the method is called, it will automatically be forwarded + * to the C++ implementation. The flags can be Php::Public, Php::Protected + * or Php::Private (using private methods can be useful if you for example + * want to make the __construct() function private). The access-modified + * flag can be bitwise combined with the flag Php::Final or Php::Abstract). + * + * @param name Name of the method + * @param method The actual method + * @param flags Optional flags + * @param args Argument descriptions */ - void initialize(struct _zend_class_entry *entry) - { - // loop through the members - for (auto iter = _members.begin(); iter != _members.end(); iter++) - { - iter->declare(entry); - } - } - + void add(const char *name, void(T::*method)(), int flags = 0, const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_0>(method), flags, args); } + void add(const char *name, void(T::*method)(Parameters ¶ms), int flags = 0, const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_1>(method), flags, args); } + void add(const char *name, bool(T::*method)(), int flags = 0, const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_2>(method), flags, args); } + void add(const char *name, bool(T::*method)(Parameters ¶ms), int flags = 0, const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_3>(method), flags, args); } + void add(const char *name, void(T::*method)(), const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_0>(method), 0, args); } + void add(const char *name, void(T::*method)(Parameters ¶ms), const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_1>(method), 0, args); } + void add(const char *name, bool(T::*method)(), const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_2>(method), 0, args); } + void add(const char *name, bool(T::*method)(Parameters ¶ms), const Arguments &args = {}) { ClassBase::add(name, static_cast<method_callback_3>(method), 0, args); } + +private: /** - * Retrieve the functions - * @param classname - * @return zend_function_entry* - */ - struct _zend_function_entry *methods(const char *classname) - { - return _members.methods(classname); - } - - /** - * Retrieve the class flags specifying whether the class - * is a regular class, abstract or final - * - * @return int flags of access types for classes + * Construct a new instance of the object + * @return Base */ - int getFlags() + virtual Base* construct() override { - return _flags; + // construct an instance + return new T(); } - -protected: + /** - * The initial arguments - * @var Members + * Extensions have access to the private base class */ - Members _members; - + friend class Extension; + }; - -// C++11 analog of `typedef`. Equivalent to the following pseudocode: typedef ClassFlagged<T, Zend::AccClass::FINAL> FinalClass<T>; -template <typename T> -using FinalClass = Class<T, ClassModifier::final>; - -template <typename T> -using AbstractClass = Class<T, ClassModifier::abstract>; - -template <typename T> -using Interface = Class<T, ClassModifier::interface>; - /** * End of namespace */ diff --git a/include/classbase.h b/include/classbase.h new file mode 100644 index 0000000..ad382fb --- /dev/null +++ b/include/classbase.h @@ -0,0 +1,170 @@ +/** + * ClassBase.h + * + * This is the base class of the "Class" class. This is an internal class that + * is used by the PHP-CPP library. But because the constructor is protected, + * you can not create any instances if this class yourself (and you are not + * supposed to do that either. + * + * Further more, because this base class is a 'private' base of Class, all + * features of it are normally also inaccessible. + * + * In other words: it is not meant to be directly used by extension writers. + * + * @copyright 2014 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Method signatures + */ +typedef void (Base::*method_callback_0)(); +typedef void (Base::*method_callback_1)(Parameters &); +typedef Value (Base::*method_callback_2)(); +typedef Value (Base::*method_callback_3)(Parameters &); + +/** + * Forward declarations + */ +class Method; + +/** + * Class definition + */ +class ClassBase +{ +protected: + /** + * Protected constructor + * @param classname Class name + * @param flags The class flags + */ + ClassBase(const char *classname, int flags = 0) : _name(classname), _flags(flags) {} + +public: + /** + * Copy constructor + * @param that + * + * @todo add properties + * @todo prefer move + */ + ClassBase(const ClassBase &that) : + _name(that._name), _flags(that._flags), _methods(that._methods) {} + + /** + * Move constructor + * @param that + * + * @todo add properties + * @todo use move semantics + */ + ClassBase(ClassBase &&that) : + _flags(that._flags), _methods(std::move(that._methods)), _entry(that._entry) + { + // 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; + } + + /** + * Destructor + */ + virtual ~ClassBase(); + + /** + * Construct a new instance of the object + * @return Base + */ + virtual Base* construct() = 0; + + /** + * Initialize the class, given its name + * + * The module functions are registered on module startup, but classes are + * initialized afterwards. The Zend engine is a strange thing. Nevertheless, + * this means that this method is called after the module is already available. + * This function will inform the Zend engine about the existence of the + * class. + */ + void initialize(); + +protected: + /** + * Add a method to the class + * + * The method will be accessible as one of the class methods in your PHP + * code. When the method is called, it will automatically be forwarded + * to the C++ implementation. The flags can be Php::Public, Php::Protected + * or Php::Private (using private methods can be useful if you for example + * want to make the __construct() function private). The access-modified + * flag can be bitwise combined with the flag Php::Final or Php::Abstract). + * + * @param name Name of the method + * @param method The actual method + * @param flags Optional flags + * @param args Description of the supported arguments + */ + void add(const char *name, method_callback_0, int flags=0, const Arguments &args = {}); + void add(const char *name, method_callback_1, int flags=0, const Arguments &args = {}); + void add(const char *name, method_callback_2, int flags=0, const Arguments &args = {}); + void add(const char *name, method_callback_3, int flags=0, const Arguments &args = {}); + +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(); + + /** + * Name of the class + * @var string + */ + std::string _name; + + /** + * The class flags (this can be values like Php::Abstract and Php::Final) + * @var int + */ + int _flags = 0; + + /** + * The class entry + * @var zend_class_entry + */ + struct _zend_class_entry *_entry = nullptr; + + /** + * Pointer to the entries + * @var zend_function_entry[] + */ + struct _zend_function_entry *_entries = nullptr; + + /** + * All class methods, this is a map indexed by method name + * @var set + */ + std::set<std::shared_ptr<Method>> _methods; + + /** + * All class properties, also a map indexed by name + * @var Properties + */ +// std::map<std::string,Property> _properties; +}; + +/** + * End namespace + */ +} + diff --git a/include/classinfo.h b/include/classinfo.h deleted file mode 100644 index 4fe73d5..0000000 --- a/include/classinfo.h +++ /dev/null @@ -1,170 +0,0 @@ -/** - * ClassInfo.h - * - * Internal class that is constructed by the library and that contains - * the information about a class, including its name. - * - * Users of the PHP-CPP libraries are not supposed to interact with - * this class, or instantiate objects of this class. - * - * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> - * @copyright 2013 Copernica BV - */ - -/** - * Forward declarations - */ -struct _zend_class_entry; - -/** - * Namespace - */ -namespace Php { - -/** - * Forward declarations - */ -class InternalFunction; - -/** - * Virtual base class of the classInfo - * - * We need this virtual base class to store pointers to class objects, - * without knowing in advance what sort of object they will hold - */ -class _ClassInfo -{ -public: - /** - * Constructor - * @param name - */ - _ClassInfo(const char *name); - - /** - * Destructor - */ - virtual ~_ClassInfo(); - - /** - * Initialize the class - */ - void initialize(); - - /** - * Initialize the class - * @param entry - */ - virtual void initialize(struct _zend_class_entry *entry) = 0; - - /** - * Construct the C++ object - * @return Base - */ - virtual Base *construct() = 0; - - /** - * Retrieve the methods - * @return zend_function_entry[] - */ - virtual struct _zend_function_entry *methods() = 0; - - /** - * set access types flags for class - */ - void setFlags(struct _zend_class_entry *entry, int flags); - -protected: - /** - * The class entry - * @var zend_class_entry - */ - struct _zend_class_entry *_entry; - - /** - * The name - * @var string - */ - std::string _name; - - /** - * Constructor function - * @var InternalFunction - */ - InternalFunction *_constructor; - - /** - * Destructor function - * @var InternalFunction - */ - InternalFunction *_destructor; - -}; - -/** - * Class definition - */ -template <typename T> -class ClassInfo : public _ClassInfo -{ -public: - /** - * Constructor - * @param name Name of the class - * @param type The class type - */ - ClassInfo(const char *name, const Class<T> &type) : _ClassInfo(name), _type(type) - { - } - - /** - * Destructor - */ - virtual ~ClassInfo() {} - - /** - * Construct the object - * @return Base - */ - virtual Base *construct() - { - return _type.construct(); - } - - /** - * Initialize the class - * @param entry - */ - virtual void initialize(struct _zend_class_entry *entry) override - { - // set access types flags for class - setFlags(entry, _type.getFlags()); - - // pass to the entry - _type.initialize(entry); - } - - /** - * Retrieve the methods - * @return zend_function_entry[] - */ - virtual struct _zend_function_entry *methods() - { - // ask class object - return _type.methods(_name.c_str()); - } - -private: - /** - * The class object - * @var Class - */ - Class<T> _type; - -}; - -/** - * End of namespace - */ -} - diff --git a/include/const.h b/include/const.h index 4f11278..55c1792 100644 --- a/include/const.h +++ b/include/const.h @@ -5,6 +5,9 @@ * * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> * @copyright 2013 Copernica BV + * + * + * @todo implement const in a different manner */ /** @@ -15,39 +18,39 @@ namespace Php { /** * Class definition */ -class Const : public Member -{ -public: - /** - * Constructor - * @param name Name of the property - * @param value Default value of the property - */ - Const(const char *name) : Member(name, MemberModifier::constMember) {} - Const(const char *name, std::nullptr_t value) : Member(name, MemberModifier::constMember, value) {} - Const(const char *name, int value) : Member(name, MemberModifier::constMember, value) {} - Const(const char *name, long value) : Member(name, MemberModifier::constMember, value) {} - Const(const char *name, bool value) : Member(name, MemberModifier::constMember, value) {} - Const(const char *name, char value) : Member(name, MemberModifier::constMember, value) {} - Const(const char *name, const std::string &value) : Member(name, MemberModifier::constMember, value) {} - Const(const char *name, const char *value, int size=-1) : Member(name, MemberModifier::constMember, value, size) {} - Const(const char *name, double value) : Member(name, MemberModifier::constMember, value) {} - - /** - * Constructor - * @param name Name of the property - * @param method Method to add - * @param arguments Optional argument information - */ - Const(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Member(name, MemberModifier::constMember, method, arguments) {} - - /** - * Destructor - */ - virtual ~Const() {} - -}; - +//class Const : public Member +//{ +//public: +// /** +// * Constructor +// * @param name Name of the property +// * @param value Default value of the property +// */ +// Const(const char *name) : Member(name, MemberModifier::constMember) {} +// Const(const char *name, std::nullptr_t value) : Member(name, MemberModifier::constMember, value) {} +// Const(const char *name, int value) : Member(name, MemberModifier::constMember, value) {} +// Const(const char *name, long value) : Member(name, MemberModifier::constMember, value) {} +// Const(const char *name, bool value) : Member(name, MemberModifier::constMember, value) {} +// Const(const char *name, char value) : Member(name, MemberModifier::constMember, value) {} +// Const(const char *name, const std::string &value) : Member(name, MemberModifier::constMember, value) {} +// Const(const char *name, const char *value, int size=-1) : Member(name, MemberModifier::constMember, value, size) {} +// Const(const char *name, double value) : Member(name, MemberModifier::constMember, value) {} +// +// /** +// * Constructor +// * @param name Name of the property +// * @param method Method to add +// * @param arguments Optional argument information +// */ +// Const(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Member(name, MemberModifier::constMember, method, arguments) {} +// +// /** +// * Destructor +// */ +// virtual ~Const() {} +// +//}; +// /** * End of namespace */ diff --git a/include/extension.h b/include/extension.h index 1082bcb..4a89cf9 100644 --- a/include/extension.h +++ b/include/extension.h @@ -29,9 +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 Value (*native_callback_2)(); +typedef Value (*native_callback_3)(Parameters &); + +/** * Forward declaration */ class Extension; +class Function; /** * Optional callback types for starting and stopping the request @@ -40,16 +51,6 @@ class Extension; typedef bool (*request_callback)(Extension *extension); /** - * 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 Value (*native_callback_2)(); -typedef Value (*native_callback_3)(Parameters &); - -/** * Class definition */ class Extension @@ -142,32 +143,15 @@ public: } /** - * 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. - * - * Note that the function must have been allocated on the HEAP (using - * "new") and that the object will be destructed (using "delete") - * by the extension object (you thus do not have to destruct it - * yourself!) - * - * @param function The function to add - * @return Function The added function - */ - Function *add(Function *function); - - /** * Add a native function directly to the extension * @param name Name of the function * @param function The function to add * @param arguments Optional argument specification - * @return Function The added function */ - Function *add(const char *name, native_callback_0 function, const std::initializer_list<Argument> &arguments = {}); - Function *add(const char *name, native_callback_1 function, const std::initializer_list<Argument> &arguments = {}); - Function *add(const char *name, native_callback_2 function, const std::initializer_list<Argument> &arguments = {}); - Function *add(const char *name, native_callback_3 function, const std::initializer_list<Argument> &arguments = {}); + void add(const char *name, native_callback_0 function, const Arguments &arguments = {}); + void add(const char *name, native_callback_1 function, const Arguments &arguments = {}); + void add(const char *name, native_callback_2 function, const Arguments &arguments = {}); + void add(const char *name, native_callback_3 function, const Arguments &arguments = {}); /** * Add a native class to the extension @@ -175,13 +159,13 @@ public: * @param type The class implementation */ template<typename T> - void add(const char *name, const Class<T> &type) + void add(const Class<T> &type) { - // construct info - _ClassInfo *info = new ClassInfo<T>(name, type); + // make a copy of the object + auto *info = new Class<T>(type); - // add class - _classes.insert(std::unique_ptr<_ClassInfo>(info)); + // and copy it to the list of classes + _classes.insert(std::unique_ptr<ClassBase>(info)); } /** @@ -197,16 +181,16 @@ public: private: /** - * Set of function objects defined in the library + * Functions defined in the library * @var set */ std::set<std::unique_ptr<Function>> _functions; /** - * Set of classes defined in the library + * Classes defined in the library, indexed by their name * @var set */ - std::set<std::unique_ptr<_ClassInfo>> _classes; + std::set<std::unique_ptr<ClassBase>> _classes; /** * The information that is passed to the Zend engine diff --git a/include/function.h b/include/function.h deleted file mode 100644 index a722104..0000000 --- a/include/function.h +++ /dev/null @@ -1,163 +0,0 @@ -/** - * Function.h - * - * Object represents a callable function that is defined with the CPP API. - * After you've instantiated the extension, you can add function objects to - * it. - * - * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> - * @copyright 2013 Copernica BV - */ - -/** - * Forward definitions - */ -struct _zend_function_entry; -struct _zend_internal_function_info; - -/** - * Set up namespace - */ -namespace Php { - -/** - * Class definition - */ -class Function -{ -public: - /** - * Constructor - * @param name Name of the function - * @param min Min number of arguments - * @param max Max number of arguments - */ - Function(const char *name, const std::initializer_list<Argument> &arguments = {}); - - /** - * No copy and move constructors - * @param function The other function - */ - Function(const Function &function) = delete; - Function(Function &&function) = delete; - - /** - * Destructor - */ - virtual ~Function(); - - /** - * No assignment operator - * @param function The other function - * @return Function - */ - Function &operator=(const Function &function) = delete; - - /** - * Comparison - * @param function The other function - * @return bool - */ - bool operator<(const Function &function) const - { - return strcmp(name(), function.name()) < 0; - } - - /** - * Comparison - * @param function The other function - * @return bool - */ - bool operator>(const Function &function) const - { - return strcmp(name(), function.name()) > 0; - } - - /** - * Comparison - * @param function The other function - * @return bool - */ - bool operator==(const Function &function) const - { - return strcmp(name(), function.name()) == 0; - } - - /** - * Function name - * @return const char * - */ - const char *name() const - { - return _ptr.text(); - } - - /** - * Method that gets called every time the function is executed - * @param params The parameters that were passed - * @return Variable Return value - */ - virtual Value invoke(Parameters ¶ms) - { - return nullptr; - } - - -protected: - /** - * Suggestion for the return type - * @var Type - */ - Type _type = nullType; - - /** - * Required number of arguments - * @var integer - */ - int _required; - - /** - * Total number of arguments - * @var integer - */ - int _argc; - - /** - * The arguments - * @var zend_arg_info[] - */ - struct _zend_arg_info *_argv; - - /** - * The object address is stored in a hidden pointer, so that we have access to the function object - * @var HiddenPointer - */ - HiddenPointer<Function> _ptr; - - /** - * Fill a function entry - * @param entry Entry to be filled - * @param classname Optional class name - * @param pub Is this a public property? - */ - void fill(struct _zend_function_entry *entry, const char *classname=NULL, MemberModifier flags = publicMember) const; - - /** - * Fill function info - * @param info Info object to be filled - * @param classname Optional class name - */ - void fill(struct _zend_internal_function_info *info, const char *classname=NULL) const; - - /** - * Extension has access to the private members - */ - friend class Extension; - -}; - -/** - * End of namespace - */ -} - diff --git a/include/hiddenpointer.h b/include/hiddenpointer.h index f432f65..96bb26a 100644 --- a/include/hiddenpointer.h +++ b/include/hiddenpointer.h @@ -29,21 +29,20 @@ public: */ HiddenPointer(Type *pointer, const char *text, int size=-1) { - // calculate size + // calculate size of the text 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 *))); + // allocate data + trailing null + size of pointer + char *buffer = new char[size + 1 + sizeof(Type *)]; + + // copy pointer into the buffer + memcpy(buffer, &pointer, sizeof(Type *)); - // append the text - _data.append(text, size); + // copy the name into the buffer + memcpy(buffer + sizeof(Type *), text, size + 1); - // store pointers - _pointer = pointer; - _text = _data.c_str() + sizeof(Type *); + // store in member + _buffer = buffer; } /** @@ -51,160 +50,85 @@ public: * @param pointer * @param text */ - HiddenPointer(Type *pointer, const std::string &text) : HiddenPointer(pointer, text.c_str(), text.size()) {} + 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; - } + HiddenPointer(const char *text) : + _buffer(text - sizeof(Type *)), // the buffer starts before the actual text + _allocated(false) {} // no memory was allocated /** * Copy constructor * @param that */ - HiddenPointer(const HiddenPointer<Type> &that) : _pointer(that._pointer), _text(that._text), _data(that._data) + HiddenPointer(const HiddenPointer<Type> &that) : _allocated(that._allocated) { - // if data is filled, the text is located inside the data - if (_data.size() > 0) _text = _data.c_str() + sizeof(Type *); + // is the other object allocated? + if (_allocated) + { + // allocate this object too, call other constructor + HiddenPointer(that, that); + } + else + { + // just copy the data + _buffer = that._buffer; + } } /** * Destructor */ - virtual ~HiddenPointer() {} + virtual ~HiddenPointer() + { + // destruct data + if (_allocated) delete[] _buffer; + } /** * 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 *); - } + HiddenPointer<Type> operator=(const HiddenPointer &that) = delete; /** * Retrieve the pointer * @return Type* */ - Type *pointer() const + operator Type * () const { - return _pointer; - } - - /** - * Change the pointer - * @param Type* - */ - void setPointer(Type *pointer) - { - // store pointer - _pointer = pointer; - - // overwrite in data - _data.replace(0, sizeof(Type *), (const char *)&_pointer, sizeof(Type *)); - - // for safety reasons, we recalculate text pointer - _text = _data.c_str() + sizeof(Type *); + // type is stored in front of the buffer + return *((Type **)_buffer); } /** * Retrieve the text * @return const char * */ - const char *text() const - { - return _text; - } - - /** - * Change the text - * @param text - * @param size - */ - void setText(const char *text, int size=-1) - { - // check if size was set - 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 new text - _text = _data.c_str() + sizeof(Type *); - } - - /** - * Cast to the pointer - * @return Type* - */ - operator Type* () const - { - return _pointer; - } - - /** - * Cast to text - * @return const char * - */ operator const char * () const { - return _text; + // name starts a number of bytes further + return _buffer + sizeof(Type *); } - /** - * Length of the text - * @return int - */ - int length() const - { - return _data.size() - sizeof(Type *); - } - private: /** - * The actual pointer - * @var Type* + * Buffer that holds both the pointer and the text - the text starts + * a number of bytes further up + * @var buffer */ - Type *_pointer; - - /** - * The original text - * @var text - */ - const char *_text; - + const char *_buffer = nullptr; + /** - * Optional data buffer - * @var string + * Was this allocated? + * @var bool */ - std::string _data; - + bool _allocated = true; }; /** diff --git a/include/member.h b/include/member.h index 564b1b6..9104c56 100644 --- a/include/member.h +++ b/include/member.h @@ -5,6 +5,8 @@ * * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> * @copyright 2013 Copernica BV + * + * @todo remove this file completely */ /** @@ -22,159 +24,159 @@ namespace Php { */ class MemberInfo; -/** - * Class definition - */ -class Member -{ -public: - /** - * Constructor - * @param name Name of the member - * @param flags Flag access to a class member (public, protected etc) - */ - Member(const char *name, MemberModifier flags); - - /** - * Constructor - * @param name Name of the member - * @param flags Flag access to a class member (public, protected etc) - * @param value The value to add - */ - Member(const char *name, MemberModifier flags, std::nullptr_t value); - - /** - * Constructor - * @param name Name of the member - * @param flags Flag access to a class member (public, protected etc) - * @param value The value to add - */ - Member(const char *name, MemberModifier flags, int value); - - /** - * Constructor - * @param name Name of the member - * @param flags Flag access to a class member (public, protected etc) - * @param value The value to add - */ - Member(const char *name, MemberModifier flags, long value); - - /** - * Constructor - * @param name Name of the member - * @param flags Flag access to a class member (public, protected etc) - * @param value The value to add - */ - Member(const char *name, MemberModifier flags, bool value); - - /** - * Constructor - * @param name Name of the member - * @param flags Flag access to a class member (public, protected etc) - * @param value The value to add - */ - Member(const char *name, MemberModifier flags, char value); - - /** - * Constructor - * @param name Name of the member - * @param flags Flag access to a class member (public, protected etc) - * @param value The value to add - */ - Member(const char *name, MemberModifier flags, const std::string &value); - - /** - * Constructor - * @param name Name of the member - * @param flags Flag access to a class member (public, protected etc) - * @param value The value to add - * @param size String length - */ - Member(const char *name, MemberModifier flags, const char *value, int size = -1); - - /** - * Constructor - * @param name Name of the member - * @param flags Flag access to a class member (public, protected etc) - * @param value The value to add - */ - Member(const char *name, MemberModifier flags, double value); - - /** - * Constructor - * @param name Name of the method - * @param flags Flag access to a class member (public, protected etc) - * @param method The method to add - */ - Member(const char *name, MemberModifier flags, const _Method &method, const std::initializer_list<Argument> &arguments = {}); - - /** - * Copy constructor - * @param member The member to copy - */ - Member(const Member &member); - - /** - * Move constructor - * @param member The member to move - */ - Member(Member &&member); - - /** - * Destructor - */ - virtual ~Member(); - - /** - * Internal method to declare the property - * @param zend_class_entry - * @internal - */ - void declare(struct _zend_class_entry *entry); - - /** - * Internal method to fill a function entry - * @param zend_function_entry - * @param classname - * @internal - */ - void fill(struct _zend_function_entry *entry, const char *classname); - - /** - * Is this a property member - * @return bool - */ - bool isProperty(); - - /** - * Is this a method member - * @return bool - */ - bool isMethod(); - - -private: - /** - * Name of the member - * @var string - */ - std::string _name; - - /** - * Flag access to a class member (public, protected etc) - * @var MemberModifier - */ - MemberModifier _flags; - - /** - * The implementation for the member - * @var MemberInfo - */ - MemberInfo *_info; - - -}; - +///** +// * Class definition +// */ +//class Member +//{ +//public: +// /** +// * Constructor +// * @param name Name of the member +// * @param flags Flag access to a class member (public, protected etc) +// */ +// Member(const char *name, MemberModifier flags); +// +// /** +// * Constructor +// * @param name Name of the member +// * @param flags Flag access to a class member (public, protected etc) +// * @param value The value to add +// */ +// Member(const char *name, MemberModifier flags, std::nullptr_t value); +// +// /** +// * Constructor +// * @param name Name of the member +// * @param flags Flag access to a class member (public, protected etc) +// * @param value The value to add +// */ +// Member(const char *name, MemberModifier flags, int value); +// +// /** +// * Constructor +// * @param name Name of the member +// * @param flags Flag access to a class member (public, protected etc) +// * @param value The value to add +// */ +// Member(const char *name, MemberModifier flags, long value); +// +// /** +// * Constructor +// * @param name Name of the member +// * @param flags Flag access to a class member (public, protected etc) +// * @param value The value to add +// */ +// Member(const char *name, MemberModifier flags, bool value); +// +// /** +// * Constructor +// * @param name Name of the member +// * @param flags Flag access to a class member (public, protected etc) +// * @param value The value to add +// */ +// Member(const char *name, MemberModifier flags, char value); +// +// /** +// * Constructor +// * @param name Name of the member +// * @param flags Flag access to a class member (public, protected etc) +// * @param value The value to add +// */ +// Member(const char *name, MemberModifier flags, const std::string &value); +// +// /** +// * Constructor +// * @param name Name of the member +// * @param flags Flag access to a class member (public, protected etc) +// * @param value The value to add +// * @param size String length +// */ +// Member(const char *name, MemberModifier flags, const char *value, int size = -1); +// +// /** +// * Constructor +// * @param name Name of the member +// * @param flags Flag access to a class member (public, protected etc) +// * @param value The value to add +// */ +// Member(const char *name, MemberModifier flags, double value); +// +// /** +// * Constructor +// * @param name Name of the method +// * @param flags Flag access to a class member (public, protected etc) +// * @param method The method to add +// */ +// Member(const char *name, MemberModifier flags, const _Method &method, const std::initializer_list<Argument> &arguments = {}); +// +// /** +// * Copy constructor +// * @param member The member to copy +// */ +// Member(const Member &member); +// +// /** +// * Move constructor +// * @param member The member to move +// */ +// Member(Member &&member); +// +// /** +// * Destructor +// */ +// virtual ~Member(); +// +// /** +// * Internal method to declare the property +// * @param zend_class_entry +// * @internal +// */ +// void declare(struct _zend_class_entry *entry); +// +// /** +// * Internal method to fill a function entry +// * @param zend_function_entry +// * @param classname +// * @internal +// */ +// void fill(struct _zend_function_entry *entry, const char *classname); +// +// /** +// * Is this a property member +// * @return bool +// */ +// bool isProperty(); +// +// /** +// * Is this a method member +// * @return bool +// */ +// bool isMethod(); +// +// +//private: +// /** +// * Name of the member +// * @var string +// */ +// std::string _name; +// +// /** +// * Flag access to a class member (public, protected etc) +// * @var MemberModifier +// */ +// MemberModifier _flags; +// +// /** +// * The implementation for the member +// * @var MemberInfo +// */ +// MemberInfo *_info; +// +// +//}; +// /** * End of namespace */ diff --git a/include/members.h b/include/members.h index 47cbebd..f286620 100644 --- a/include/members.h +++ b/include/members.h @@ -5,6 +5,9 @@ * * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> * @copyright 2013 Copernica BV + * + * + * @todo remove this file completely */ /** @@ -12,43 +15,43 @@ */ namespace Php { -/** - * Class definition - */ -class Members : public std::vector<Member> -{ -public: - /** - * Constructor - * @param arguments - */ - Members(const std::initializer_list<Member> &members) : std::vector<Member>(members), _methods(NULL) {} - - /** - * Destructor - */ - virtual ~Members(); - - /** - * Get access to the methods - * @param classname - * @return Methods - */ - struct _zend_function_entry *methods(const char *classname); - -private: - /** - * Number of methods - * @return integer - */ - int methods(); - - /** - * Array of method structures used internally in the Zend engine - * @var zend_function_entry - */ - struct _zend_function_entry *_methods; -}; +///** +// * Class definition +// */ +//class Members : public std::vector<Member> +//{ +//public: +// /** +// * Constructor +// * @param arguments +// */ +// Members(const std::initializer_list<Member> &members) : std::vector<Member>(members), _methods(NULL) {} +// +// /** +// * Destructor +// */ +// virtual ~Members(); +// +// /** +// * Get access to the methods +// * @param classname +// * @return Methods +// */ +// struct _zend_function_entry *methods(const char *classname); +// +//private: +// /** +// * Number of methods +// * @return integer +// */ +// int methods(); +// +// /** +// * Array of method structures used internally in the Zend engine +// * @var zend_function_entry +// */ +// struct _zend_function_entry *_methods; +//}; /** * End of namespace diff --git a/include/method.h b/include/method.h deleted file mode 100644 index d652d89..0000000 --- a/include/method.h +++ /dev/null @@ -1,110 +0,0 @@ -/** - * Method.h - */ - -/** - * Namespace - */ -namespace Php { - -/** - * A very generic function pointer - */ -typedef void (*function_ptr)(); - -/** - * Base class of the method - */ -class _Method -{ -public: - /** - * Copy constructor - * @param method - */ - _Method(const _Method &method) : _type(method._type), _callback(method._callback) {} - - /** - * Destructor - * @param type - * @param callback - */ - virtual ~_Method() {} - - /** - * Invoke the method - * @param parameters - * @return Value - */ - Value invoke(Parameters ¶meters) - { - // the object to call a method on - Base *base = parameters.object(); - - // find out which method to call, and call it - switch (_type) { - case 0: (base->*_callback.m0)(); return Value(); - case 1: (base->*_callback.m1)(parameters); return Value(); - case 2: return (base->*_callback.m2)(); - case 3: return (base->*_callback.m3)(parameters); - default: return Value(); - } - } - -protected: - /** - * Protected constructor to prevent that anyone instantiates this object - */ - _Method(method_callback_0 callback) : _type(0) { _callback.m0 = callback; } - _Method(method_callback_1 callback) : _type(1) { _callback.m1 = callback; } - _Method(method_callback_2 callback) : _type(2) { _callback.m2 = callback; } - _Method(method_callback_3 callback) : _type(3) { _callback.m3 = callback; } - -private: - /** - * Callback type - * @var int - */ - int _type; - - /** - * The actual callback - * @var void* - */ - union { - method_callback_0 m0; - method_callback_1 m1; - method_callback_2 m2; - method_callback_3 m3; - } _callback; -}; - -/** - * Actual template class of the method - */ -template <typename T> -class Method : public _Method -{ -public: - /** - * Constructor - * @param callback - */ - Method(void(T::*callback)()) : _Method(static_cast<method_callback_0>(callback)) {} - Method(void(T::*callback)(Parameters&)) : _Method(static_cast<method_callback_1>(callback)) {} - Method(Value(T::*callback)()) : _Method(static_cast<method_callback_2>(callback)) {} - Method(Value(T::*callback)(Parameters&)) : _Method(static_cast<method_callback_3>(callback)) {} - - /** - * Destructor - */ - virtual ~Method() {} - -}; - -/** - * End of namespace - */ -} - - diff --git a/include/private.h b/include/private.h index eddac69..f21ba6b 100644 --- a/include/private.h +++ b/include/private.h @@ -15,39 +15,39 @@ namespace Php { /** * Class definition */ -class Private : public Member -{ -public: - /** - * Constructor - * @param name Name of the property - * @param value Default value of the property - */ - Private(const char *name) : Member(name, MemberModifier::privateMember) {} - Private(const char *name, std::nullptr_t value) : Member(name, MemberModifier::privateMember, value) {} - Private(const char *name, int value) : Member(name, MemberModifier::privateMember, value) {} - Private(const char *name, long value) : Member(name, MemberModifier::privateMember, value) {} - Private(const char *name, bool value) : Member(name, MemberModifier::privateMember, value) {} - Private(const char *name, char value) : Member(name, MemberModifier::privateMember, value) {} - Private(const char *name, const std::string &value) : Member(name, MemberModifier::privateMember, value) {} - Private(const char *name, const char *value, int size=-1) : Member(name, MemberModifier::privateMember, value, size) {} - Private(const char *name, double value) : Member(name, MemberModifier::privateMember, value) {} - - /** - * Constructor - * @param name Name of the property - * @param method Method to add - * @param arguments Optional argument information - */ - Private(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Member(name, MemberModifier::privateMember, method, arguments) {} - - /** - * Destructor - */ - virtual ~Private() {} - -}; - +//class Private : public Member +//{ +//public: +// /** +// * Constructor +// * @param name Name of the property +// * @param value Default value of the property +// */ +// Private(const char *name) : Member(name, MemberModifier::privateMember) {} +// Private(const char *name, std::nullptr_t value) : Member(name, MemberModifier::privateMember, value) {} +// Private(const char *name, int value) : Member(name, MemberModifier::privateMember, value) {} +// Private(const char *name, long value) : Member(name, MemberModifier::privateMember, value) {} +// Private(const char *name, bool value) : Member(name, MemberModifier::privateMember, value) {} +// Private(const char *name, char value) : Member(name, MemberModifier::privateMember, value) {} +// Private(const char *name, const std::string &value) : Member(name, MemberModifier::privateMember, value) {} +// Private(const char *name, const char *value, int size=-1) : Member(name, MemberModifier::privateMember, value, size) {} +// Private(const char *name, double value) : Member(name, MemberModifier::privateMember, value) {} +// +// /** +// * Constructor +// * @param name Name of the property +// * @param method Method to add +// * @param arguments Optional argument information +// */ +// Private(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Member(name, MemberModifier::privateMember, method, arguments) {} +// +// /** +// * Destructor +// */ +// virtual ~Private() {} +// +//}; +// /** * End of namespace */ diff --git a/include/protected.h b/include/protected.h index 977b4c4..aeee064 100644 --- a/include/protected.h +++ b/include/protected.h @@ -5,6 +5,8 @@ * * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> * @copyright 2013 Copernica BV + * + * @todo remove this class completely */ /** @@ -12,42 +14,42 @@ */ namespace Php { -/** - * Class definition - */ -class Protected : public Member -{ -public: - /** - * Constructor - * @param name Name of the property - * @param value Default value of the property - */ - Protected(const char *name) : Member(name, MemberModifier::protectedMember) {} - Protected(const char *name, std::nullptr_t value) : Member(name, MemberModifier::protectedMember, value) {} - Protected(const char *name, int value) : Member(name, MemberModifier::protectedMember, value) {} - Protected(const char *name, long value) : Member(name, MemberModifier::protectedMember, value) {} - Protected(const char *name, bool value) : Member(name, MemberModifier::protectedMember, value) {} - Protected(const char *name, char value) : Member(name, MemberModifier::protectedMember, value) {} - Protected(const char *name, const std::string &value) : Member(name, MemberModifier::protectedMember, value) {} - Protected(const char *name, const char *value, int size=-1) : Member(name, MemberModifier::protectedMember, value, size) {} - Protected(const char *name, double value) : Member(name, MemberModifier::protectedMember, value) {} - - /** - * Constructor - * @param name Name of the property - * @param method Method to add - * @param arguments Optional argument information - */ - Protected(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Member(name, MemberModifier::protectedMember, method, arguments) {} - - /** - * Destructor - */ - virtual ~Protected() {} - -}; - +///** +// * Class definition +// */ +//class Protected : public Member +//{ +//public: +// /** +// * Constructor +// * @param name Name of the property +// * @param value Default value of the property +// */ +// Protected(const char *name) : Member(name, MemberModifier::protectedMember) {} +// Protected(const char *name, std::nullptr_t value) : Member(name, MemberModifier::protectedMember, value) {} +// Protected(const char *name, int value) : Member(name, MemberModifier::protectedMember, value) {} +// Protected(const char *name, long value) : Member(name, MemberModifier::protectedMember, value) {} +// Protected(const char *name, bool value) : Member(name, MemberModifier::protectedMember, value) {} +// Protected(const char *name, char value) : Member(name, MemberModifier::protectedMember, value) {} +// Protected(const char *name, const std::string &value) : Member(name, MemberModifier::protectedMember, value) {} +// Protected(const char *name, const char *value, int size=-1) : Member(name, MemberModifier::protectedMember, value, size) {} +// Protected(const char *name, double value) : Member(name, MemberModifier::protectedMember, value) {} +// +// /** +// * Constructor +// * @param name Name of the property +// * @param method Method to add +// * @param arguments Optional argument information +// */ +// Protected(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Member(name, MemberModifier::protectedMember, method, arguments) {} +// +// /** +// * Destructor +// */ +// virtual ~Protected() {} +// +//}; +// /** * End of namespace */ diff --git a/include/public.h b/include/public.h index 17a2468..a2f91f3 100644 --- a/include/public.h +++ b/include/public.h @@ -5,6 +5,8 @@ * * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> * @copyright 2013 Copernica BV + * + * @todo remove this file completely */ /** @@ -15,40 +17,40 @@ namespace Php { /** * Class definition */ -class Public : public Member -{ -public: - /** - * Constructor - * @param name Name of the property - * @param value Default value of the property - */ - Public(const char *name) : Member(name, MemberModifier::publicMember) {} - Public(const char *name, std::nullptr_t value) : Member(name, MemberModifier::publicMember, value) {} - Public(const char *name, int value) : Member(name, MemberModifier::publicMember, value) {} - Public(const char *name, long value) : Member(name, MemberModifier::publicMember, value) {} - Public(const char *name, bool value) : Member(name, MemberModifier::publicMember, value) {} - Public(const char *name, char value) : Member(name, MemberModifier::publicMember, value) {} - Public(const char *name, const std::string &value) : Member(name, MemberModifier::publicMember, value) {} - Public(const char *name, const char *value, int size=-1) : Member(name, MemberModifier::publicMember, value, size) {} - Public(const char *name, double value) : Member(name, MemberModifier::publicMember, value) {} - - /** - * Constructor - * @param name Name of the property - * @param method Method to add - * @param arguments Optional argument information - */ - Public(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Member(name, MemberModifier::publicMember, method, arguments) {} - - /** - * Destructor - */ - virtual ~Public() {} - - -}; - +//class Public : public Member +//{ +//public: +// /** +// * Constructor +// * @param name Name of the property +// * @param value Default value of the property +// */ +// Public(const char *name) : Member(name, MemberModifier::publicMember) {} +// Public(const char *name, std::nullptr_t value) : Member(name, MemberModifier::publicMember, value) {} +// Public(const char *name, int value) : Member(name, MemberModifier::publicMember, value) {} +// Public(const char *name, long value) : Member(name, MemberModifier::publicMember, value) {} +// Public(const char *name, bool value) : Member(name, MemberModifier::publicMember, value) {} +// Public(const char *name, char value) : Member(name, MemberModifier::publicMember, value) {} +// Public(const char *name, const std::string &value) : Member(name, MemberModifier::publicMember, value) {} +// Public(const char *name, const char *value, int size=-1) : Member(name, MemberModifier::publicMember, value, size) {} +// Public(const char *name, double value) : Member(name, MemberModifier::publicMember, value) {} +// +// /** +// * Constructor +// * @param name Name of the property +// * @param method Method to add +// * @param arguments Optional argument information +// */ +// Public(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Member(name, MemberModifier::publicMember, method, arguments) {} +// +// /** +// * Destructor +// */ +// virtual ~Public() {} +// +// +//}; +// /** * End of namespace */ @@ -37,10 +37,8 @@ #include <phpcpp/hashmember.h> #include <phpcpp/parameters.h> #include <phpcpp/membermodifier.h> -#include <phpcpp/function.h> #include <phpcpp/properties.h> #include <phpcpp/base.h> -#include <phpcpp/method.h> #include <phpcpp/member.h> #include <phpcpp/public.h> #include <phpcpp/protected.h> @@ -48,8 +46,8 @@ #include <phpcpp/const.h> #include <phpcpp/members.h> #include <phpcpp/classmodifier.h> +#include <phpcpp/classbase.h> #include <phpcpp/class.h> -#include <phpcpp/classinfo.h> #include <phpcpp/extension.h> #include <phpcpp/exception.h> diff --git a/src/Makefile b/src/Makefile index 069024d..64b4eb1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ CPP = g++ RM = rm -f PHP_DIR = /usr/include/php5 -CPP_FLAGS = -c -I. -I${PHP_DIR} -I${PHP_DIR}/main -I${PHP_DIR}/ext -I${PHP_DIR}/Zend -I${PHP_DIR}/TSRM -O2 -std=c++11 +CPP_FLAGS = -c -I. -I${PHP_DIR} -I${PHP_DIR}/main -I${PHP_DIR}/ext -I${PHP_DIR}/Zend -I${PHP_DIR}/TSRM -g -std=c++11 LD = g++ LD_FLAGS = -Wall -shared -O2 diff --git a/src/function.cpp b/src/callable.cpp index ba37022..d410c0b 100644 --- a/src/function.cpp +++ b/src/callable.cpp @@ -23,13 +23,13 @@ namespace Php { * @param tsrm_ls * @return integer */ -void invoke_function(INTERNAL_FUNCTION_PARAMETERS) +static void invoke_callable(INTERNAL_FUNCTION_PARAMETERS) { // find the function name const char *name = get_active_function_name(TSRMLS_C); // uncover the hidden pointer inside the function name - Function *function = HiddenPointer<Function>(name); + Callable *callable = HiddenPointer<Callable>(name); // wrap the return value Value result(return_value, true); @@ -41,7 +41,7 @@ void invoke_function(INTERNAL_FUNCTION_PARAMETERS) try { // get the result - result = function->invoke(params); + result = callable->invoke(params); } catch (Php::OrigException &exception) { @@ -58,40 +58,6 @@ void invoke_function(INTERNAL_FUNCTION_PARAMETERS) } /** - * Constructor - * @param name Name of the function - * @param min Min number of arguments - * @param max Max number of arguments - */ -Function::Function(const char *name, const std::initializer_list<Argument> &arguments) : _ptr(this, name) -{ - // construct vector for arguments - _argc = arguments.size(); - _argv = new zend_arg_info[_argc+1]; - - // counter - int i=1; - - // loop through the arguments - for (auto it = arguments.begin(); it != arguments.end(); it++) - { - // fill the arg info - it->fill(&_argv[i++]); - } - - // @todo find out number of required arguments - _required = _argc; -} - -/** - * Destructor - */ -Function::~Function() -{ - delete[] _argv; -} - -/** * Fill a function entry * * This method is called when the extension is registering itself, when the @@ -101,18 +67,18 @@ Function::~Function() * @param classname Optional class name * @param flags Is this a public property? */ -void Function::fill(zend_function_entry *entry, const char *classname, MemberModifier flags) const +void Callable::initialize(zend_function_entry *entry, const char *classname, int flags) const { // fill the members of the entity, and hide a pointer to the current object in the name - entry->fname = _ptr; - entry->handler = invoke_function; + entry->fname = (const char *)_ptr; + entry->handler = invoke_callable; entry->arg_info = _argv; entry->num_args = _argc; entry->flags = flags; // we should fill the first argument as well #if PHP_VERSION_ID >= 50400 - fill((zend_internal_function_info *)entry->arg_info, classname); + initialize((zend_internal_function_info *)entry->arg_info, classname); #endif } @@ -122,7 +88,7 @@ void Function::fill(zend_function_entry *entry, const char *classname, MemberMod * @param classname Optional classname */ #if PHP_VERSION_ID >= 50400 -void Function::fill(zend_internal_function_info *info, const char *classname) const +void Callable::initialize(zend_internal_function_info *info, const char *classname) const { // fill in all the members, note that return reference is false by default, // because we do not support returning references in PHP-CPP, although Zend @@ -133,7 +99,7 @@ void Function::fill(zend_internal_function_info *info, const char *classname) co // number of required arguments, and the expected return type info->required_num_args = _required; - info->_type_hint = _type; + info->_type_hint = _return; // we do not support return-by-reference info->return_reference = false; diff --git a/src/callable.h b/src/callable.h new file mode 100644 index 0000000..1b761ae --- /dev/null +++ b/src/callable.h @@ -0,0 +1,121 @@ +/** + * Callable.h + * + * Object represents a callable function or method that is defined with the CPP + * API. + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ + +/** + * Forward definitions + */ +struct _zend_function_entry; +struct _zend_internal_function_info; + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class Callable +{ +public: + /** + * Constructor + * @param name Function or method name + * @param arguments Information about the arguments + */ + Callable(const char *name, const Arguments &arguments = {}) : _ptr(this, name) + { + // construct vector for arguments + _argc = arguments.size(); + _argv = new zend_arg_info[_argc+1]; + + // counter + int i=1; + + // loop through the arguments + for (auto it = arguments.begin(); it != arguments.end(); it++) + { + // fill the arg info + it->fill(&_argv[i++]); + } + + // @todo find out number of required arguments + _required = _argc; + } + + /** + * Destructor + */ + virtual ~Callable() + { + delete[] _argv; + } + + /** + * Method that gets called every time the function is executed + * @param params The parameters that were passed + * @return Variable Return value + */ + virtual Value invoke(Parameters ¶ms) = 0; + + /** + * Fill a function entry + * @param entry Entry to be filled + * @param classname Optional class name + * @param flags Access flags + */ + void initialize(struct _zend_function_entry *entry, const char *classname = nullptr, int flags = 0) const; + + /** + * Fill function info + * @param info Info object to be filled + * @param classname Optional class name + */ + void initialize(struct _zend_internal_function_info *info, const char *classname = nullptr) const; + + +protected: + /** + * Hidden pointer to the name and the function + * @var HiddenPointer + */ + HiddenPointer<Callable> _ptr; + + /** + * Suggestion for the return type + * @var Type + */ + Type _return = nullType; + + /** + * Required number of arguments + * @var integer + */ + int _required = 0; + + /** + * Total number of arguments + * @var integer + */ + int _argc = 0; + + /** + * The arguments + * @var zend_arg_info[] + */ + struct _zend_arg_info *_argv = nullptr; + +}; + +/** + * End of namespace + */ +} + diff --git a/src/class.cpp b/src/class.cpp deleted file mode 100644 index 6263147..0000000 --- a/src/class.cpp +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Class.cpp - * - * Implementation for the class entry - * - * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> - * @copyright 2013 Copernica BV - */ -#include "includes.h" - diff --git a/src/classinfo.cpp b/src/classbase.cpp index f96d724..2ad51b1 100644 --- a/src/classinfo.cpp +++ b/src/classbase.cpp @@ -1,10 +1,10 @@ /** - * ClassInfo.cpp + * ClassBase.cpp * - * Implementation for the class info + * Implementation of the ClassBase class. * * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> - * @copyright 2013 Copernica BV + * @copyright 2014 Copernica BV */ #include "includes.h" @@ -62,9 +62,9 @@ static zend_object_value create_object(zend_class_entry *type TSRMLS_DC) // retrieve the classinfo object #if PHP_VERSION_ID >= 50400 - _ClassInfo *info = (_ClassInfo *)base->info.user.doc_comment; + ClassBase *info = (ClassBase *)base->info.user.doc_comment; #else - _ClassInfo *info = *((_ClassInfo **)base->doc_comment); + ClassBase *info = *((ClassBase **)base->doc_comment); #endif // store the class @@ -102,31 +102,70 @@ static zend_object_value create_object(zend_class_entry *type TSRMLS_DC) } /** - * Constructor - * @param name + * Destructor */ -_ClassInfo::_ClassInfo(const char *name) : _name(name), _entry(NULL) +ClassBase::~ClassBase() { + // destruct the entries + if (_entries) delete[] _entries; } /** - * Destructor + * Retrieve an array of zend_function_entry objects that hold the + * properties for each method. This method is called at extension + * startup time to register all methods. + * + * @param classname The class name + * @return zend_function_entry[] */ -_ClassInfo::~_ClassInfo() +const struct _zend_function_entry *ClassBase::entries() { + // already initialized? + if (_entries) return _entries; + + // allocate memory for the functions + _entries = new zend_function_entry[_methods.size() + 1]; + + // keep iterator counter + int i = 0; + + // loop through the functions + for (auto &method : _methods) + { + // retrieve entry + zend_function_entry *entry = &_entries[i++]; + + // let the function fill the entry + // @todo check flags for the method + method->initialize(entry, _name); + } + + // last entry should be set to all zeros + zend_function_entry *last = &_entries[i]; + + // all should be set to zero + memset(last, 0, sizeof(zend_function_entry)); + + // done + return _entries; } /** - * Initialize the class - * @param mixed Optional threading ID + * Initialize the class, given its name + * + * The module functions are registered on module startup, but classes are + * initialized afterwards. The Zend engine is a strange thing. Nevertheless, + * this means that this method is called after the module is already available. + * This function will inform the Zend engine about the existence of the + * class. */ -void _ClassInfo::initialize(TSRMLS_DC) +void ClassBase::initialize() { // the class entry zend_class_entry entry; // initialize the class entry - INIT_CLASS_ENTRY_EX(entry, _name.c_str(), _name.size(), methods()); + INIT_CLASS_ENTRY_EX(entry, _name.c_str(), _name.size(), entries()); // we need a special constructor entry.create_object = create_object; @@ -159,19 +198,69 @@ void _ClassInfo::initialize(TSRMLS_DC) _entry->doc_comment = (char *)wrapper; #endif - // initialize the entry - initialize(_entry); + // set access types flags for class + // @todo something with the flags, but before or after the register_internal_class? + //setFlags(entry, _type.getFlags()); + + // declare all properties + // @todo enable this +// _properties.initialize(_entry); +} + +/** + * Add a method to the class + * @param name Name of the method + * @param method The actual method + * @param flags Optional flags + * @param args Description of the supported arguments + */ +void ClassBase::add(const char *name, method_callback_0 callback, int flags, const Arguments &args) +{ + // add the method + _methods.insert(std::make_shared<Method>(name, callback, flags, args)); +} + +/** + * Add a method to the class + * @param name Name of the method + * @param method The actual method + * @param flags Optional flags + * @param args Description of the supported arguments + */ +void ClassBase::add(const char *name, method_callback_1 callback, int flags, const Arguments &args) +{ + // add the method + _methods.insert(std::make_shared<Method>(name, callback, flags, args)); } /** - * set access types flags for class + * Add a method to the class + * @param name Name of the method + * @param method The actual method + * @param flags Optional flags + * @param args Description of the supported arguments */ -void _ClassInfo::setFlags(struct _zend_class_entry *entry, int flags) { - entry->ce_flags |= flags; +void ClassBase::add(const char *name, method_callback_2 callback, int flags, const Arguments &args) +{ + // add the method + _methods.insert(std::make_shared<Method>(name, callback, flags, args)); } /** - * End of namespace + * Add a method to the class + * @param name Name of the method + * @param method The actual method + * @param flags Optional flags + * @param args Description of the supported arguments */ +void ClassBase::add(const char *name, method_callback_3 callback, int flags, const Arguments &args) +{ + // add the method + _methods.insert(std::make_shared<Method>(name, callback, flags, args)); } - + +/** + * End namespace + */ +} + diff --git a/src/extension.cpp b/src/extension.cpp index 5c5292e..dae5051 100644 --- a/src/extension.cpp +++ b/src/extension.cpp @@ -191,7 +191,7 @@ Extension::Extension(const char *name, const char *version, request_callback sta _entry->type = 0; // temporary or persistent module, will be filled by Zend engine _entry->handle = NULL; // dlopen() handle, will be filled by Zend engine _entry->module_number = 0; // module number will be filled in by Zend engine - _entry->build_id = ZEND_MODULE_BUILD_ID; // check if extension and zend engine are compatible + _entry->build_id = (char *)ZEND_MODULE_BUILD_ID; // check if extension and zend engine are compatible // things that only need to be initialized #ifdef ZTS @@ -215,29 +215,52 @@ Extension::~Extension() } /** - * Add a function to the library - * @param function Function object - * @return Function + * Add a native function directly to the extension + * @param name Name of the function + * @param function The function to add + * @param arguments Optional argument specification */ -Function *Extension::add(Function *function) +void Extension::add(const char *name, native_callback_0 function, const Arguments &arguments) { - // add the function to the map - _functions.insert(std::unique_ptr<Function>(function)); - - // the result is a pair with an iterator - return function; + // add a function + _functions.insert(std::unique_ptr<Function>(new Function(name, function, arguments))); +} + +/** + * Add a native function directly to the extension + * @param name Name of the function + * @param function The function to add + * @param arguments Optional argument specification + */ +void Extension::add(const char *name, native_callback_1 function, const Arguments &arguments) +{ + // add a function + _functions.insert(std::unique_ptr<Function>(new Function(name, function, arguments))); } /** * Add a native function directly to the extension * @param name Name of the function * @param function The function to add - * @return Function The added function + * @param arguments Optional argument specification */ -Function *Extension::add(const char *name, native_callback_0 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); } -Function *Extension::add(const char *name, native_callback_1 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); } -Function *Extension::add(const char *name, native_callback_2 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); } -Function *Extension::add(const char *name, native_callback_3 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); } +void Extension::add(const char *name, native_callback_2 function, const Arguments &arguments) +{ + // add a function + _functions.insert(std::unique_ptr<Function>(new Function(name, function, arguments))); +} + +/** + * Add a native function directly to the extension + * @param name Name of the function + * @param function The function to add + * @param arguments Optional argument specification + */ +void Extension::add(const char *name, native_callback_3 function, const Arguments &arguments) +{ + // add a function + _functions.insert(std::unique_ptr<Function>(new Function(name, function, arguments))); +} /** * Retrieve the module entry @@ -249,29 +272,29 @@ zend_module_entry *Extension::module() if (_entry->functions || _functions.size() == 0) return _entry; // allocate memory for the functions - zend_function_entry *functions = new zend_function_entry[_functions.size() + 1]; + zend_function_entry *entries = new zend_function_entry[_functions.size() + 1]; // keep iterator counter int i = 0; // loop through the functions - for (auto it = begin(_functions); it != _functions.end(); it++) + for (auto &function : _functions) { // retrieve entry - zend_function_entry *entry = &functions[i++]; + zend_function_entry *entry = &entries[i++]; // let the function fill the entry - (*it)->fill(entry); + function->initialize(entry); } // last entry should be set to all zeros - zend_function_entry *last = &functions[i]; + zend_function_entry *last = &entries[i]; // all should be set to zero memset(last, 0, sizeof(zend_function_entry)); // store functions in entry object - _entry->functions = functions; + _entry->functions = entries; // return the entry return _entry; @@ -284,11 +307,7 @@ zend_module_entry *Extension::module() bool Extension::initialize() { // loop through the classes - for (auto iter = _classes.begin(); iter != _classes.end(); iter++) - { - // initialize the class - (*iter)->initialize(); - } + for (auto &iter : _classes) iter->initialize(); // done return true; diff --git a/src/nativefunction.h b/src/function.h index 8b946a3..84d7dcc 100644 --- a/src/nativefunction.h +++ b/src/function.h @@ -1,7 +1,7 @@ /** - * NativeFunction.h + * Function.h * - * The NativeFunction class is an extension of the Function class that + * The Function class is an extension of the Callable class that * forwards the function call directly to a native function in C/C++ * * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> @@ -16,7 +16,7 @@ namespace Php { /** * Class definition */ -class NativeFunction : public Function +class Function : public Callable { public: /** @@ -24,15 +24,15 @@ public: * @param name Function name * @param function The native C function */ - NativeFunction(const char *name, native_callback_0 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(0) { _function.f0 = function; } - NativeFunction(const char *name, native_callback_1 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(1) { _function.f1 = function; } - NativeFunction(const char *name, native_callback_2 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(2) { _function.f2 = function; } - NativeFunction(const char *name, native_callback_3 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(3) { _function.f3 = function; } + Function(const char *name, native_callback_0 function, const Arguments &arguments = {}) : Callable(name, arguments), _type(0) { _function.f0 = function; } + Function(const char *name, native_callback_1 function, const Arguments &arguments = {}) : Callable(name, arguments), _type(1) { _function.f1 = function; } + Function(const char *name, native_callback_2 function, const Arguments &arguments = {}) : Callable(name, arguments), _type(2) { _function.f2 = function; } + Function(const char *name, native_callback_3 function, const Arguments &arguments = {}) : Callable(name, arguments), _type(3) { _function.f3 = function; } /** * Destructor */ - virtual ~NativeFunction() {} + virtual ~Function() {} /** * Method that gets called every time the function is executed diff --git a/src/includes.h b/src/includes.h index 5b97e03..4e6e583 100644 --- a/src/includes.h +++ b/src/includes.h @@ -30,6 +30,7 @@ /** * PHP includes */ +#pragma GCC system_header #include <php.h> #include "zend_exceptions.h" #include "zend_interfaces.h" @@ -54,10 +55,8 @@ #include "../include/hashmember.h" #include "../include/parameters.h" #include "../include/membermodifier.h" -#include "../include/function.h" #include "../include/properties.h" #include "../include/base.h" -#include "../include/method.h" #include "../include/member.h" #include "../include/public.h" #include "../include/protected.h" @@ -65,8 +64,8 @@ #include "../include/const.h" #include "../include/members.h" #include "../include/classmodifier.h" +#include "../include/classbase.h" #include "../include/class.h" -#include "../include/classinfo.h" #include "../include/extension.h" #include "../include/exception.h" #include "../include/init.h" @@ -75,7 +74,9 @@ * Interface files for internal use only */ #include "mixedobject.h" -#include "nativefunction.h" +#include "callable.h" +#include "function.h" +#include "method.h" #include "internalfunction.h" #include "memberinfo.h" #include "nullmember.h" diff --git a/src/member.cpp b/src/member.cpp index 85990cc..e3e7ff2 100644 --- a/src/member.cpp +++ b/src/member.cpp @@ -5,6 +5,9 @@ * * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> * @copyright 2013 Copernica BV + * + * + * @todo refactor this class to a property */ #include "includes.h" @@ -13,6 +16,8 @@ */ namespace Php { +#ifdef XXXX + /** * Constructor * @param name Name of the member @@ -218,6 +223,8 @@ void Member::fill(struct _zend_function_entry *entry, const char *classname) _info->fill(entry, classname, _flags); } +#endif + /** * End of namespace */ diff --git a/src/members.cpp b/src/members.cpp index 4ff1b60..1965807 100644 --- a/src/members.cpp +++ b/src/members.cpp @@ -13,76 +13,76 @@ */ namespace Php { -/** - * Destructor - */ -Members::~Members() -{ - // check if there are methods - if (_methods) delete[] _methods; -} - -/** - * Number of methods - * @return integer - */ -int Members::methods() -{ - // result variable - int result = 0; - - // loop through the functions - for (auto it = begin(); it != end(); it++) - { - // check if this is a method - if (it->isMethod()) result++; - } - - // done - return result; -} - -/** - * Get access to the methods - * @return Methods - */ -struct _zend_function_entry *Members::methods(const char *classname) -{ - // already set? - if (_methods) return _methods; - - // the number of methods - int count = methods(); - - // allocate memory for the functions - _methods = new zend_function_entry[count + 1]; - - // keep iterator counter - int i = 0; - - // loop through the functions - for (auto it = begin(); it != end(); it++) - { - // skip if this is not a method - if (!it->isMethod()) continue; - - // retrieve entry - zend_function_entry *entry = &_methods[i++]; - - // let the function fill the entry - it->fill(entry, classname); - } - - // last entry should be set to all zeros - zend_function_entry *last = &_methods[i]; - - // all should be set to zero - memset(last, 0, sizeof(zend_function_entry)); - - // done - return _methods; -} - +///** +// * Destructor +// */ +//Members::~Members() +//{ +// // check if there are methods +// if (_methods) delete[] _methods; +//} +// +///** +// * Number of methods +// * @return integer +// */ +//int Members::methods() +//{ +// // result variable +// int result = 0; +// +// // loop through the functions +// for (auto it = begin(); it != end(); it++) +// { +// // check if this is a method +// if (it->isMethod()) result++; +// } +// +// // done +// return result; +//} +// +///** +// * Get access to the methods +// * @return Methods +// */ +//struct _zend_function_entry *Members::methods(const char *classname) +//{ +// // already set? +// if (_methods) return _methods; +// +// // the number of methods +// int count = methods(); +// +// // allocate memory for the functions +// _methods = new zend_function_entry[count + 1]; +// +// // keep iterator counter +// int i = 0; +// +// // loop through the functions +// for (auto it = begin(); it != end(); it++) +// { +// // skip if this is not a method +// if (!it->isMethod()) continue; +// +// // retrieve entry +// zend_function_entry *entry = &_methods[i++]; +// +// // let the function fill the entry +// it->initialize(classname, entry); +// } +// +// // last entry should be set to all zeros +// zend_function_entry *last = &_methods[i]; +// +// // all should be set to zero +// memset(last, 0, sizeof(zend_function_entry)); +// +// // done +// return _methods; +//} +// /** * End of namespace */ diff --git a/src/method.h b/src/method.h new file mode 100644 index 0000000..cc9f973 --- /dev/null +++ b/src/method.h @@ -0,0 +1,104 @@ +/** + * Method.h + * + * Internal class that represents a native class method, that can be called + * from PHP scripts. + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2014 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class Method : public Callable +{ +public: + /** + * Constructor + * + * @param name Method name + * @param callback Native callback + * @param flags Access flags + * @param args Argument description + */ + Method(const char *name, method_callback_0 callback, int flags, const Arguments &args) : Callable(name, args), _type(0), _flags(flags) { _callback.m0 = callback; } + Method(const char *name, method_callback_1 callback, int flags, const Arguments &args) : Callable(name, args), _type(1), _flags(flags) { _callback.m1 = callback; } + Method(const char *name, method_callback_2 callback, int flags, const Arguments &args) : Callable(name, args), _type(2), _flags(flags) { _callback.m2 = callback; } + Method(const char *name, method_callback_3 callback, int flags, const Arguments &args) : Callable(name, args), _type(3), _flags(flags) { _callback.m3 = callback; } + + /** + * Destructor + * @param type + * @param callback + */ + virtual ~Method() {} + + /** + * Internal method to fill a function entry + * @param zend_function_entry + * @param classname + */ + void initialize(struct _zend_function_entry *entry, const std::string &classname) + { + // call base + Callable::initialize(entry, classname.c_str(), _flags); + } + + /** + * Invoke the method + * @param parameters + * @return Value + */ + virtual Value invoke(Parameters ¶meters) override + { + // the object to call a method on + Base *base = parameters.object(); + + // find out which method to call, and call it + switch (_type) { + case 0: (base->*_callback.m0)(); return Value(); + case 1: (base->*_callback.m1)(parameters); return Value(); + case 2: return (base->*_callback.m2)(); + case 3: return (base->*_callback.m3)(parameters); + default: return Value(); + } + } + + +private: + /** + * Callback type + * @var int + */ + int _type; + + /** + * Access flags (protected, public, abstract, final, private, etc) + * @var int + * @todo use this + */ + int _flags; + + /** + * The actual callback + * @var void* + */ + union { + method_callback_0 m0; + method_callback_1 m1; + method_callback_2 m2; + method_callback_3 m3; + } _callback; +}; + +/** + * End of namespace + */ +} + diff --git a/src/methodbase.cpp b/src/methodbase.cpp new file mode 100644 index 0000000..81ce40a --- /dev/null +++ b/src/methodbase.cpp @@ -0,0 +1,24 @@ +/** + * MethodBase.cpp + * + * Implementation of the MethodBase class + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2014 Copernica BV + */ +#include "includes.h" + +/** + * Set up namespace + * + * @todo remove file + */ +namespace Php { + +/** + * End namespace + */ +} + + +
\ No newline at end of file diff --git a/src/methodmember.h b/src/methodmember.h index 709aec9..5d903e9 100644 --- a/src/methodmember.h +++ b/src/methodmember.h @@ -5,6 +5,9 @@ * * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> * @copyright 2013 Copernica BV + * + * @todo remove this class + * @todo but do implement this for properties */ /** @@ -12,60 +15,60 @@ */ namespace Php { -/** - * Class definition - */ -class MethodMember : public MemberInfo, public Function -{ -public: - /** - * Constructor - * @param name - * @param method - * @param arguments - */ - MethodMember(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _method(method) {} - - /** - * Destructor - */ - virtual ~MethodMember() {} - - /** - * Is this a method member - * @return bool - */ - virtual bool isMethod() { return true; } - - /** - * Fill a function entry object - * @param entry Function entry - * @param classname Name of the class - * @param method Is this a public entry - */ - virtual void fill(struct _zend_function_entry *entry, const char *classname, MemberModifier flags) override - { - // call function object - Function::fill(entry, classname, flags); - } - - /** - * Method that gets called every time the function is executed - * @param params The parameters that were passed - * @return Variable Return value - */ - virtual Value invoke(Parameters ¶ms) - { - return _method.invoke(params); - } - -private: - /** - * The method pointer - * @var _Method - */ - _Method _method; -}; +///** +// * Class definition +// */ +//class MethodMember : public MemberInfo, public Function +//{ +//public: +// /** +// * Constructor +// * @param name +// * @param method +// * @param arguments +// */ +// MethodMember(const char *name, const _Method &method, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _method(method) {} +// +// /** +// * Destructor +// */ +// virtual ~MethodMember() {} +// +// /** +// * Is this a method member +// * @return bool +// */ +// virtual bool isMethod() { return true; } +// +// /** +// * Fill a function entry object +// * @param entry Function entry +// * @param classname Name of the class +// * @param method Is this a public entry +// */ +// virtual void fill(struct _zend_function_entry *entry, const char *classname, MemberModifier flags) override +// { +// // call function object +// Function::fill(entry, classname, flags); +// } +// +// /** +// * Method that gets called every time the function is executed +// * @param params The parameters that were passed +// * @return Variable Return value +// */ +// virtual Value invoke(Parameters ¶ms) +// { +// return _method.invoke(params); +// } +// +//private: +// /** +// * The method pointer +// * @var _Method +// */ +// _Method _method; +//}; /** * End of namespace diff --git a/src/methods.h b/src/methods.h new file mode 100644 index 0000000..08c129b --- /dev/null +++ b/src/methods.h @@ -0,0 +1,114 @@ +/** + * Methods.h + * + * Class in which all methods are stored. This is a class that is used + * internally by the PHP-CPP library, and that you do not have to use + * as an extension writer. + * + * Essentially, it is std::map that is a littlebit extended with features + * to initialize the methods in the Zend engine + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2014 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class Methods +{ +public: + /** + * Constructor + */ + Methods() {} + + /** + * Destructor + */ + virtual ~Methods() + { + // destruct the entries + if (_entries) delete[] _entries; + } + + /** + * Retrieve an array of zend_function_entry objects that hold the + * properties for each method. This method is called at extension + * startup time to register all methods. + * + * @param classname The class name + * @return zend_function_entry[] + */ + const struct _zend_function_entry *entries(const std::string &classname) + { + // already initialized? + if (_entries) return _entries; + + // allocate memory for the functions + _entries = new zend_function_entry[_methods.size() + 1]; + + // keep iterator counter + int i = 0; + + // loop through the functions + for (auto &method : _methods) + { + // retrieve entry + zend_function_entry *entry = &_entries[i++]; + + // let the function fill the entry + // @todo check flags for the method + method->initialize(entry, classname); + } + + // last entry should be set to all zeros + zend_function_entry *last = &_entries[i]; + + // all should be set to zero + memset(last, 0, sizeof(zend_function_entry)); + + // done + return _entries; + } + + /** + * Add a method + * @param name + * @param method + */ + void add(MethodBase *method) + { + // add the method + _methods.insert(std::shared_ptr<MethodBase>(method)); + } + + +private: + /** + * Pointer to the entries + * @var zend_function_entry[] + */ + struct _zend_function_entry *_entries = nullptr; + + /** + * Map of all methods + * + * A unique_ptr would have been cooler, but that somehow does not compile + * + * @var std::set + */ + std::set<std::shared_ptr<MethodBase>> _methods; + +}; + +/** + * End namespace + */ +} + |