diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-15 01:32:22 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-15 01:32:22 +0100 |
commit | 3300d64c4dd61e71b62d5b55b1f16e34d6335680 (patch) | |
tree | c2bd999ba1a2a1320acba20fb99acf0defb9651e /include | |
parent | 681d1e6aa735568a492140d2307a89063e7aadb9 (diff) | |
parent | cda98dc0dea7144941a46ff20598f3c095d7a6d0 (diff) |
implemented __clone method
Diffstat (limited to 'include')
-rw-r--r-- | include/array.h | 7 | ||||
-rw-r--r-- | include/base.h | 12 | ||||
-rw-r--r-- | include/callstatic.h | 64 | ||||
-rw-r--r-- | include/class.h | 22 | ||||
-rw-r--r-- | include/classbase.h | 46 | ||||
-rw-r--r-- | include/globals.h | 2 | ||||
-rw-r--r-- | include/hashmember.h | 30 | ||||
-rw-r--r-- | include/super.h | 76 | ||||
-rw-r--r-- | include/value.h | 29 |
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 ¶ms) -{ - // 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 ¶ms) -{ - 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; }; /** |