d249b8a1d97d883df2a6a476062c9a12e168d84e
[platal.git] / classes / plarrayiterator.php
1 <?php
2 /***************************************************************************
3 * Copyright (C) 2003-2008 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
21
22 class PlArrayIterator implements PlIterator
23 {
24 private $array;
25 private $depth;
26
27 private $_its = array();
28
29 private $_total;
30 private $_first;
31 private $_last;
32 private $_pos;
33
34 public function __construct(array &$array, $depth = 1)
35 {
36 $this->array =& $array;
37 $this->depth = $depth;
38 $this->_total = $this->count($array, $depth - 1);
39 $this->_pos = 0;
40 $this->_first = false;
41 $this->_last = false;
42
43 for ($i = 0 ; $i < $depth ; ++$i) {
44 if ($i == 0) {
45 $this->_its[] = $array;
46 } else {
47 $this->_its[] = current($this->_its[$i - 1]);
48 }
49 reset($this->_its[$i]);
50 }
51 }
52
53 private function count(array &$array, $depth)
54 {
55 if ($depth == 0) {
56 return count($array);
57 } else {
58 $sum = 0;
59 foreach ($array as &$item) {
60 $sum += $this->count($item, $depth - 1);
61 }
62 return $sum;
63 }
64 }
65
66 private function nextArray($depth)
67 {
68 if ($depth == 0) {
69 return;
70 }
71 $this->_its[$depth] = next($this->_its[$depth - 1]);
72 if ($this->_its[$depth] === false) {
73 $this->nextArray($depth - 1);
74 if ($this->_its[$depth - 1] === false) {
75 return;
76 }
77 $this->_its[$depth] = current($this->_its[$depth - 1]);
78 }
79 reset($this->_its[$depth]);
80 }
81
82 public function next()
83 {
84 ++$this->_pos;
85 $this->_first = ($this->_total > 0 && $this->_pos == 1);
86 $this->_last = ($this->_pos == $this->_total);
87 if ($this->_pos > $this->_total) {
88 return null;
89 }
90
91 $val = current($this->_its[$this->depth - 1]);
92 if ($val === false) {
93 $this->nextArray($this->depth - 1);
94 $val = current($this->_its[$this->depth - 1]);
95 if ($val === false) {
96 return null;
97 }
98 }
99 $keys = array();
100 for ($i = 0 ; $i < $this->depth ; ++$i) {
101 $keys[] = key($this->_its[$i]);
102 }
103 next($this->_its[$this->depth - 1]);
104 return array('keys' => $keys,
105 'value' => $val);
106 }
107
108 public function total()
109 {
110 return $this->_total;
111 }
112
113 public function first()
114 {
115 return $this->_first;
116 }
117
118 public function last()
119 {
120 return $this->_last;
121 }
122 }
123
124 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
125 ?>