3 * @copyright Copyright (C) 2021, Friendica
5 * @license GNU AGPL version 3 or any later version
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 namespace Friendica\Util;
26 * An iterator which returns lines from file in reversed order
28 * original code https://stackoverflow.com/a/10494801
30 class ReversedFileReader implements \Iterator
32 const BUFFER_SIZE = 4096;
33 const SEPARATOR = "\n";
35 public function __construct($filename)
37 $this->_fh = fopen($filename, 'r');
39 // this should use a custom exception.
40 throw \Exception("Unable to open $filename");
42 $this->_filesize = filesize($filename);
44 $this->_buffer = null;
49 public function _read($size)
52 fseek($this->_fh, $this->_pos);
53 return fread($this->_fh, $size);
56 public function _readline()
58 $buffer =& $this->_buffer;
60 if ($this->_pos == 0) {
61 return array_pop($buffer);
63 if (count($buffer) > 1) {
64 return array_pop($buffer);
66 $buffer = explode(self::SEPARATOR, $this->_read(self::BUFFER_SIZE) . $buffer[0]);
70 public function next()
73 $this->_value = $this->_readline();
76 public function rewind()
78 if ($this->_filesize > 0) {
79 $this->_pos = $this->_filesize;
82 $this->_buffer = explode(self::SEPARATOR, $this->_read($this->_filesize % self::BUFFER_SIZE ?: self::BUFFER_SIZE));
92 public function current()
97 public function valid()
99 return ! is_null($this->_value);