summaryrefslogtreecommitdiff
path: root/zend/iteratorimpl.cpp
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-06 21:53:24 +0200
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-06 21:53:24 +0200
commit35fd3ccbeb4def71b4d8a59dfbb5c31201b099b9 (patch)
tree915223360aed4743aa6127fde4836aa413a260e5 /zend/iteratorimpl.cpp
parentda4710512865e6816585ac4ab8edab2fa125e2d8 (diff)
renamed src directory to zend directory, disabled TSRM debug code
Diffstat (limited to 'zend/iteratorimpl.cpp')
-rw-r--r--zend/iteratorimpl.cpp183
1 files changed, 183 insertions, 0 deletions
diff --git a/zend/iteratorimpl.cpp b/zend/iteratorimpl.cpp
new file mode 100644
index 0000000..2750ddb
--- /dev/null
+++ b/zend/iteratorimpl.cpp
@@ -0,0 +1,183 @@
+/**
+ * IteratorImpl.cpp
+ *
+ * Implementation file of the IteratorImpl class
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2014 Copernica BV
+ */
+#include "includes.h"
+
+/**
+ * Set up namespace
+ */
+namespace Php {
+
+/**
+ * Helper method to get access to ourselves
+ * @param iter
+ * @return IteratorImpl
+ */
+static IteratorImpl *self(zend_object_iterator *iter)
+{
+ return (IteratorImpl *)iter->data;
+}
+
+/**
+ * Iterator destructor method
+ * @param iter
+ * @param tsrm_ls
+ */
+void IteratorImpl::destructor(zend_object_iterator *iter TSRMLS_DC)
+{
+ // delete the object
+ delete self(iter);
+}
+
+/**
+ * Iterator valid function
+ * Returns FAILURE or SUCCESS
+ * @param iter
+ * @param tsrm_ls
+ * @return int
+ */
+int IteratorImpl::valid(zend_object_iterator *iter TSRMLS_DC)
+{
+ // check if valid
+ return self(iter)->valid() ? SUCCESS : FAILURE;
+}
+
+/**
+ * Fetch the current item
+ * @param iter
+ * @param data
+ * @param tsrm_ls
+ */
+void IteratorImpl::current(zend_object_iterator *iter, zval ***data TSRMLS_DC)
+{
+ // get the actual iterator
+ IteratorImpl *iterator = self(iter);
+
+ // retrieve the value (and store it in a member so that it is not
+ // destructed when the function returns)
+ iterator->_current = iterator->current();
+
+ // copy the value
+ *data = &iterator->_current._val;
+}
+
+/**
+ * Fetch the key for the current element (optional, may be NULL). The key
+ * should be written into the provided zval* using the ZVAL_* macros. If
+ * this handler is not provided auto-incrementing integer keys will be
+ * used.
+ * @param iter
+ * @param key
+ * @param tsrm_ls
+ */
+void IteratorImpl::key(zend_object_iterator *iter, zval *key TSRMLS_DC)
+{
+ // retrieve the key
+ Value retval(self(iter)->key());
+
+ // detach the underlying zval
+ zval *val = retval.detach();
+
+ // copy it to the key
+ ZVAL_ZVAL(key, val, 1, 1);
+}
+
+/**
+ * Function to retrieve the current key, php 5.3 style
+ * @param iter
+ * @param str_key
+ * @param str_key_len
+ * @param int_key
+ * @param tsrm_ls
+ * @return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG
+ */
+int IteratorImpl::key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
+{
+ // retrieve the key
+ Value retval(self(iter)->key());
+
+ // is this a numeric string?
+ if (retval.isString())
+ {
+ // copy the key and the from the value
+ *str_key = estrndup(retval.rawValue(), retval.size());
+ *str_key_len = retval.size() + 1;
+
+ // done
+ return HASH_KEY_IS_STRING;
+ }
+ else
+ {
+ // convert to a numeric
+ *int_key = retval.numericValue();
+
+ // done
+ return HASH_KEY_IS_LONG;
+ }
+}
+
+/**
+ * Step forwards to the next element
+ * @param iter
+ * @param tsrm_ls
+ */
+void IteratorImpl::next(zend_object_iterator *iter TSRMLS_DC)
+{
+ // call the next method
+ self(iter)->next();
+}
+
+/**
+ * Rewind the iterator back to the start
+ * @param iter
+ * @param tsrm_ls
+ */
+void IteratorImpl::rewind(zend_object_iterator *iter TSRMLS_DC)
+{
+ // call the rewind method
+ self(iter)->rewind();
+}
+
+/**
+ * Get access to all iterator functions
+ * @return zend_object_iterator_funcs
+ */
+zend_object_iterator_funcs *IteratorImpl::functions()
+{
+ // static variable with all functions
+ static zend_object_iterator_funcs funcs;
+
+ // static variable that knows if the funcs are already initialized
+ static bool initialized = false;
+
+ // no need to set anything if already initialized
+ if (initialized) return &funcs;
+
+ // set the members
+ funcs.dtor = &IteratorImpl::destructor;
+ funcs.valid = &IteratorImpl::valid;
+ funcs.get_current_data = &IteratorImpl::current;
+ funcs.get_current_key = &IteratorImpl::key;
+ funcs.move_forward = &IteratorImpl::next;
+ funcs.rewind = &IteratorImpl::rewind;
+
+ // invalidate is not yet supported
+ funcs.invalidate_current = nullptr;
+
+ // remember that functions are initialized
+ initialized = true;
+
+ // done
+ return &funcs;
+}
+
+/**
+ * End namespace
+ */
+}
+