diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2013-08-29 01:51:07 -0700 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2013-08-29 01:51:07 -0700 |
commit | 8cb852a298cf8aa260883c5bc474bcf8cb7f9a76 (patch) | |
tree | fe34d039154dc9406ff4295d1dfe94d052052955 | |
parent | 05c421983a0a57fa735fcccee76ad67ca6c67ea4 (diff) |
Initial implementation for array access operators in Value class
-rw-r--r-- | include/value.h | 24 | ||||
-rw-r--r-- | src/value.cpp | 119 |
2 files changed, 137 insertions, 6 deletions
diff --git a/include/value.h b/include/value.h index bf4beef..bc25eab 100644 --- a/include/value.h +++ b/include/value.h @@ -204,13 +204,19 @@ public: * The number of members in case of an array or object * @return int */ - int count(); + int count() + { + return size(); + } /** * The number of members in case of an array or object * @return int */ - int length(); + int length() + { + return size(); + } /** * Cast to an int @@ -255,7 +261,7 @@ public: * @param index * @return Value */ - Value &operator[](int index); + Value operator[](int index); /** * Array access operator @@ -264,7 +270,17 @@ public: * @param key * @return Value */ - Value &operator[](const std::string &key); + Value operator[](const std::string &key); + + /** + * Array access operator + * This can be used for adding a record to the array + * Be aware: if the 'this' object is not already an array, it will be converted into one! + * @param key + * @return Value + */ + //Value operator[](); + protected: /** diff --git a/src/value.cpp b/src/value.cpp index 3c84d9c..64c33ea 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -98,8 +98,11 @@ Value::Value(struct _zval_struct *zval, bool ref) // we see ourselves as reference too Z_ADDREF_P(_val); - // should this be a forced reference - if (ref) Z_SET_ISREF_P(zval); + // we're ready if we do not have to force it as a reference + if (!ref || Z_ISREF_P(zval)) return; + + // make this a reference + Z_SET_ISREF_P(zval); } /** @@ -399,6 +402,118 @@ double Value::decimalValue() } /** + * The number of members in case of an array or object + * @return int + */ +int Value::size() +{ + // is it an array + if (isArray()) return zend_hash_num_elements(Z_ARRVAL_P(_val)); + + // not an array + return 0; +} + +/** + * Array access operator + * This can be used for accessing arrays + * Be aware: if the 'this' object is not already an array, it will be converted into one! + * @param index + * @return Value + */ +Value Value::operator[](int index) +{ + // must be an array + if (!isArray()) setType(arrayType); + + // the result value + zval **result; + + // check if this index is already in the array + if (zend_hash_index_find(Z_ARRVAL_P(_val), index, &result) == FAILURE) + { + // construct a new vale + Value val; + + // we want to add a new record + add_index_zval(Z_ARRVAL_P(_val), index, val._val); + + // make the value a reference, so that changing the value will also update the array + Z_SET_ISREF_P(val._val); + + // done + return val; + } + else + { + // the index is already in the array, if multiple variables all use this + // zval, then we want to seperate it, because the other values should + // not be updated when the member gets updated + SEPARATE_ZVAL_IF_NOT_REF(result); + + // wrap it into a value, and force this to be a reference, so that + // changing the value will also change the array member + return Value(*result, true); + } +} + +/** + * Array access operator + * This can be used for accessing associative arrays + * Be aware: if the 'this' object is not already an array, it will be converted into one! + * @param key + * @return Value + */ +Value Value::operator[](const std::string &key) +{ + // must be an array + if (!isArray()) setType(arrayType); + + // the result value + zval **result; + + // check if this index is already in the array + if (zend_hash_find(Z_ARRVAL_P(_val), key.c_str(), key.size() + 1, &result) == FAILURE) + { + // construct a new vale + Value val; + + // we want to add a new record + add_assoc_zval_ex(Z_ARRVAL_P(_val), key.c_str(), key.size()+1, val._val); + + // make the value a reference, so that changing the value will also update the array + Z_SET_ISREF_P(val._val); + + // done + return val; + } + else + { + // the index is already in the array, if multiple variables all use this + // zval, then we want to seperate it, because the other values should + // not be updated when the member gets updated + SEPARATE_ZVAL_IF_NOT_REF(result); + + // wrap it into a value, and force this to be a reference, so that + // changing the value will also change the array member + return Value(*result, true); + } +} + +/** + * Array access operator + * This can be used for adding a record to the array + * Be aware: if the 'this' object is not already an array, it will be converted into one! + * @param key + * @return Value + */ +//Value Value::operator[]() +//{ +// +// +//} + +/** * End of namespace */ } |