summaryrefslogtreecommitdiff
path: root/ext/spl/internal/cachingiterator.inc
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-03-14 05:42:27 +0000
committer <>2013-04-03 16:25:08 +0000
commitc4dd7a1a684490673e25aaf4fabec5df138854c4 (patch)
tree4d57c44caae4480efff02b90b9be86f44bf25409 /ext/spl/internal/cachingiterator.inc
downloadphp2-master.tar.gz
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'ext/spl/internal/cachingiterator.inc')
-rw-r--r--ext/spl/internal/cachingiterator.inc157
1 files changed, 157 insertions, 0 deletions
diff --git a/ext/spl/internal/cachingiterator.inc b/ext/spl/internal/cachingiterator.inc
new file mode 100644
index 0000000..33258ab
--- /dev/null
+++ b/ext/spl/internal/cachingiterator.inc
@@ -0,0 +1,157 @@
+<?php
+
+/** @file cachingiterator.inc
+ * @ingroup SPL
+ * @brief class CachingIterator
+ * @author Marcus Boerger
+ * @date 2003 - 2009
+ *
+ * SPL - Standard PHP Library
+ */
+
+/**
+ * @brief Cached iteration over another Iterator
+ * @author Marcus Boerger
+ * @version 1.2
+ * @since PHP 5.0
+ *
+ * This iterator wrapper does a one ahead iteration. This way it knows whether
+ * the inner iterator has one more element.
+ *
+ * @note If you want to convert the elements into strings and the inner
+ * Iterator is an internal Iterator then you need to provide the
+ * flag CALL_TOSTRING to do the conversion when the actual element
+ * is being fetched. Otherwise the conversion would happen with the
+ * already changed iterator. If you do not need this then it you should
+ * omit this flag because it costs unneccessary work and time.
+ */
+class CachingIterator implements OuterIterator
+{
+ const CALL_TOSTRING = 0x00000001;
+ const CATCH_GET_CHILD = 0x00000002;
+ const TOSTRING_USE_KEY = 0x00000010;
+ const TOSTRING_USE_CURRENT = 0x00000020;
+
+ private $it;
+ private $current;
+ private $key;
+ private $valid;
+ private $strValue;
+
+ /** Construct from another iterator
+ *
+ * @param it Iterator to cache
+ * @param flags Bitmask:
+ * - CALL_TOSTRING (whether to call __toString() for every element)
+ */
+ function __construct(Iterator $it, $flags = self::CALL_TOSTRING)
+ {
+ if ((($flags & self::CALL_TOSTRING) && ($flags & (self::TOSTRING_USE_KEY|self::TOSTRING_USE_CURRENT)))
+ || ((flags & (self::CIT_TOSTRING_USE_KEY|self::CIT_TOSTRING_USE_CURRENT)) == (self::CIT_TOSTRING_USE_KEY|self::CIT_TOSTRING_USE_CURRENT)))
+ {
+ throw new InvalidArgumentException('Flags must contain only one of CIT_CALL_TOSTRING, CIT_TOSTRING_USE_KEY, CIT_TOSTRING_USE_CURRENT');
+ }
+ $this->it = $it;
+ $this->flags = $flags & (0x0000FFFF);
+ $this->next();
+ }
+
+ /** Rewind the Iterator
+ */
+ function rewind()
+ {
+ $this->it->rewind();
+ $this->next();
+ }
+
+ /** Forward to the next element
+ */
+ function next()
+ {
+ if ($this->valid = $this->it->valid()) {
+ $this->current = $this->it->current();
+ $this->key = $this->it->key();
+ if ($this->flags & self::CALL_TOSTRING) {
+ if (is_object($this->current)) {
+ $this->strValue = $this->current->__toString();
+ } else {
+ $this->strValue = (string)$this->current;
+ }
+ }
+ } else {
+ $this->current = NULL;
+ $this->key = NULL;
+ $this->strValue = NULL;
+ }
+ $this->it->next();
+ }
+
+ /** @return whether the iterator is valid
+ */
+ function valid()
+ {
+ return $this->valid;
+ }
+
+ /** @return whether there is one more element
+ */
+ function hasNext()
+ {
+ return $this->it->valid();
+ }
+
+ /** @return the current element
+ */
+ function current()
+ {
+ return $this->current;
+ }
+
+ /** @return the current key
+ */
+ function key()
+ {
+ return $this->key;
+ }
+
+ /** Aggregate the inner iterator
+ *
+ * @param func Name of method to invoke
+ * @param params Array of parameters to pass to method
+ */
+ function __call($func, $params)
+ {
+ return call_user_func_array(array($this->it, $func), $params);
+ }
+
+ /** @return the string represenatation that was generated for the current
+ * element
+ * @throw exception when CALL_TOSTRING was not specified in constructor
+ */
+ function __toString()
+ {
+ if ($this->flags & self::TOSTRING_USE_KEY)
+ {
+ return $this->key;
+ }
+ else if ($this->flags & self::TOSTRING_USE_CURRENT)
+ {
+ return $this->current;
+ }
+ if (!$this->flags & self::CALL_TOSTRING)
+ {
+ throw new exception('CachingIterator does not fetch string value (see CachingIterator::__construct)');
+ }
+ return $this->strValue;
+ }
+
+ /**
+ * @return The inner iterator
+ */
+ function getInnerIterator()
+ {
+ return $this->it;
+ }
+}
+
+?>