]> git.mxchange.org Git - friendica.git/blobdiff - src/Util/ReversedFileReader.php
Handle reading empty file in ReversedFileReader
[friendica.git] / src / Util / ReversedFileReader.php
index c889b5f93d6bab033e533ba23f43cab69da6bb29..92c8cced184e1db5c8b602815ed3a4a9373af302 100644 (file)
@@ -31,25 +31,34 @@ class ReversedFileReader implements \Iterator
        const BUFFER_SIZE = 4096;
        const SEPARATOR   = "\n";
 
+       /** @var resource */
+       private $fh = null;
+
        /** @var int */
-       private $filesize;
+       private $filesize = -1;
 
        /** @var int */
-       private $pos;
+       private $pos = -1;
 
        /** @var array */
-       private $buffer;
+       private $buffer = null;
 
        /** @var int */
-       private $key;
+       private $key = -1;
 
        /** @var string */
-       private $value;
+       private $value = null;
 
-       public function __construct($filename)
+       /**
+        * Open $filename for read and reset iterator
+        *
+        * @param string $filename      File to open
+        * @return $this
+        */
+       public function open(string $filename)
        {
-               $this->_fh = fopen($filename, 'r');
-               if (!$this->_fh) {
+               $this->fh = fopen($filename, 'r');
+               if (!$this->fh) {
                        // this should use a custom exception.
                        throw \Exception("Unable to open $filename");
                }
@@ -58,22 +67,37 @@ class ReversedFileReader implements \Iterator
                $this->buffer   = null;
                $this->key      = -1;
                $this->value    = null;
+               return $this;
        }
 
-       public function _read($size)
+       /**
+        * Read $size bytes behind last position
+        *
+        * @return string
+        */
+       private function _read($size)
        {
                $this->pos -= $size;
-               fseek($this->_fh, $this->pos);
-               return fread($this->_fh, $size);
+               fseek($this->fh, $this->pos);
+               return fread($this->fh, $size);
        }
 
-       public function _readline()
+       /**
+        * Read next line from end of file
+        * Return null if no lines are left to read
+        *
+        * @return ?string
+        */
+       private function _readline()
        {
                $buffer = & $this->buffer;
                while (true) {
                        if ($this->pos == 0) {
                                return array_pop($buffer);
                        }
+                       if (is_null($buffer)) {
+                               return null;
+                       }
                        if (count($buffer) > 1) {
                                return array_pop($buffer);
                        }
@@ -81,12 +105,24 @@ class ReversedFileReader implements \Iterator
                }
        }
 
+       /**
+        * Fetch next line from end and set it as current iterator value.
+        *
+        * @see Iterator::next()
+        * @return void
+        */
        public function next()
        {
                ++$this->key;
                $this->value = $this->_readline();
        }
 
+       /**
+        * Rewind iterator to the first line at the end of file
+        *
+        * @see Iterator::rewind()
+        * @return void
+        */
        public function rewind()
        {
                if ($this->filesize > 0) {
@@ -98,16 +134,34 @@ class ReversedFileReader implements \Iterator
                }
        }
 
+       /**
+        * Return current line number, starting from zero at the end of file
+        *
+        * @see Iterator::key()
+        * @return int
+        */
        public function key()
        {
                return $this->key;
        }
 
+       /**
+        * Return current line
+        *
+        * @see Iterator::current()
+        * @return string
+        */
        public function current()
        {
                return $this->value;
        }
 
+       /**
+        * Checks if current iterator value is valid, that is, we readed all lines in files
+        *
+        * @see Iterator::valid()
+        * @return bool
+        */
        public function valid()
        {
                return ! is_null($this->value);