diff --git a/library/Icinga/Protocol/File/Reader.php b/library/Icinga/Protocol/File/Reader.php index b2eb80c23..9168c2cca 100644 --- a/library/Icinga/Protocol/File/Reader.php +++ b/library/Icinga/Protocol/File/Reader.php @@ -185,12 +185,14 @@ class Reader implements DatasourceInterface $lines = array(); $s = ''; $f = fopen($this->filename, 'rb'); + $buffer = ''; fseek($f, 0, SEEK_END); - $pos = ftell($f); + if (ftell($f) === 0) { + return array(); + } while ($read_lines === null || count($lines) < $read_lines) { - fseek($f, --$pos); - $c = fgetc($f); - if ($c === false || $pos < 0) { + $c = $this->fgetc($f, $buffer); + if ($c === false) { $l = $this->validateLine($s, $query); if (!($l === false || $skip_lines)) { $lines[] = $l; @@ -213,6 +215,34 @@ class Reader implements DatasourceInterface return $lines; } + /** + * Backend for $this->readFromEnd + */ + public function fgetc($file, &$buffer) + { + $strlen = strlen($buffer); + if ($strlen === 0) { + $pos = ftell($file); + if ($pos === 0) { + return false; + } + if ($pos < 4096) { + fseek($file, 0); + $buffer = fread($file, $pos); + fseek($file, 0); + } else { + fseek($file, -4096, SEEK_CUR); + $buffer = fread($file, 4096); + fseek($file, -4096, SEEK_CUR); + } + return $this->fgetc($file, $buffer); + } else { + $char = substr($buffer, -1); + $buffer = substr($buffer, 0, $strlen - 1); + return $char; + } + } + /** * Backend for $this->read * Direction: FIFO @@ -223,16 +253,20 @@ class Reader implements DatasourceInterface $lines = array(); $s = ''; $f = fopen($this->filename, 'rb'); + $buffer = ''; while ($read_lines === null || count($lines) < $read_lines) { - $c = fgetc($f); - if ($c === false) { - $l = $this->validateLine($s, $query); - if (!($l === false || $skip_lines)) { - $lines[] = $l; + if (strlen($buffer) === 0) { + $buffer = fread($f, 4096); + if (strlen($buffer) === 0) { + $l = $this->validateLine($s, $query); + if (!($l === false || $skip_lines)) { + $lines[] = $l; + } + break; } - break; } - $s .= $c; + $s .= substr($buffer, 0, 1); + $buffer = substr($buffer, 1); if (strpos($s, PHP_EOL) !== false) { $l = $this->validateLine((string)substr($s, 0, strlen($s) - $PHP_EOL_len), $query); if ($l !== false) { @@ -260,20 +294,21 @@ class Reader implements DatasourceInterface $lines = 0; $s = ''; $f = fopen($this->filename, 'rb'); - fseek($f, 0, SEEK_END); - $pos = ftell($f); + $buffer = ''; while (true) { - fseek($f, --$pos); - $c = fgetc($f); - if ($c === false || $pos < 0) { - if ($this->validateLine($s, $query) !== false) { - $lines++; + if (strlen($buffer) === 0) { + $buffer = fread($f, 4096); + if (strlen($buffer) === 0) { + if ($this->validateLine($s, $query) !== false) { + $lines++; + } + break; } - break; } - $s = $c . $s; - if (strpos($s, PHP_EOL) === 0) { - if ($this->validateLine((string)substr($s, $PHP_EOL_len), $query) !== false) { + $s .= substr($buffer, 0, 1); + $buffer = substr($buffer, 1); + if (strpos($s, PHP_EOL) !== false) { + if ($this->validateLine((string)substr($s, 0, strlen($s) - $PHP_EOL_len), $query) !== false) { $lines++; } $s = ''; @@ -281,4 +316,4 @@ class Reader implements DatasourceInterface } return $lines; } -} \ No newline at end of file +}