From 53272534a76a9d8cbee4ee887e1f360c4a99728b Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Mon, 14 Oct 2013 02:46:52 -0700 Subject: The initial class properties can now only be scalar values, just like in PHP --- src/boolmember.h | 56 +++++++++++++++++++ src/classinfo.cpp | 7 ++- src/doublemember.h | 56 +++++++++++++++++++ src/includes.h | 7 ++- src/longmember.h | 56 +++++++++++++++++++ src/member.cpp | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++-- src/memberinfo.h | 66 ++++++++++++++++++++++ src/nullmember.h | 48 ++++++++++++++++ src/stringmember.h | 63 +++++++++++++++++++++ 9 files changed, 509 insertions(+), 7 deletions(-) create mode 100644 src/boolmember.h create mode 100644 src/doublemember.h create mode 100644 src/longmember.h create mode 100644 src/memberinfo.h create mode 100644 src/nullmember.h create mode 100644 src/stringmember.h (limited to 'src') 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 + * @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 + * @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 + * @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 + * @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 + * @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 + * @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 + */ +} + -- cgit v1.2.3