summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-15 01:32:22 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-15 01:32:22 +0100
commit3300d64c4dd61e71b62d5b55b1f16e34d6335680 (patch)
treec2bd999ba1a2a1320acba20fb99acf0defb9651e /include
parent681d1e6aa735568a492140d2307a89063e7aadb9 (diff)
parentcda98dc0dea7144941a46ff20598f3c095d7a6d0 (diff)
implemented __clone method
Diffstat (limited to 'include')
-rw-r--r--include/array.h7
-rw-r--r--include/base.h12
-rw-r--r--include/callstatic.h64
-rw-r--r--include/class.h22
-rw-r--r--include/classbase.h46
-rw-r--r--include/globals.h2
-rw-r--r--include/hashmember.h30
-rw-r--r--include/super.h76
-rw-r--r--include/value.h29
9 files changed, 192 insertions, 96 deletions
diff --git a/include/array.h b/include/array.h
index dcd5e5f..26fec24 100644
--- a/include/array.h
+++ b/include/array.h
@@ -12,7 +12,7 @@
* Set up namespace
*/
namespace Php {
-
+
/**
* Class definition
*/
@@ -124,11 +124,6 @@ public:
};
/**
- * Define for arrays and objects
- */
-using Array = Array;
-
-/**
* End of namespace
*/
}
diff --git a/include/base.h b/include/base.h
index b9dced2..97b153d 100644
--- a/include/base.h
+++ b/include/base.h
@@ -111,6 +111,11 @@ public:
{
return Value(this)[name];
}
+
+ /**
+ * Overridable method that is called right before an object is destructed
+ */
+ void __destruct() const;
/**
* Overridable method that is called right after an object is cloned
@@ -120,13 +125,6 @@ public:
void __clone() const {}
/**
- * Overridable method that is called right before an object is destructed
- *
- * The default implementation does nothing
- */
- void __destruct() const {}
-
- /**
* Overridable method that is called to check if a property is set
*
* The default implementation does nothing, and the script will fall back
diff --git a/include/callstatic.h b/include/callstatic.h
deleted file mode 100644
index 3979ef3..0000000
--- a/include/callstatic.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * CallStatic.h
- *
- * Class that performs a lot of C++11 magic to find out if the __callStatic()
- * method was implemented by the user, and if it was, calls it
- *
- */
-
-namespace Php {
-
-/**
- * SFINAE test to check if the __callStatic method is defined
- *
- * This type trait checks if the __callStatic method is defined in class T
- *
- * @see http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence
- */
-template <typename T>
-class HasCallStatic
-{
- typedef char one;
- typedef long two;
-
- template <typename C> static one test( decltype(&C::__callStatic) ) ;
- template <typename C> static two test(...);
-
-public:
- static const bool value = sizeof(test<T>(0)) == sizeof(char);
-};
-
-/**
- * Function that only exists if the class T has a __callStatic method
- * @param name Name of the function
- * @param params Parameters passed to the function
- * @return Value
- */
-template<typename T>
-typename std::enable_if<HasCallStatic<T>::value, Value >::type
-callStatic(const char *name, Parameters &params)
-{
- // call the __callStatic() function
- return T::__callStatic(name, params);
-}
-
-/**
- * Function that only exists if the class T does not have a __callStatic method
- * @param name Name of the function
- * @param params Parameters passed to the function
- * @return Value
- */
-template<typename T>
-typename std::enable_if<!HasCallStatic<T>::value >::type
-callStatic(const char *name, Parameters &params)
-{
- std::cout << "has NO call static" << std::endl;
-
- return nullptr;
-}
-
-/**
- * End namespace
- */
-}
-
diff --git a/include/class.h b/include/class.h
index f8e3365..f8ba578 100644
--- a/include/class.h
+++ b/include/class.h
@@ -156,7 +156,27 @@ public:
void property(const char *name, const std::string &value, int flags = Public) { ClassBase::property(name, value, flags); }
void property(const char *name, bool value, int flags = Public) { ClassBase::property(name, value, flags); }
void property(const char *name, double value, int flags = Public) { ClassBase::property(name, value, flags); }
-
+
+ /**
+ * Properties as methods
+ *
+ * This is a smarter way for adding properties to a class. You can define
+ * a property and a method that gets called every time the property is
+ * set or unset.
+ *
+ * If you do not set a setter method, your property will be read-only.
+ *
+ * @param name Name of the property
+ * @param getter The getter method
+ * @param setter The setter method
+ */
+ void property(const char *name, Value (T::*getter)() ) { ClassBase::property(name, static_cast<getter_callback_0>(getter)); }
+ void property(const char *name, Value (T::*getter)() const ) { ClassBase::property(name, static_cast<getter_callback_1>(getter)); }
+ void property(const char *name, Value (T::*getter)() , void (T::*setter)(const Value &value) ) { ClassBase::property(name, static_cast<getter_callback_0>(getter), static_cast<setter_callback_0>(setter)); }
+ void property(const char *name, Value (T::*getter)() const, void (T::*setter)(const Value &value) ) { ClassBase::property(name, static_cast<getter_callback_1>(getter), static_cast<setter_callback_0>(setter)); }
+ void property(const char *name, Value (T::*getter)() , void (T::*setter)(const Value &value) const) { ClassBase::property(name, static_cast<getter_callback_0>(getter), static_cast<setter_callback_1>(setter)); }
+ void property(const char *name, Value (T::*getter)() const, void (T::*setter)(const Value &value) const) { ClassBase::property(name, static_cast<getter_callback_1>(getter), static_cast<setter_callback_1>(setter)); }
+
private:
/**
* Construct a new instance of the object
diff --git a/include/classbase.h b/include/classbase.h
index fac9dbd..6a71ecb 100644
--- a/include/classbase.h
+++ b/include/classbase.h
@@ -52,10 +52,19 @@ typedef Value (Base::*method_callback_6)() const;
typedef Value (Base::*method_callback_7)(Parameters &) const;
/**
+ * Signatures for getters and setters
+ */
+typedef Value (Base::*getter_callback_0)();
+typedef Value (Base::*getter_callback_1)() const;
+typedef void (Base::*setter_callback_0)(const Php::Value &value);
+typedef void (Base::*setter_callback_1)(const Php::Value &value) const;
+
+/**
* Forward declarations
*/
class Method;
class Member;
+class Property;
/**
* Class definition
@@ -87,6 +96,7 @@ public:
_type(that._type),
_methods(that._methods),
_members(that._members),
+ _properties(that._properties),
_entry(nullptr) {}
/**
@@ -98,6 +108,7 @@ public:
_type(that._type),
_methods(std::move(that._methods)),
_members(std::move(that._members)),
+ _properties(std::move(that._properties)),
_entry(that._entry)
{
// other entry are invalid now (not that it is used..., class objects are
@@ -271,6 +282,19 @@ protected:
void property(const char *name, const char *value, int flags = Php::Public);
void property(const char *name, double value, int flags = Php::Public);
+ /**
+ * Set property with callbacks
+ * @param name Name of the property
+ * @param getter Getter method
+ * @param setter Setter method
+ */
+ void property(const char *name, const getter_callback_0 &getter);
+ void property(const char *name, const getter_callback_1 &getter);
+ void property(const char *name, const getter_callback_0 &getter, const setter_callback_0 &setter);
+ void property(const char *name, const getter_callback_1 &getter, const setter_callback_0 &setter);
+ void property(const char *name, const getter_callback_0 &getter, const setter_callback_1 &setter);
+ void property(const char *name, const getter_callback_1 &getter, const setter_callback_1 &setter);
+
private:
/**
* Retrieve an array of zend_function_entry objects that hold the
@@ -283,6 +307,14 @@ private:
const struct _zend_function_entry *entries();
/**
+ * Helper method to turn a property into a zval
+ * @param value
+ * @param type
+ * @return Value
+ */
+ static struct _zval_struct *toZval(Value &&value, int type);
+
+ /**
* Static member functions to create or clone objects based on this class
* @param entry Pointer to class information
* @param val The object to be cloned
@@ -290,6 +322,8 @@ private:
*/
static struct _zend_object_value createObject(struct _zend_class_entry *entry);
static struct _zend_object_value cloneObject(struct _zval_struct *val);
+ static void destructObject(struct _zend_object *object, unsigned int handle);
+ static void freeObject(struct _zend_object *object);
/**
* Static member function that get called when a method or object is called
@@ -502,6 +536,18 @@ private:
* @var std::list
*/
std::list<std::shared_ptr<Member>> _members;
+
+ /**
+ * Map of dynamically accessible properties
+ * @var std::map
+ */
+ std::map<std::string,std::shared_ptr<Property>> _properties;
+
+ /**
+ * Base object has access to the members
+ * This is needed by the Base::store() method
+ */
+ friend class Base;
};
/**
diff --git a/include/globals.h b/include/globals.h
index 0278c88..b996131 100644
--- a/include/globals.h
+++ b/include/globals.h
@@ -68,7 +68,7 @@ public:
};
/**
- * We always have one instance
+ * We always have one instance of the GLOBALS instance
* @var Globals
*/
extern Globals &GLOBALS;
diff --git a/include/hashmember.h b/include/hashmember.h
index 65ca23d..41c40d3 100644
--- a/include/hashmember.h
+++ b/include/hashmember.h
@@ -43,7 +43,7 @@ public:
HashMember &operator=(const Value &value)
{
// set property in parent array
- _base.set(_index, value);
+ _base->set(_index, value);
// if there is a parent, it should sets its value too
if (_parent) _parent->operator=(_base);
@@ -58,7 +58,7 @@ public:
*/
Value value() const
{
- return _base.get(_index);
+ return _base->get(_index);
}
/**
@@ -67,7 +67,7 @@ public:
*/
operator Value () const
{
- return _base.get(_index);
+ return _base->get(_index);
}
/**
@@ -76,7 +76,7 @@ public:
*/
operator int16_t () const
{
- return _base.get(_index).numericValue();
+ return _base->get(_index).numericValue();
}
/**
@@ -85,7 +85,7 @@ public:
*/
operator int32_t () const
{
- return _base.get(_index).numericValue();
+ return _base->get(_index).numericValue();
}
/**
@@ -94,7 +94,7 @@ public:
*/
operator int64_t () const
{
- return _base.get(_index).numericValue();
+ return _base->get(_index).numericValue();
}
/**
@@ -103,7 +103,7 @@ public:
*/
operator bool () const
{
- return _base.get(_index).boolValue();
+ return _base->get(_index).boolValue();
}
/**
@@ -112,7 +112,7 @@ public:
*/
operator std::string () const
{
- return _base.get(_index).stringValue();
+ return _base->get(_index).stringValue();
}
/**
@@ -121,7 +121,7 @@ public:
*/
operator const char * () const
{
- return _base.get(_index).rawValue();
+ return _base->get(_index).rawValue();
}
/**
@@ -130,7 +130,7 @@ public:
*/
operator double () const
{
- return _base.get(_index).decimalValue();
+ return _base->get(_index).decimalValue();
}
/**
@@ -141,7 +141,7 @@ public:
*/
HashMember operator[](int index)
{
- return _base.get(_index)[index].add(this);
+ return _base->get(_index)[index].add(this);
}
/**
@@ -152,7 +152,7 @@ public:
*/
HashMember operator[](const std::string &key)
{
- return _base.get(_index)[key].add(this);
+ return _base->get(_index)[key].add(this);
}
/**
@@ -163,7 +163,7 @@ public:
*/
HashMember operator[](const char *key)
{
- return _base.get(_index)[key].add(this);
+ return _base->get(_index)[key].add(this);
}
/**
@@ -359,7 +359,7 @@ private:
* @param base Base value
* @param index Index in the array
*/
- HashMember(const Value *base, Type index) : _base(*base), _index(index) {}
+ HashMember(Value *base, Type index) : _base(base), _index(index) {}
// @todo add move constructor
@@ -390,7 +390,7 @@ private:
* Base value
* @var Value
*/
- Value _base;
+ Value *_base;
/**
* Parent member (in case of nested members)
diff --git a/include/super.h b/include/super.h
new file mode 100644
index 0000000..73e3761
--- /dev/null
+++ b/include/super.h
@@ -0,0 +1,76 @@
+/**
+ * Super.h
+ *
+ * The Super class is used to implement one of the super variables $_POST,
+ * $_GET, $_SERVER, et cetera
+ *
+ * @copyright 2014 Copernica BV
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ */
+
+/**
+ * Set up namespace
+ */
+namespace Php {
+
+/**
+ * Class definition
+ */
+class Super
+{
+public:
+ /**
+ * Constructor
+ *
+ * Extension writers do not have to access the super-globals themselves.
+ * They are always accessible via Php::POST, Php::GET, et cetera.
+ *
+ * @param index number
+ */
+ Super(int index) : _index(index) {}
+
+ /**
+ * Destructor
+ */
+ virtual ~Super() {}
+
+ /**
+ * Array access operator
+ * This can be used for accessing associative arrays
+ * @param key
+ * @return Value
+ */
+ Value operator[](const std::string &key) const;
+
+ /**
+ * Array access operator
+ * This can be used for accessing associative arrays
+ * @param key
+ * @return Value
+ */
+ Value operator[](const char *key) const;
+
+private:
+ /**
+ * Index number
+ * @var int
+ */
+ int _index;
+};
+
+/**
+ * A number of super-globals are always accessible
+ */
+extern Super POST;
+extern Super GET;
+extern Super COOKIE;
+extern Super SERVER;
+extern Super ENV;
+extern Super FILES;
+extern Super REQUEST;
+
+/**
+ * End namespace
+ */
+}
+
diff --git a/include/value.h b/include/value.h
index f2850c9..fce8750 100644
--- a/include/value.h
+++ b/include/value.h
@@ -112,6 +112,12 @@ public:
Value(struct _zval_struct *zval, bool ref = false);
/**
+ * Wrap around a hash table
+ * @param ht Hashtable to wrap
+ */
+ Value(struct _hashtable *ht);
+
+ /**
* Wrap around an object implemented by us
* @param object Object to be wrapped
*/
@@ -375,9 +381,15 @@ public:
/**
* Retrieve the value as number
- * @return long
+ *
+ * We force this to be a int64_t because we assume that most
+ * servers run 64 bits nowadays, and because we use int32_t, int64_t
+ * almost everywhere, instead of 'long' and on OSX neither of
+ * these intxx_t types is defined as 'long'...
+ *
+ * @return int64_t
*/
- long numericValue() const;
+ int64_t numericValue() const;
/**
* Retrieve the value as boolean
@@ -846,6 +858,18 @@ protected:
struct _zval_struct *detach();
/**
+ * Attach a different zval
+ *
+ * This will first detach the current zval, and link the Value object to
+ * a different zval. Versions exist to attach to a zval and to an entire
+ * hash table
+ *
+ * @param val
+ */
+ void attach(struct _zval_struct *val);
+ void attach(struct _hashtable *hashtable);
+
+ /**
* Set a certain property without running any checks (you must already know
* for sure that this is an array, and that the index is not yet in use)
*
@@ -874,6 +898,7 @@ protected:
friend class Member;
friend class ClassBase;
friend class Iterator;
+ friend class Extension;
};
/**