diff options
Diffstat (limited to 'src/hashiterator.h')
-rw-r--r-- | src/hashiterator.h | 250 |
1 files changed, 0 insertions, 250 deletions
diff --git a/src/hashiterator.h b/src/hashiterator.h deleted file mode 100644 index b1f409f..0000000 --- a/src/hashiterator.h +++ /dev/null @@ -1,250 +0,0 @@ -/** - * HashIterator.h - * - * This is an internal helper class that is used when iterating over a - * Php::Value object that holds a hash table (an array or an object that - * does not implement the Traversable interface - stl style. - * - * Thus, when you do c++ things like "for (auto &iter : value)", internally - * a ValueIterator object is being used. - * - * @author Emiel Bruijntjes - * @copyright 2014 Copernica BV - */ - -/** - * Set up namespace - */ -namespace Php { - -/** - * Class definition - */ -class HashIterator : public ValueIteratorImpl -{ -public: - /** - * Constructor - * @param hashtable The hashtable to iterate over - * @param first Should it start on the first position? - * @param tsrm_ls - */ - HashIterator(HashTable *hashtable, bool first) : _table(hashtable) - { - // reset the hash pointer to the internal position - if (hashtable && first) - { - // move to first position - zend_hash_internal_pointer_reset_ex(_table, &_position); - - // read current data - if (read()) return; - - // data was private, move on - increment(); - } - else - { - // start with invalid data - invalidate(); - } - } - - /** - * Copy constructor - * @param that - * @param tsrm_ls - */ - HashIterator(const HashIterator &that TSRMLS_DC) : - _table(that._table), _position(that._position) - { - // read current position - read(); - } - - /** - * Destructor - */ - virtual ~HashIterator() {} - - /** - * Clone the object - * @param tsrm_ls - * @return ValueIteratorImpl - */ - virtual ValueIteratorImpl *clone() - { - // create a new instance - return new HashIterator(*this); - } - - /** - * Increment position (pre-increment) - * @return bool - */ - virtual bool increment() override - { - // leap out if already on an invalid pos (behind the last pos) - if (!_position) return false; - - // move the iterator forward - if (zend_hash_move_forward_ex(_table, &_position) == SUCCESS) - { - // read current key and value - if (read()) return true; - - // data was private or invalid, move further - return increment(); - } - else - { - // invalidate current position - return invalidate(); - } - } - - /** - * Decrement position (pre-decrement) - * @return bool - */ - virtual bool decrement() override - { - // leap out if we're not even iterating over a hash table - if (!_table) return false; - - // if position is invalid, it is one position behind the last position - if (!_position) - { - // move to last position - zend_hash_internal_pointer_end_ex(_table, &_position); - } - else if (zend_hash_move_backwards_ex(_table, &_position) == FAILURE) - { - // invalidate current position - return invalidate(); - } - - // read current key and value - if (read()) return true; - - // data was private, move on - return decrement(); - } - - /** - * Compare with other iterator - * @param that - * @return bool - */ - virtual bool equals(const ValueIteratorImpl *that) const override - { - // this always is a hash iterator - HashIterator *other = (HashIterator *)that; - - // compare the positions - return _position == other->_position; - } - - /** - * Derefecence, this returns a std::pair with the current key and value - * @return std::pair - */ - virtual const std::pair<Value,Value> ¤t() const override - { - return _current; - } - -private: - /** - * The hash table over which is being iterated - * @var HashTable - */ - HashTable *_table = nullptr; - - /** - * The position in the hash table - * @var HashPosition - */ - Bucket *_position = nullptr; - - /** - * The current key and value - * @var std::pair - */ - std::pair<Value,Value> _current; - - /** - * Read current key and value - * @return bool - */ - bool read() - { - // zval to read the current key in - Value key; - -#if PHP_VERSION_ID >= 50500 - - // read in the current key - zend_hash_get_current_key_zval_ex(_table, key._val, &_position); - - // if the key is set to NULL, it means that the object is not at a valid position - if (key.isNull()) return invalidate(); - -#else - - // php 5.3 and php 5.4 need a different implementation because the function - // zend_hash_get_current_key_zval_ex is missing in php 5.3, declare variables - // we need for storing the key in - char *string_key; - unsigned int str_len; - unsigned long num_key; - - // get the current key - int type = zend_hash_get_current_key_ex(_table, &string_key, &str_len, &num_key, 0, &_position); - - // if key is not found, the iterator is at an invalid position - if (type == HASH_KEY_NON_EXISTANT) return invalidate(); - - // numeric keys are the easiest ones - if (type == HASH_KEY_IS_LONG) key = (int64_t)num_key; - else key = string_key; - -#endif - - // iterator is at a valid position, go fetch the data - // this is the variable we need for fetching the data - zval **value; - - // retrieve data - zend_hash_get_current_data_ex(_table, (void **) &value, &_position); - - // we can now update the current data - _current = std::make_pair<Value,Value>(std::move(key), *value); - - // if the key is private (it starts with a null character) we should return - // false to report that the object is not in a completely valid state - return !_current.first.isString() || _current.first.rawValue()[0]; - } - - /** - * Invalidate the iterator - * @return bool - */ - bool invalidate() - { - // forget current position - _position = nullptr; - - // make the data a pair of null ptrs - _current = std::make_pair<Value,Value>(nullptr,nullptr); - - // done - return false; - } -}; - -/** - * End namespace - */ -} - |