summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-20 16:59:00 +0100
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-03-20 16:59:00 +0100
commit64bbfe2cb99b9214aa78089ad8a14c9c73ed6a16 (patch)
treee563370264326b0ccc3e6f1cfc1d3e614e8c3f01
parent42e2402efb8840ee72d145ac3df8a06ccc8f5c7f (diff)
added missing methods to the hashiterator class
-rw-r--r--src/hashiterator.h61
1 files changed, 59 insertions, 2 deletions
diff --git a/src/hashiterator.h b/src/hashiterator.h
index 3c23003..8573a03 100644
--- a/src/hashiterator.h
+++ b/src/hashiterator.h
@@ -174,13 +174,70 @@ private:
* Read current key and value
* @return bool
*/
- bool read();
+ 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();
+ 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;
+ }
};
/**