]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/libs/ExplodeIterator.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / libs / ExplodeIterator.php
1 <?php
2 /**
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16  * http://www.gnu.org/copyleft/gpl.html
17  *
18  * @file
19  */
20
21 /**
22  * An iterator which works exactly like:
23  *
24  * foreach ( explode( $delim, $s ) as $element ) {
25  *    ...
26  * }
27  *
28  * Except it doesn't use 193 byte per element
29  */
30 class ExplodeIterator implements Iterator {
31         // The subject string
32         private $subject, $subjectLength;
33
34         // The delimiter
35         private $delim, $delimLength;
36
37         // The position of the start of the line
38         private $curPos;
39
40         // The position after the end of the next delimiter
41         private $endPos;
42
43         /** @var string|false The current token */
44         private $current;
45
46         /**
47          * Construct a DelimIterator
48          * @param string $delim
49          * @param string $subject
50          */
51         public function __construct( $delim, $subject ) {
52                 $this->subject = $subject;
53                 $this->delim = $delim;
54
55                 // Micro-optimisation (theoretical)
56                 $this->subjectLength = strlen( $subject );
57                 $this->delimLength = strlen( $delim );
58
59                 $this->rewind();
60         }
61
62         public function rewind() {
63                 $this->curPos = 0;
64                 $this->endPos = strpos( $this->subject, $this->delim );
65                 $this->refreshCurrent();
66         }
67
68         public function refreshCurrent() {
69                 if ( $this->curPos === false ) {
70                         $this->current = false;
71                 } elseif ( $this->curPos >= $this->subjectLength ) {
72                         $this->current = '';
73                 } elseif ( $this->endPos === false ) {
74                         $this->current = substr( $this->subject, $this->curPos );
75                 } else {
76                         $this->current = substr( $this->subject, $this->curPos, $this->endPos - $this->curPos );
77                 }
78         }
79
80         public function current() {
81                 return $this->current;
82         }
83
84         /**
85          * @return int|bool Current position or boolean false if invalid
86          */
87         public function key() {
88                 return $this->curPos;
89         }
90
91         /**
92          * @return string
93          */
94         public function next() {
95                 if ( $this->endPos === false ) {
96                         $this->curPos = false;
97                 } else {
98                         $this->curPos = $this->endPos + $this->delimLength;
99                         if ( $this->curPos >= $this->subjectLength ) {
100                                 $this->endPos = false;
101                         } else {
102                                 $this->endPos = strpos( $this->subject, $this->delim, $this->curPos );
103                         }
104                 }
105                 $this->refreshCurrent();
106
107                 return $this->current;
108         }
109
110         /**
111          * @return bool
112          */
113         public function valid() {
114                 return $this->curPos !== false;
115         }
116 }