summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/member.h93
-rw-r--r--include/protected.h10
-rw-r--r--include/public.h10
-rw-r--r--src/boolmember.h56
-rw-r--r--src/classinfo.cpp7
-rw-r--r--src/doublemember.h56
-rw-r--r--src/includes.h7
-rw-r--r--src/longmember.h56
-rw-r--r--src/member.cpp157
-rw-r--r--src/memberinfo.h66
-rw-r--r--src/nullmember.h48
-rw-r--r--src/stringmember.h63
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
+ */
+}
+