diff options
-rw-r--r-- | include/classbase.h | 8 | ||||
-rw-r--r-- | include/global.h | 8 | ||||
-rw-r--r-- | include/hashmember.h | 181 | ||||
-rw-r--r-- | include/hashparent.h | 92 | ||||
-rw-r--r-- | include/value.h | 29 | ||||
-rw-r--r-- | phpcpp.h | 1 | ||||
-rw-r--r-- | src/includes.h | 1 | ||||
-rw-r--r-- | src/value.cpp | 30 |
8 files changed, 240 insertions, 110 deletions
diff --git a/include/classbase.h b/include/classbase.h index 4e03f1c..f4a6f22 100644 --- a/include/classbase.h +++ b/include/classbase.h @@ -94,10 +94,10 @@ public: ClassBase(const ClassBase &that) : _name(that._name), _type(that._type), + _entry(that._entry), _methods(that._methods), _members(that._members), - _properties(that._properties), - _entry(nullptr) {} + _properties(that._properties) {} /** * Move constructor @@ -106,10 +106,10 @@ public: ClassBase(ClassBase &&that) : _name(std::move(that._name)), _type(that._type), + _entry(that._entry), _methods(std::move(that._methods)), _members(std::move(that._members)), - _properties(std::move(that._properties)), - _entry(that._entry) + _properties(std::move(that._properties)) { // other entry are invalid now (not that it is used..., class objects are // only moved during extension setup, when the entry pointer has not yet diff --git a/include/global.h b/include/global.h index 4531f77..ae54212 100644 --- a/include/global.h +++ b/include/global.h @@ -106,13 +106,13 @@ public: * @param value Value to set * @return Value The value that was set */ - virtual const Value &set(int index, const Value &value) override + virtual void set(int index, const Value &value) override { // update current object update(); // call base - return Value::set(index, value); + Value::set(index, value); } /** @@ -123,13 +123,13 @@ public: * @param value Value to set * @return Value The value that was set */ - virtual const Value &set(const char *key, int size, const Value &value) override + virtual void set(const char *key, int size, const Value &value) override { // update current object update(); // call base - return Value::set(key, size, value); + Value::set(key, size, value); } diff --git a/include/hashmember.h b/include/hashmember.h index 0bb5a4c..6603b57 100644 --- a/include/hashmember.h +++ b/include/hashmember.h @@ -24,26 +24,20 @@ namespace Php { class Value; /** - * Base class for hash members - */ -class HashMemberBase -{ -public: - /** - * Assignment operator - * @param param value - */ - virtual void assign(const Value &value) = 0; -}; - -/** * Member class */ template <typename Type> -class HashMember : public HashMemberBase +class HashMember : private HashParent { public: /** + * Constructor + * @param parent + * @param index + */ + HashMember(HashParent *parent, Type index) : _parent(parent), _index(index) {} + + /** * Destructor */ virtual ~HashMember() {} @@ -55,9 +49,9 @@ public: */ HashMember &operator=(const Value &value) { - // assign the property - assign(value); - + // set new value in the parent + _parent->set(_index, value); + // done return *this; } @@ -69,7 +63,8 @@ public: */ bool exists() const { - return _base.contains(_index); + // ask the parent + return _parent->contains(_index); } /** @@ -78,7 +73,7 @@ public: */ Value value() const { - return _base.get(_index); + return _parent->get(_index); } /** @@ -87,7 +82,7 @@ public: */ operator Value () const { - return _base.get(_index); + return _parent->get(_index); } /** @@ -96,7 +91,7 @@ public: */ operator int16_t () const { - return _base.get(_index).numericValue(); + return value().numericValue(); } /** @@ -105,7 +100,7 @@ public: */ operator int32_t () const { - return _base.get(_index).numericValue(); + return value().numericValue(); } /** @@ -114,7 +109,7 @@ public: */ operator int64_t () const { - return _base.get(_index).numericValue(); + return value().numericValue(); } /** @@ -123,7 +118,7 @@ public: */ operator bool () const { - return _base.get(_index).boolValue(); + return value().boolValue(); } /** @@ -132,7 +127,7 @@ public: */ operator std::string () const { - return _base.get(_index).stringValue(); + return value().stringValue(); } /** @@ -141,7 +136,7 @@ public: */ operator const char * () const { - return _base.get(_index).rawValue(); + return value().rawValue(); } /** @@ -150,7 +145,7 @@ public: */ operator double () const { - return _base.get(_index).decimalValue(); + return value().floatValue(); } /** @@ -161,7 +156,7 @@ public: */ HashMember<int> operator[](int index) { - return _base.get(_index)[index].add(this); + return HashMember<int>(this, index); } /** @@ -172,7 +167,7 @@ public: */ HashMember<std::string> operator[](const std::string &key) { - return _base.get(_index)[key].add(this); + return HashMember<std::string>(this, key); } /** @@ -183,11 +178,11 @@ public: */ HashMember<std::string> operator[](const char *key) { - return _base.get(_index)[key].add(this); + return HashMember<std::string>(this, key); } /** - * Add a value to the object + * Add a value to the object (or other arithmetric operators) * @param value * @return HashMember */ @@ -373,70 +368,124 @@ public: Value operator()(Value param0, Value param1, Value param2, Value param3, Value param4, Value param5, Value param6, Value param7, Value param8) { return value()(param0, param1, param2, param3, param4, param5, param6, param7, param8); } Value operator()(Value param0, Value param1, Value param2, Value param3, Value param4, Value param5, Value param6, Value param7, Value param8, Value param9) { return value()(param0, param1, param2, param3, param4, param5, param6, param7, param8, param9); } -private: /** - * Constructor - * @param base Base value - * @param index Index in the array + * Check if a certain key exists in the array/object + * @param key + * @return bool */ - HashMember(struct _zval_struct *base, Type index) : _base(base, true), _index(index) {} + virtual bool contains(const std::string &key) const override + { + // object must exist, and the value must contain the key + return exists() && value().contains(key); + } - // @todo add move constructor + /** + * Check if a certain index exists in the array/object + * @param key + * @return bool + */ + virtual bool contains(int index) const override + { + // object must exist, and the value must contain the key + return exists() && value().contains(index); + } /** - * Protected copy constructor - * @param value Other element + * Retrieve the value at a string index + * @param key + * @return Value */ - HashMember(const HashMember<Type> &member) : _base(member._base._val, true), _index(member._index), _parent(member._parent) {} + virtual Value get(const std::string &key) const override + { + // return null if it does not exist + if (!exists()) return nullptr; + + // ask the value + return value().get(key); + } /** - * Add parent - * @param parent + * Retrieve the value at a numeric index + * @param index + * @return Value */ - HashMember &add(HashMemberBase *parent) + virtual Value get(int index) const override { - _parent = parent; - return *this; + // return null if it does not exist + if (!exists()) return nullptr; + + // ask the value + return value().get(index); } - + /** - * Implementation of the assign method + * Overwrite the value at a certain string index + * @param key * @param value */ - virtual void assign(const Value &value) override + virtual void set(const std::string &key, const Value &value) override { - // set property in parent array - _base.set(_index, value); - - // if there is a parent, it should sets its value too - if (_parent) _parent->assign(_base); + // get the current value + Value current(this->value()); + + // add the value + current[key] = value; + + // pass this to the base + _parent->set(_index, current); } /** - * The original index - * @var Type + * Overwrite the value at a certain numeric index + * @param index + * @param value */ - Type _index; - + virtual void set(int index, const Value &value) override + { + // get the current value + Value current(value()); + + // add the value + current[index] = value; + + // pass this to the base + _parent->set(_index, current); + } + +protected: + /** + * Protected copy constructor + * @param value Other element + */ + HashMember(const HashMember<Type> &member) : _parent(member._parent), _index(member._index) {} + + /** + * Move constructor + * @param value Other element + */ +// HashMember(HashMember<Type> &&member) : +// _parent(std::move(member._parent)), _index(std::move(member._index)) {} + +private: /** * Base value - * @var Value + * @var */ - Value _base; + HashParent *_parent; /** - * Parent member (in case of nested members) - * @var HashMemberBase + * The original index + * @var Type */ - HashMemberBase *_parent = nullptr; + Type _index; /** - * Only value objects may construct members + * Friend classes */ - friend class Value; - friend class Base; - friend class HashMember<int>; friend class HashMember<std::string>; + friend class HashMember<int>; + friend class Base; + friend class Value; }; /** diff --git a/include/hashparent.h b/include/hashparent.h new file mode 100644 index 0000000..4c2ee68 --- /dev/null +++ b/include/hashparent.h @@ -0,0 +1,92 @@ +/** + * HashParent.h + * + * Interface that is implemented by all objects that can be accessed with + * array-access variables ([]). When the value of a hash-member is changed, + * it will call one of the methods from this class to set the new property + * + * This is an internal class that you normally not need when writing + * extensions. It is used by the PHP-CPP library when you use constructs + * like value["x"]["y"] = 10; + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2014 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Forwards + */ +class Value; + +/** + * Class definition + */ +class HashParent +{ +protected: + /** + * Protected constructor - users should not instantiate HashParent + * objects themselved. Use a Value object instead. + */ + HashParent() {} + +public: + /** + * Destructor + */ + virtual ~HashParent() {} + + /** + * Check if a certain key exists in the array/object + * @param key + * @return bool + */ + virtual bool contains(const std::string &key) const = 0; + + /** + * Check if a certain index exists in the array/object + * @param key + * @return bool + */ + virtual bool contains(int index) const = 0; + + /** + * Retrieve the value at a string index + * @param key + * @return Value + */ + virtual Value get(const std::string &key) const = 0; + + /** + * Retrieve the value at a numeric index + * @param index + * @return Value + */ + virtual Value get(int index) const = 0; + + /** + * Overwrite the value at a certain string index + * @param key + * @param value + */ + virtual void set(const std::string &key, const Value &value) = 0; + + /** + * Overwrite the value at a certain numeric index + * @param index + * @param value + */ + virtual void set(int index, const Value &value) = 0; + +}; + +/** + * End namespace + */ +} + diff --git a/include/value.h b/include/value.h index 34ac510..2e1dd84 100644 --- a/include/value.h +++ b/include/value.h @@ -38,7 +38,7 @@ template <class Type> class HashMember; /** * Class definition */ -class Value +class Value : private HashParent { public: /** @@ -543,14 +543,14 @@ public: * @param index * @return bool */ - bool contains(int index) const; + virtual bool contains(int index) const override; /** * Is a certain key set in the array * @param key * @return bool */ - bool contains(const std::string &key) const + virtual bool contains(const std::string &key) const override { return contains(key.c_str(), key.size()); } @@ -671,7 +671,7 @@ public: * @param index * @return Value */ - Value get(int index) const; + virtual Value get(int index) const override; /** * Get access to a certain assoc member @@ -686,7 +686,7 @@ public: * @param key * @return Value */ - Value get(const std::string &key) const + virtual Value get(const std::string &key) const override { return get(key.c_str(), key.size()); } @@ -698,7 +698,7 @@ public: * @param value Value to set * @return Value The value that was set */ - virtual const Value &set(int index, const Value &value); + virtual void set(int index, const Value &value) override; /** * Set a certain property @@ -706,20 +706,18 @@ public: * @param key Key of the property to set * @param size Size of the key * @param value Value to set - * @return Value The value that was set */ - virtual const Value &set(const char *key, int size, const Value &value); + virtual void set(const char *key, int size, const Value &value); /** * Set a certain property * Calling this method will turn the object into an array * @param key Key to set * @param value Value to set - * @return Value The value that was set */ - const Value &set(const char *key, const Value &value) + void set(const char *key, const Value &value) { - return set(key, strlen(key), value); + set(key, strlen(key), value); } /** @@ -727,9 +725,8 @@ public: * Calling this method will turn the object into an array * @param key Key to set * @param value Value to set - * @return Value The value that was set */ - const Value &set(const std::string &key, const Value &value) + virtual void set(const std::string &key, const Value &value) override { return set(key.c_str(), key.size(), value); } @@ -919,9 +916,8 @@ protected: * * @param index Index of the property to set * @param value Value to set - * @return Value The value that was set */ - const Value &setRaw(int index, const Value &value); + void setRaw(int index, const Value &value); /** * Set a certain property without any checks (you must already know for @@ -931,9 +927,8 @@ protected: * @param key Key of the property to set * @param size Size of the key * @param value Value to set - * @return Value The value that was set */ - const Value &setRaw(const char *key, int size, const Value &value); + void setRaw(const char *key, int size, const Value &value); /** * Internal helper method to create an iterator @@ -54,6 +54,7 @@ #include <phpcpp/exception.h> #include <phpcpp/streams.h> #include <phpcpp/type.h> +#include <phpcpp/hashparent.h> #include <phpcpp/value.h> #include <phpcpp/valueiterator.h> #include <phpcpp/array.h> diff --git a/src/includes.h b/src/includes.h index 50cb65f..f06f686 100644 --- a/src/includes.h +++ b/src/includes.h @@ -42,6 +42,7 @@ #include "../include/exception.h" #include "../include/streams.h" #include "../include/type.h" +#include "../include/hashparent.h" #include "../include/value.h" #include "../include/valueiterator.h" #include "../include/array.h" diff --git a/src/value.cpp b/src/value.cpp index 26c753f..6684bd0 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -1741,7 +1741,7 @@ Value Value::get(const char *key, int size) const * @param value * @return Value */ -const Value &Value::setRaw(int index, const Value &value) +void Value::setRaw(int index, const Value &value) { // if this is not a reference variable, we should detach it to implement copy on write SEPARATE_ZVAL_IF_NOT_REF(&_val); @@ -1751,19 +1751,15 @@ const Value &Value::setRaw(int index, const Value &value) // the variable has one more reference (the array entry) Z_ADDREF_P(value._val); - - // done - return value; } - /** * Set a certain property * @param index * @param value * @return Value */ -const Value &Value::set(int index, const Value &value) +void Value::set(int index, const Value &value) { // the current value zval **current; @@ -1772,14 +1768,14 @@ const Value &Value::set(int index, const Value &value) if (isArray() && zend_hash_index_find(Z_ARRVAL_P(_val), index, (void **)¤t) != FAILURE) { // skip if nothing is going to change - if (value._val == *current) return value; + if (value._val == *current) return; } // must be an array setType(Type::Array); // set property - return setRaw(index, value); + setRaw(index, value); } /** @@ -1787,9 +1783,8 @@ const Value &Value::set(int index, const Value &value) * @param key * @param size * @param value - * @return Value */ -const Value &Value::setRaw(const char *key, int size, const Value &value) +void Value::setRaw(const char *key, int size, const Value &value) { // is this an object? if (isObject()) @@ -1817,9 +1812,6 @@ const Value &Value::setRaw(const char *key, int size, const Value &value) // the variable has one more reference (the array entry) Z_ADDREF_P(value._val); } - - // done - return value; } /** @@ -1829,7 +1821,7 @@ const Value &Value::setRaw(const char *key, int size, const Value &value) * @param value * @return Value */ -const Value &Value::set(const char *key, int size, const Value &value) +void Value::set(const char *key, int size, const Value &value) { // the current value zval **current; @@ -1838,14 +1830,14 @@ const Value &Value::set(const char *key, int size, const Value &value) if (isArray() && zend_hash_find(Z_ARRVAL_P(_val), key, size + 1, (void **)¤t) != FAILURE) { // skip if nothing is going to change - if (value._val == *current) return value; + if (value._val == *current) return; } // this should be an object or an array if (!isObject()) setType(Type::Array); // done - return setRaw(key, size, value); + setRaw(key, size, value); } /** @@ -1856,7 +1848,7 @@ const Value &Value::set(const char *key, int size, const Value &value) */ HashMember<int> Value::operator[](int index) { - return HashMember<int>(_val, index); + return HashMember<int>(this, index); } /** @@ -1867,7 +1859,7 @@ HashMember<int> Value::operator[](int index) */ HashMember<std::string> Value::operator[](const std::string &key) { - return HashMember<std::string>(_val, key); + return HashMember<std::string>(this, key); } /** @@ -1878,7 +1870,7 @@ HashMember<std::string> Value::operator[](const std::string &key) */ HashMember<std::string> Value::operator[](const char *key) { - return HashMember<std::string>(_val, key); + return HashMember<std::string>(this, key); } /** |