diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-04-05 19:30:13 +0200 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-04-05 19:30:13 +0200 |
commit | 479e9979a69b9fdb995525576d4588cd92239ed5 (patch) | |
tree | e55dcfc2aca533be034cbc84472056ebce272536 | |
parent | f407d6d4c5ea35f73c5aec72f8b492c259dc7dfe (diff) |
removed zend code from the iterator header file, and moved it into the src directory
-rw-r--r-- | include/iterator.h | 88 | ||||
-rw-r--r-- | include/value.h | 2 | ||||
-rw-r--r-- | src/classimpl.cpp | 2 | ||||
-rw-r--r-- | src/includes.h | 1 | ||||
-rw-r--r-- | src/iteratorimpl.cpp (renamed from src/iterator.cpp) | 97 | ||||
-rw-r--r-- | src/iteratorimpl.h | 190 | ||||
-rw-r--r-- | src/valueiteratorimpl.h | 2 |
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 |