summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-05 19:30:13 +0200
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-05 19:30:13 +0200
commit479e9979a69b9fdb995525576d4588cd92239ed5 (patch)
treee55dcfc2aca533be034cbc84472056ebce272536
parentf407d6d4c5ea35f73c5aec72f8b492c259dc7dfe (diff)
removed zend code from the iterator header file, and moved it into the src directory
-rw-r--r--include/iterator.h88
-rw-r--r--include/value.h2
-rw-r--r--src/classimpl.cpp2
-rw-r--r--src/includes.h1
-rw-r--r--src/iteratorimpl.cpp (renamed from src/iterator.cpp)97
-rw-r--r--src/iteratorimpl.h190
-rw-r--r--src/valueiteratorimpl.h2
7 files changed, 229 insertions, 153 deletions
diff --git a/include/iterator.h b/include/iterator.h
index ad9820a..331c8b3 100644
--- a/include/iterator.h
+++ b/include/iterator.h
@@ -64,7 +64,7 @@ public:
*/
virtual void rewind() = 0;
-private:
+protected:
/**
* During the lifetime of the iterator, the object over which
* it iterates is keps as a private variable. This ensures that
@@ -73,92 +73,6 @@ private:
*/
Value _object;
- /**
- * The current() method that is called by the Zend engine wants a
- * pointer-to-pointer-to-a-zval. Because of this, we have to keep the
- * current value in memory after the current() method returns because
- * the pointer would otherwise fall out of scope. This is (once again)
- * odd behavior of the Zend engine, but we'll have to live with that
- * @var Value
- */
- Value _current;
-
- /**
- * Internal method that returns the implementation object
- * @return zend_object_iterator
- */
- struct _zend_object_iterator *implementation();
-
- /**
- * Iterator destructor method
- * @param iter
- * @param tsrm_ls
- */
- static void destructor(struct _zend_object_iterator *iter TSRMLS_DC);
-
- /**
- * Iterator valid function
- * Returns FAILURE or SUCCESS
- * @param iter
- * @param tsrm_ls
- * @return int
- */
- static int valid(struct _zend_object_iterator *iter TSRMLS_DC);
-
- /**
- * Fetch the current item
- * @param iter
- * @param data
- * @param tsrm_ls
- */
- static void current(struct _zend_object_iterator *iter, struct _zval_struct ***data TSRMLS_DC);
-
- /**
- * 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 data
- * @param tsrm_ls
- */
- static void key(struct _zend_object_iterator *iter, struct _zval_struct *data TSRMLS_DC);
-
- /**
- * 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
- */
- static int key(struct _zend_object_iterator *iter, char **str_key, unsigned int *str_key_len, unsigned long *int_key TSRMLS_DC);
-
- /**
- * Step forwards to the next element
- * @param iter
- * @param tsrm_ls
- */
- static void next(struct _zend_object_iterator *iter TSRMLS_DC);
-
- /**
- * Rewind the iterator back to the start
- * @param iter
- * @param tsrm_ls
- */
- static void rewind(struct _zend_object_iterator *iter TSRMLS_DC);
-
- /**
- * Get access to all iterator functions
- * @return zend_object_iterator_funcs
- */
- static struct _zend_object_iterator_funcs *functions();
-
- /**
- * Classbase is a friend
- */
- friend class ClassImpl;
};
/**
diff --git a/include/value.h b/include/value.h
index e7fa825..844f978 100644
--- a/include/value.h
+++ b/include/value.h
@@ -943,7 +943,7 @@ protected:
friend class Globals;
friend class Member;
friend class ClassImpl;
- friend class Iterator;
+ friend class IteratorImpl;
friend class Extension;
friend class HashIterator;
friend class TraverseIterator;
diff --git a/src/classimpl.cpp b/src/classimpl.cpp
index 3999cf3..ea7fdd7 100644
--- a/src/classimpl.cpp
+++ b/src/classimpl.cpp
@@ -1246,7 +1246,7 @@ zend_object_iterator *ClassImpl::getIterator(zend_class_entry *entry, zval *obje
try
{
// create an iterator
- auto *iterator = traversable->getIterator();
+ auto *iterator = new IteratorImpl(traversable->getIterator());
// return the implementation
return iterator->implementation();
diff --git a/src/includes.h b/src/includes.h
index ace1401..f725ae1 100644
--- a/src/includes.h
+++ b/src/includes.h
@@ -97,6 +97,7 @@
#include "hashiterator.h"
#include "invaliditerator.h"
#include "traverseiterator.h"
+#include "iteratorimpl.h"
#include "streambuf.h"
#include "classimpl.h"
diff --git a/src/iterator.cpp b/src/iteratorimpl.cpp
index d797924..2750ddb 100644
--- a/src/iterator.cpp
+++ b/src/iteratorimpl.cpp
@@ -1,7 +1,7 @@
/**
- * Iterator.cpp
+ * IteratorImpl.cpp
*
- * Implementation file of the Iterator class
+ * Implementation file of the IteratorImpl class
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2014 Copernica BV
@@ -14,20 +14,24 @@
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 Iterator::destructor(zend_object_iterator *iter TSRMLS_DC)
+void IteratorImpl::destructor(zend_object_iterator *iter TSRMLS_DC)
{
- // get the actual iterator
- Iterator *iterator = (Iterator *)iter->data;
-
- // delete the iterator
- delete iterator;
-
- // free memory for the meta object
- efree(iter);
+ // delete the object
+ delete self(iter);
}
/**
@@ -37,13 +41,10 @@ void Iterator::destructor(zend_object_iterator *iter TSRMLS_DC)
* @param tsrm_ls
* @return int
*/
-int Iterator::valid(zend_object_iterator *iter TSRMLS_DC)
+int IteratorImpl::valid(zend_object_iterator *iter TSRMLS_DC)
{
- // get the actual iterator
- Iterator *iterator = (Iterator *)iter->data;
-
// check if valid
- return iterator->valid() ? SUCCESS : FAILURE;
+ return self(iter)->valid() ? SUCCESS : FAILURE;
}
/**
@@ -52,10 +53,10 @@ int Iterator::valid(zend_object_iterator *iter TSRMLS_DC)
* @param data
* @param tsrm_ls
*/
-void Iterator::current(zend_object_iterator *iter, zval ***data TSRMLS_DC)
+void IteratorImpl::current(zend_object_iterator *iter, zval ***data TSRMLS_DC)
{
// get the actual iterator
- Iterator *iterator = (Iterator *)iter->data;
+ IteratorImpl *iterator = self(iter);
// retrieve the value (and store it in a member so that it is not
// destructed when the function returns)
@@ -74,13 +75,10 @@ void Iterator::current(zend_object_iterator *iter, zval ***data TSRMLS_DC)
* @param key
* @param tsrm_ls
*/
-void Iterator::key(zend_object_iterator *iter, zval *key TSRMLS_DC)
+void IteratorImpl::key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
- // get the actual iterator
- Iterator *iterator = (Iterator *)iter->data;
-
// retrieve the key
- Value retval(iterator->key());
+ Value retval(self(iter)->key());
// detach the underlying zval
zval *val = retval.detach();
@@ -98,13 +96,10 @@ void Iterator::key(zend_object_iterator *iter, zval *key TSRMLS_DC)
* @param tsrm_ls
* @return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG
*/
-int Iterator::key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
+int IteratorImpl::key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
{
- // get the actual iterator
- Iterator *iterator = (Iterator *)iter->data;
-
// retrieve the key
- Value retval(iterator->key());
+ Value retval(self(iter)->key());
// is this a numeric string?
if (retval.isString())
@@ -131,13 +126,10 @@ int Iterator::key(zend_object_iterator *iter, char **str_key, uint *str_key_len,
* @param iter
* @param tsrm_ls
*/
-void Iterator::next(zend_object_iterator *iter TSRMLS_DC)
+void IteratorImpl::next(zend_object_iterator *iter TSRMLS_DC)
{
- // get the actual iterator
- Iterator *iterator = (Iterator *)iter->data;
-
// call the next method
- iterator->next();
+ self(iter)->next();
}
/**
@@ -145,20 +137,17 @@ void Iterator::next(zend_object_iterator *iter TSRMLS_DC)
* @param iter
* @param tsrm_ls
*/
-void Iterator::rewind(zend_object_iterator *iter TSRMLS_DC)
+void IteratorImpl::rewind(zend_object_iterator *iter TSRMLS_DC)
{
- // get the actual iterator
- Iterator *iterator = (Iterator *)iter->data;
-
// call the rewind method
- iterator->rewind();
+ self(iter)->rewind();
}
/**
* Get access to all iterator functions
* @return zend_object_iterator_funcs
*/
-zend_object_iterator_funcs *Iterator::functions()
+zend_object_iterator_funcs *IteratorImpl::functions()
{
// static variable with all functions
static zend_object_iterator_funcs funcs;
@@ -170,12 +159,12 @@ zend_object_iterator_funcs *Iterator::functions()
if (initialized) return &funcs;
// set the members
- funcs.dtor = &Iterator::destructor;
- funcs.valid = &Iterator::valid;
- funcs.get_current_data = &Iterator::current;
- funcs.get_current_key = &Iterator::key;
- funcs.move_forward = &Iterator::next;
- funcs.rewind = &Iterator::rewind;
+ 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;
@@ -188,24 +177,6 @@ zend_object_iterator_funcs *Iterator::functions()
}
/**
- * Internal method that returns the implementation object
- * @return zend_object_iterator
- */
-struct _zend_object_iterator *Iterator::implementation()
-{
- // create an iterator
- zend_object_iterator *iterator = (zend_object_iterator *)emalloc(sizeof(zend_object_iterator));
-
- // initialize all properties
- iterator->data = this;
- iterator->index = 0;
- iterator->funcs = functions();
-
- // done
- return iterator;
-}
-
-/**
* End namespace
*/
}
diff --git a/src/iteratorimpl.h b/src/iteratorimpl.h
new file mode 100644
index 0000000..0a815e2
--- /dev/null
+++ b/src/iteratorimpl.h
@@ -0,0 +1,190 @@
+/**
+ * Iterator.h
+ *
+ * Base class for iterators. Extension writers that want to create traversable
+ * classes, should override the Php::Traversable base class. This base class
+ * forces you to implement a getIterator() method that returns an instance of
+ * a Php::Iterator class.
+ *
+ * In this file you find the signature of the Php::Iterator class. It mostly has
+ * pure virtual methods, which means that you should create a derived class
+ * that implements all these methods.
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2014 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace Php {
+
+/**
+ * Class definition
+ */
+class IteratorImpl
+{
+private:
+ /**
+ * Unique pointer to the iterator that is returned by the extension
+ * @var std::unique_ptr
+ */
+ std::unique_ptr<Iterator> _iterator;
+
+ /**
+ * The current() method that is called by the Zend engine wants a
+ * pointer-to-pointer-to-a-zval. Because of this, we have to keep the
+ * current value in memory after the current() method returns because
+ * the pointer would otherwise fall out of scope. This is (once again)
+ * odd behavior of the Zend engine, but we'll have to live with that
+ * @var Value
+ */
+ Value _current;
+
+ /**
+ * The object iterator as is needed by the Zend engine
+ * @var zend_object_iterator
+ */
+ zend_object_iterator _impl;
+
+ /**
+ * Get access to all iterator functions
+ * @return zend_object_iterator_funcs
+ */
+ static zend_object_iterator_funcs *functions();
+
+ /**
+ * Is the iterator on a valid position
+ * @return bool
+ */
+ bool valid()
+ {
+ return _iterator->valid();
+ }
+
+ /**
+ * The value at the current position
+ * @return Value
+ */
+ Value current()
+ {
+ return _iterator->current();
+ }
+
+ /**
+ * The key at the current position
+ * @return Value
+ */
+ Value key()
+ {
+ return _iterator->key();
+ }
+
+ /**
+ * Move to the next position
+ */
+ void next()
+ {
+ return _iterator->next();
+ }
+
+ /**
+ * Rewind the iterator to the front position
+ */
+ void rewind()
+ {
+ return _iterator->rewind();
+ }
+
+ /**
+ * Iterator destructor method
+ * @param iter
+ * @param tsrm_ls
+ */
+ static void destructor(zend_object_iterator *iter TSRMLS_DC);
+
+ /**
+ * Iterator valid function
+ * Returns FAILURE or SUCCESS
+ * @param iter
+ * @param tsrm_ls
+ * @return int
+ */
+ static int valid(zend_object_iterator *iter TSRMLS_DC);
+
+ /**
+ * Fetch the current item
+ * @param iter
+ * @param data
+ * @param tsrm_ls
+ */
+ static void current(zend_object_iterator *iter, zval ***data TSRMLS_DC);
+
+ /**
+ * 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 data
+ * @param tsrm_ls
+ */
+ static void key(zend_object_iterator *iter, zval *data TSRMLS_DC);
+
+ /**
+ * 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
+ */
+ static int key(zend_object_iterator *iter, char **str_key, unsigned int *str_key_len, unsigned long *int_key TSRMLS_DC);
+
+ /**
+ * Step forwards to the next element
+ * @param iter
+ * @param tsrm_ls
+ */
+ static void next(zend_object_iterator *iter TSRMLS_DC);
+
+ /**
+ * Rewind the iterator back to the start
+ * @param iter
+ * @param tsrm_ls
+ */
+ static void rewind(zend_object_iterator *iter TSRMLS_DC);
+
+public:
+ /**
+ * Constructor
+ * @param iterator The iterator that is implemented by the extension
+ */
+ IteratorImpl(Iterator *iterator) : _iterator(iterator)
+ {
+ // initialize impl object
+ _impl.data = this;
+ _impl.index = 0;
+ _impl.funcs = functions();
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~IteratorImpl() {}
+
+ /**
+ * Internal method that returns the implementation object
+ * @return zend_object_iterator
+ */
+ zend_object_iterator *implementation()
+ {
+ return &_impl;
+ }
+};
+
+/**
+ * End namespace
+ */
+}
diff --git a/src/valueiteratorimpl.h b/src/valueiteratorimpl.h
index 7de2443..82c888d 100644
--- a/src/valueiteratorimpl.h
+++ b/src/valueiteratorimpl.h
@@ -3,7 +3,7 @@
*
* Interface that describes what an implementation of a value iterator should
* look like. This is an internal class that extension developers do not
- * need.
+ * need. It is used internally inside the ValueIterator class.
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2014 Copernica BV