Annotation of embedaddon/php/ext/spl/internal/recursiveiteratoriterator.inc, revision 1.1
1.1 ! misho 1: <?php
! 2:
! 3: /** @file recursiveiteratoriterator.inc
! 4: * @ingroup SPL
! 5: * @brief class RecursiveIteratorIterator
! 6: * @author Marcus Boerger
! 7: * @date 2003 - 2009
! 8: *
! 9: * SPL - Standard PHP Library
! 10: */
! 11:
! 12: /**
! 13: * @brief Iterates through recursive iterators
! 14: * @author Marcus Boerger
! 15: * @version 1.2
! 16: * @since PHP 5.0
! 17: *
! 18: * The objects of this class are created by instances of RecursiveIterator.
! 19: * Elements of those iterators may be traversable themselves. If so these
! 20: * sub elements are recursed into.
! 21: */
! 22: class RecursiveIteratorIterator implements OuterIterator
! 23: {
! 24: /** Mode: Only show leaves */
! 25: const LEAVES_ONLY = 0;
! 26: /** Mode: Show parents prior to their children */
! 27: const SELF_FIRST = 1;
! 28: /** Mode: Show all children prior to their parent */
! 29: const CHILD_FIRST = 2;
! 30:
! 31: /** Flag: Catches exceptions during getChildren() calls and simply jumps
! 32: * to the next element. */
! 33: const CATCH_GET_CHILD = 0x00000002;
! 34:
! 35: private $ait = array();
! 36: private $count = 0;
! 37: private $mode = self::LEAVES_ONLY;
! 38: private $flags = 0;
! 39:
! 40: /** Construct from RecursiveIterator
! 41: *
! 42: * @param it RecursiveIterator to iterate
! 43: * @param mode Operation mode (one of):
! 44: * - LEAVES_ONLY only show leaves
! 45: * - SELF_FIRST show parents prior to their childs
! 46: * - CHILD_FIRST show all children prior to their parent
! 47: * @param flags Control flags, zero or any combination of the following
! 48: * (since PHP 5.1).
! 49: * - CATCH_GET_CHILD which catches exceptions during
! 50: * getChildren() calls and simply jumps to the next
! 51: * element.
! 52: */
! 53: function __construct(RecursiveIterator $it, $mode = self::LEAVES_ONLY, $flags = 0)
! 54: {
! 55: $this->ait[0] = $it;
! 56: $this->mode = $mode;
! 57: $this->flags = $flags;
! 58: }
! 59:
! 60: /** Rewind to top iterator as set in constructor
! 61: */
! 62: function rewind()
! 63: {
! 64: while ($this->count) {
! 65: unset($this->ait[$this->count--]);
! 66: $this->endChildren();
! 67: }
! 68: $this->ait[0]->rewind();
! 69: $this->ait[0]->recursed = false;
! 70: callNextElement(true);
! 71: }
! 72:
! 73: /** @return whether iterator is valid
! 74: */
! 75: function valid()
! 76: {
! 77: $count = $this->count;
! 78: while ($count) {
! 79: $it = $this->ait[$count];
! 80: if ($it->valid()) {
! 81: return true;
! 82: }
! 83: $count--;
! 84: $this->endChildren();
! 85: }
! 86: return false;
! 87: }
! 88:
! 89: /** @return current key
! 90: */
! 91: function key()
! 92: {
! 93: $it = $this->ait[$this->count];
! 94: return $it->key();
! 95: }
! 96:
! 97: /** @return current element
! 98: */
! 99: function current()
! 100: {
! 101: $it = $this->ait[$this->count];
! 102: return $it->current();
! 103: }
! 104:
! 105: /** Forward to next element
! 106: */
! 107: function next()
! 108: {
! 109: while ($this->count) {
! 110: $it = $this->ait[$this->count];
! 111: if ($it->valid()) {
! 112: if (!$it->recursed && callHasChildren()) {
! 113: $it->recursed = true;
! 114: try
! 115: {
! 116: $sub = callGetChildren();
! 117: }
! 118: catch (Exception $e)
! 119: {
! 120: if (!($this->flags & self::CATCH_GET_CHILD))
! 121: {
! 122: throw $e;
! 123: }
! 124: $it->next();
! 125: continue;
! 126: }
! 127: $sub->recursed = false;
! 128: $sub->rewind();
! 129: if ($sub->valid()) {
! 130: $this->ait[++$this->count] = $sub;
! 131: if (!$sub instanceof RecursiveIterator) {
! 132: throw new Exception(get_class($sub).'::getChildren() must return an object that implements RecursiveIterator');
! 133: }
! 134: $this->beginChildren();
! 135: return;
! 136: }
! 137: unset($sub);
! 138: }
! 139: $it->next();
! 140: $it->recursed = false;
! 141: if ($it->valid()) {
! 142: return;
! 143: }
! 144: $it->recursed = false;
! 145: }
! 146: if ($this->count) {
! 147: unset($this->ait[$this->count--]);
! 148: $it = $this->ait[$this->count];
! 149: $this->endChildren();
! 150: callNextElement(false);
! 151: }
! 152: }
! 153: callNextElement(true);
! 154: }
! 155:
! 156: /** @return Sub Iterator at given level or if unspecified the current sub
! 157: * Iterator
! 158: */
! 159: function getSubIterator($level = NULL)
! 160: {
! 161: if (is_null($level)) {
! 162: $level = $this->count;
! 163: }
! 164: return @$this->ait[$level];
! 165: }
! 166:
! 167: /**
! 168: * @return The inner iterator
! 169: */
! 170: function getInnerIterator()
! 171: {
! 172: return $this->it;
! 173: }
! 174:
! 175: /** @return Current Depth (Number of parents)
! 176: */
! 177: function getDepth()
! 178: {
! 179: return $this->level;
! 180: }
! 181:
! 182: /** @return whether current sub iterators current element has children
! 183: * @since PHP 5.1
! 184: */
! 185: function callHasChildren()
! 186: {
! 187: return $this->ait[$this->count]->hasChildren();
! 188: }
! 189:
! 190: /** @return current sub iterators current children
! 191: * @since PHP 5.1
! 192: */
! 193: function callGetChildren()
! 194: {
! 195: return $this->ait[$this->count]->getChildren();
! 196: }
! 197:
! 198: /** Called right after calling getChildren() and its rewind().
! 199: * @since PHP 5.1
! 200: */
! 201: function beginChildren()
! 202: {
! 203: }
! 204:
! 205: /** Called after current child iterator is invalid and right before it
! 206: * gets destructed.
! 207: * @since PHP 5.1
! 208: */
! 209: function endChildren()
! 210: {
! 211: }
! 212:
! 213: private function callNextElement($after_move)
! 214: {
! 215: if ($this->valid())
! 216: {
! 217: if ($after_move)
! 218: {
! 219: if (($this->mode == self::SELF_FIRST && $this->callHasChildren())
! 220: || $this->mode == self::LEAVES_ONLY)
! 221: $this->nextElement();
! 222: }
! 223: else
! 224: {
! 225: $this->nextElement();
! 226: }
! 227: }
! 228: }
! 229:
! 230: /** Called when the next element is available
! 231: */
! 232: function nextElement()
! 233: {
! 234: }
! 235: }
! 236:
! 237: ?>
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>