summaryrefslogtreecommitdiff
path: root/src/hashiterator.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/hashiterator.h')
-rw-r--r--src/hashiterator.h93
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