]> git.mxchange.org Git - friendica.git/blobdiff - src/Util/ReversedFileReader.php
Merge pull request #11519 from MrPetovan/task/11511-console-domain-move
[friendica.git] / src / Util / ReversedFileReader.php
index 8a3083f7d8d14a31489d3cd2263d65af3a29cbce..0566002de29e899e75034972d51f2fa4ad023be1 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * @copyright Copyright (C) 2021, Friendica
+ * @copyright Copyright (C) 2010-2022, the Friendica project
  *
  * @license GNU AGPL version 3 or any later version
  *
@@ -21,7 +21,6 @@
 
 namespace Friendica\Util;
 
-
 /**
  * An iterator which returns lines from file in reversed order
  *
@@ -29,73 +28,142 @@ namespace Friendica\Util;
  */
 class ReversedFileReader implements \Iterator
 {
-    const BUFFER_SIZE = 4096;
-    const SEPARATOR = "\n";
+       const BUFFER_SIZE = 4096;
+       const SEPARATOR   = "\n";
+
+       /** @var resource */
+       private $fh = null;
+
+       /** @var int */
+       private $filesize = -1;
+
+       /** @var int */
+       private $pos = -1;
+
+       /** @var array */
+       private $buffer = null;
+
+       /** @var int */
+       private $key = -1;
 
-    public function __construct($filename)
-    {
-        $this->_fh = fopen($filename, 'r');
-               if (!$this->_fh) {
+       /** @var string */
+       private $value = null;
+
+       /**
+        * 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 should use a custom exception.
                        throw \Exception("Unable to open $filename");
                }
-        $this->_filesize = filesize($filename);
-        $this->_pos = -1;
-        $this->_buffer = null;
-        $this->_key = -1;
-        $this->_value = null;
-    }
-
-    public function _read($size)
-    {
-        $this->_pos -= $size;
-        fseek($this->_fh, $this->_pos);
-        return fread($this->_fh, $size);
-    }
-
-    public function _readline()
-    {
-        $buffer =& $this->_buffer;
-        while (true) {
-            if ($this->_pos == 0) {
-                return array_pop($buffer);
-            }
-            if (count($buffer) > 1) {
-                return array_pop($buffer);
-            }
-            $buffer = explode(self::SEPARATOR, $this->_read(self::BUFFER_SIZE) . $buffer[0]);
-        }
-    }
-
-    public function next()
-    {
-        ++$this->_key;
-        $this->_value = $this->_readline();
-    }
-
-    public function rewind()
-    {
-        if ($this->_filesize > 0) {
-            $this->_pos = $this->_filesize;
-            $this->_value = null;
-            $this->_key = -1;
-            $this->_buffer = explode(self::SEPARATOR, $this->_read($this->_filesize % self::BUFFER_SIZE ?: self::BUFFER_SIZE));
-            $this->next();
-        }
-    }
-
-    public function key()
+               $this->filesize = filesize($filename);
+               $this->pos      = -1;
+               $this->buffer   = null;
+               $this->key      = -1;
+               $this->value    = null;
+               return $this;
+       }
+
+       /**
+        * 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);
+       }
+
+       /**
+        * 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);
+                       }
+                       $buffer = explode(self::SEPARATOR, $this->_read(self::BUFFER_SIZE) . $buffer[0]);
+               }
+       }
+
+       /**
+        * 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) {
+                       $this->pos    = $this->filesize;
+                       $this->value  = null;
+                       $this->key    = -1;
+                       $this->buffer = explode(self::SEPARATOR, $this->_read($this->filesize % self::BUFFER_SIZE ?: self::BUFFER_SIZE));
+                       $this->next();
+               }
+       }
+
+       /**
+        * Return current line number, starting from zero at the end of file
+        *
+        * @see Iterator::key()
+        * @return int
+        */
+       public function key()
        {
-               return $this->_key;
+               return $this->key;
        }
 
-    public function current()
+       /**
+        * Return current line
+        *
+        * @see Iterator::current()
+        * @return string
+        */
+       public function current()
        {
-               return $this->_value;
+               return $this->value;
        }
 
-    public function valid()
+       /**
+        * 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);
+               return ! is_null($this->value);
        }
 }