diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2013-10-14 02:46:52 -0700 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2013-10-14 02:46:52 -0700 |
commit | 53272534a76a9d8cbee4ee887e1f360c4a99728b (patch) | |
tree | 54206aca1cfa1461ba365b05e5848f2843be91b9 | |
parent | 777eb276f635c949ccdcf9613ad55d42190cb387 (diff) |
The initial class properties can now only be scalar values, just like in PHP
-rw-r--r-- | include/member.h | 93 | ||||
-rw-r--r-- | include/protected.h | 10 | ||||
-rw-r--r-- | include/public.h | 10 | ||||
-rw-r--r-- | src/boolmember.h | 56 | ||||
-rw-r--r-- | src/classinfo.cpp | 7 | ||||
-rw-r--r-- | src/doublemember.h | 56 | ||||
-rw-r--r-- | src/includes.h | 7 | ||||
-rw-r--r-- | src/longmember.h | 56 | ||||
-rw-r--r-- | src/member.cpp | 157 | ||||
-rw-r--r-- | src/memberinfo.h | 66 | ||||
-rw-r--r-- | src/nullmember.h | 48 | ||||
-rw-r--r-- | src/stringmember.h | 63 |
12 files changed, 614 insertions, 15 deletions
diff --git a/include/member.h b/include/member.h index 4a9a754..5043ead 100644 --- a/include/member.h +++ b/include/member.h @@ -18,6 +18,11 @@ struct _zend_class_entry; namespace Php { /** + * Forward declarations + */ +class MemberInfo; + +/** * Class definition */ class Member @@ -27,15 +32,90 @@ public: * Constructor * @param name Name of the member * @param pub Is this a public property (otherwise it is protected) + */ + Member(const char *name, bool pub); + + /** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ + Member(const char *name, bool pub, std::nullptr_t value); + + /** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ + Member(const char *name, bool pub, int value); + + /** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ + Member(const char *name, bool pub, long value); + + /** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ + Member(const char *name, bool pub, bool value); + + /** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) * @param value The value to add */ - Member(const char *name, bool pub, const Value &value) : - _name(name), _public(pub), _value(value) {} + Member(const char *name, bool pub, char value); + + /** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ + Member(const char *name, bool pub, const std::string &value); + + /** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + * @param size String length + */ + Member(const char *name, bool pub, const char *value, int size = -1); + + /** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ + Member(const char *name, bool pub, double value); + + /** + * 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() {} + virtual ~Member(); /** * Internal method to declare the property @@ -58,10 +138,11 @@ private: bool _public; /** - * The default value - * @var Value + * The implementation for the member + * @var MemberInfo */ - Value _value; + MemberInfo *_info; + }; diff --git a/include/protected.h b/include/protected.h index e660f76..a1fdde5 100644 --- a/include/protected.h +++ b/include/protected.h @@ -23,7 +23,15 @@ public: * @param name Name of the property * @param value Default value of the property */ - Protected(const char *name, const Value &value) : Member(name, false, value) {} + Protected(const char *name) : Member(name, false) {} + Protected(const char *name, std::nullptr_t value) : Member(name, false, value) {} + Protected(const char *name, int value) : Member(name, false, value) {} + Protected(const char *name, long value) : Member(name, false, value) {} + Protected(const char *name, bool value) : Member(name, false, value) {} + Protected(const char *name, char value) : Member(name, false, value) {} + Protected(const char *name, const std::string &value) : Member(name, false, value) {} + Protected(const char *name, const char *value, int size=-1) : Member(name, false, value, size) {} + Protected(const char *name, double value) : Member(name, false, value) {} /** * Destructor diff --git a/include/public.h b/include/public.h index 17a5d0c..b37230b 100644 --- a/include/public.h +++ b/include/public.h @@ -23,7 +23,15 @@ public: * @param name Name of the property * @param value Default value of the property */ - Public(const char *name, const Value &value) : Member(name, true, value) {} + Public(const char *name) : Member(name, true) {} + Public(const char *name, std::nullptr_t value) : Member(name, true, value) {} + Public(const char *name, int value) : Member(name, true, value) {} + Public(const char *name, long value) : Member(name, true, value) {} + Public(const char *name, bool value) : Member(name, true, value) {} + Public(const char *name, char value) : Member(name, true, value) {} + Public(const char *name, const std::string &value) : Member(name, true, value) {} + Public(const char *name, const char *value, int size=-1) : Member(name, true, value, size) {} + Public(const char *name, double value) : Member(name, true, value) {} /** * Destructor diff --git a/src/boolmember.h b/src/boolmember.h new file mode 100644 index 0000000..c7db592 --- /dev/null +++ b/src/boolmember.h @@ -0,0 +1,56 @@ +/** + * BoolMember.h + * + * Implementation for a property that is initially set to a boolean value + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class BoolMember : public MemberInfo +{ +private: + /** + * The value + * @var bool + */ + bool _value; + +public: + /** + * Constructor + * @param value + */ + BoolMember(bool value) : MemberInfo(), _value(value) {} + + /** + * Destructor + */ + virtual ~BoolMember() {} + + /** + * Virtual method to declare the property + * @param entry Class entry + * @param name Name of the member + * @param size Size of the name + * @param flags Additional flags + */ + virtual void declare(struct _zend_class_entry *entry, const char *name, int size, int flags) + { + zend_declare_property_bool(entry, name, size, _value, flags); + } +}; + +/** + * End of namespace + */ +} + diff --git a/src/classinfo.cpp b/src/classinfo.cpp index aa4d67f..6d96494 100644 --- a/src/classinfo.cpp +++ b/src/classinfo.cpp @@ -34,8 +34,11 @@ static void deallocate_object(void *object TSRMLS_DC) if (obj->cpp) delete obj->cpp; // get rid of the object properties - zend_hash_destroy(obj->php.properties); - FREE_HASHTABLE(obj->php.properties); + // @todo if we enable the following two lines, segmentation + // faults and memory corruption occurs. however, the online + // documentation does it like this + //zend_hash_destroy(obj->php.properties); + //FREE_HASHTABLE(obj->php.properties); // deallocate the entire object efree(obj); diff --git a/src/doublemember.h b/src/doublemember.h new file mode 100644 index 0000000..9293932 --- /dev/null +++ b/src/doublemember.h @@ -0,0 +1,56 @@ +/** + * DoubleMember.h + * + * Implementation for a property that is initially set to a boolean value + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class DoubleMember : public MemberInfo +{ +private: + /** + * The value + * @var double + */ + double _value; + +public: + /** + * Constructor + * @param value + */ + DoubleMember(bool value) : MemberInfo(), _value(value) {} + + /** + * Destructor + */ + virtual ~DoubleMember() {} + + /** + * Virtual method to declare the property + * @param entry Class entry + * @param name Name of the member + * @param size Size of the name + * @param flags Additional flags + */ + virtual void declare(struct _zend_class_entry *entry, const char *name, int size, int flags) + { + zend_declare_property_double(entry, name, size, _value, flags); + } +}; + +/** + * End of namespace + */ +} + diff --git a/src/includes.h b/src/includes.h index 92de4ab..a131f7f 100644 --- a/src/includes.h +++ b/src/includes.h @@ -59,4 +59,9 @@ */ #include "nativefunction.h" #include "internalfunction.h" - +#include "memberinfo.h" +#include "nullmember.h" +#include "longmember.h" +#include "boolmember.h" +#include "stringmember.h" +#include "doublemember.h" diff --git a/src/longmember.h b/src/longmember.h new file mode 100644 index 0000000..c4107bf --- /dev/null +++ b/src/longmember.h @@ -0,0 +1,56 @@ +/** + * LongMember.h + * + * Implementation for a property that is initially set to a long value + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class LongMember : public MemberInfo +{ +private: + /** + * The value + * @var long + */ + long _value; + +public: + /** + * Constructor + * @param value + */ + LongMember(long value) : MemberInfo(), _value(value) {} + + /** + * Destructor + */ + virtual ~LongMember() {} + + /** + * Virtual method to declare the property + * @param entry Class entry + * @param name Name of the member + * @param size Size of the name + * @param flags Additional flags + */ + virtual void declare(struct _zend_class_entry *entry, const char *name, int size, int flags) + { + zend_declare_property_long(entry, name, size, _value, flags); + } +}; + +/** + * End of namespace + */ +} + diff --git a/src/member.cpp b/src/member.cpp index 82faf95..1c32777 100644 --- a/src/member.cpp +++ b/src/member.cpp @@ -12,17 +12,166 @@ * Set up namespace */ namespace Php { + +/** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + */ +Member::Member(const char *name, bool pub) : _name(name), _public(pub) +{ + // create a null member + _info = new NullMember(); +} + +/** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ +Member::Member(const char *name, bool pub, std::nullptr_t value) : _name(name), _public(pub) +{ + // create a null member + _info = new NullMember(); +} + +/** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ +Member::Member(const char *name, bool pub, int value) : _name(name), _public(pub) +{ + // create a long member + _info = new LongMember(value); +} + +/** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ +Member::Member(const char *name, bool pub, long value) : _name(name), _public(pub) +{ + // create a long member + _info = new LongMember(value); +} + +/** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ +Member::Member(const char *name, bool pub, bool value) : _name(name), _public(pub) +{ + // create a bool member + _info = new BoolMember(value); +} + +/** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ +Member::Member(const char *name, bool pub, char value) : _name(name), _public(pub) +{ + // create a new string member + _info = new StringMember(&value, 1); +} + +/** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ +Member::Member(const char *name, bool pub, const std::string &value) : _name(name), _public(pub) +{ + // create a new string member + _info = new StringMember(value); +} + +/** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + * @param size String length + */ +Member::Member(const char *name, bool pub, const char *value, int size) : _name(name), _public(pub) +{ + // create a new string member + if (size < 0) size = strlen(value); + _info = new StringMember(value, size); +} + +/** + * Constructor + * @param name Name of the member + * @param pub Is this a public property (otherwise it is protected) + * @param value The value to add + */ +Member::Member(const char *name, bool pub, double value) : _name(name), _public(pub) +{ + // create a new double member + _info = new DoubleMember(value); +} + +/** + * Copy constructor + * @param member The member to copy + */ +Member::Member(const Member &member) +{ + // copy info object, and name and public members + _info = member._info; + _name = member._name; + _public = member._public; + + // update refcount in info object + _info->refcount(+1); +} + +/** + * Move constructor + * @param member The member to move + */ +Member::Member(Member &&member) +{ + // move info object, and name and public properties + _info = member._info; + _name = std::move(member._name); + _public = member._public; + + // reset info in other object + member._info = NULL; +} + +/** + * Destructor + */ +Member::~Member() +{ + // leap out if there is no other info object, or when it is also used by other objects + if (!_info || _info->refcount(-1) > 0) return; + // deallocate info object + delete _info; +} + /** * Internal method to declare the property * @var zend_class_entry */ void Member::declare(struct _zend_class_entry *entry) { - std::cout << "declare property " << _name << std::endl; - - // declare the property - zend_declare_property(entry, _name.c_str(), _name.size(), _value._val, _public ? ZEND_ACC_PUBLIC : ZEND_ACC_PROTECTED TSRMLS_CC); + // let the info object handle stuff + _info->declare(entry, _name.c_str(), _name.size(), _public ? ZEND_ACC_PUBLIC : ZEND_ACC_PROTECTED TSRMLS_CC); } /** diff --git a/src/memberinfo.h b/src/memberinfo.h new file mode 100644 index 0000000..e0cfbd8 --- /dev/null +++ b/src/memberinfo.h @@ -0,0 +1,66 @@ +/** + * MemberInfo.h + * + * Base class for the implementation of class members + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class MemberInfo +{ +private: + /** + * Number of references + * @var int + */ + int _refcount; + +public: + /** + * Constructor + */ + MemberInfo() : _refcount(1) {} + + /** + * Virtual destructor + */ + virtual ~MemberInfo() {} + + /** + * Retrieve refcount + * @return int + */ + int refcount() { return _refcount; } + + /** + * Refcount after making a change + * @param change + * @return integer + */ + int refcount(int change) { return _refcount += change; } + + /** + * Virtual method to declare the property + * @param entry Class entry + * @param name Name of the member + * @param size Size of the name + * @param flags Additional flags + */ + virtual void declare(struct _zend_class_entry *entry, const char *name, int size, int flags)=0; +}; + +/** + * End of namespace + */ +} + + diff --git a/src/nullmember.h b/src/nullmember.h new file mode 100644 index 0000000..ea336ea --- /dev/null +++ b/src/nullmember.h @@ -0,0 +1,48 @@ +/** + * NullMember.h + * + * Implementation for a property that is initially set to NULL + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class NullMember : public MemberInfo +{ +public: + /** + * Constructor + */ + NullMember() : MemberInfo() {} + + /** + * Destructor + */ + virtual ~NullMember() {} + + /** + * Virtual method to declare the property + * @param entry Class entry + * @param name Name of the member + * @param size Size of the name + * @param flags Additional flags + */ + virtual void declare(struct _zend_class_entry *entry, const char *name, int size, int flags) + { + zend_declare_property_null(entry, name, size, flags); + } +}; + +/** + * End of namespace + */ +} + diff --git a/src/stringmember.h b/src/stringmember.h new file mode 100644 index 0000000..8818da4 --- /dev/null +++ b/src/stringmember.h @@ -0,0 +1,63 @@ +/** + * StringMember.h + * + * Implementation for a property that is initially set to a strnig value + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class StringMember : public MemberInfo +{ +private: + /** + * The value + * @var string + */ + std::string _value; + +public: + /** + * Constructor + * @param value + */ + StringMember(const std::string &value) : MemberInfo(), _value(value) {} + + /** + * Constructor + * @param value + * @param size + */ + StringMember(const char *value, int size) : MemberInfo(), _value(value, size) {} + + /** + * Destructor + */ + virtual ~StringMember() {} + + /** + * Virtual method to declare the property + * @param entry Class entry + * @param name Name of the member + * @param size Size of the name + * @param flags Additional flags + */ + virtual void declare(struct _zend_class_entry *entry, const char *name, int size, int flags) + { + zend_declare_property_stringl(entry, name, size, _value.c_str(), _value.size(), flags); + } +}; + +/** + * End of namespace + */ +} + |