diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-20 16:52:25 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-20 16:52:25 +0100 |
commit | 4bd9e7af0ab86adc09d449603158c8bc43d7103c (patch) | |
tree | 0c050b642466f8ef029a07a5b325cf3159e12232 /src/hashiterator.h | |
parent | b1f91277a29ddac92479106543ecfd62ff99d152 (diff) |
moved implementation for hashiterator to header file, introduced invaliditerator class, valueiterator now uses the hashiterator class internally
Diffstat (limited to 'src/hashiterator.h')
-rw-r--r-- | src/hashiterator.h | 93 |
1 files changed, 81 insertions, 12 deletions
diff --git a/src/hashiterator.h b/src/hashiterator.h index c37c22b..3c23003 100644 --- a/src/hashiterator.h +++ b/src/hashiterator.h @@ -13,12 +13,6 @@ */ /** - * Forward declaration - */ -struct _hashtable; -struct bucket; - -/** * Set up namespace */ namespace Php { @@ -34,30 +28,105 @@ public: * @param hashtable The hashtable to iterate over * @param first Should it start on the first position? */ - HashIterator(struct _hashtable *hashtable, bool first); + 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 */ - HashIterator(const ValueIterator &that); + HashIterator(const HashIterator &that) : + _table(that._table), _position(that._position) + { + // read current position + read(); + } /** * Destructor */ virtual ~HashIterator() {} + + /** + * Clone the object + * @return IteratorImpl + */ + virtual IteratorImpl *clone() + { + // create a new instance + return new HashIterator(*this); + } /** * Increment position (pre-increment) * @return bool */ - virtual bool increment() override; + 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; + 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 @@ -87,13 +156,13 @@ private: * The hash table over which is being iterated * @var HashTable */ - struct _hashtable *_table = nullptr; + HashTable *_table = nullptr; /** * The position in the hash table * @var HashPosition */ - struct bucket *_position = nullptr; + Bucket *_position = nullptr; /** * The current key and value |