nur-sery/nur_src/b/io/StringReader.php

120 lines
3.1 KiB
PHP
Raw Normal View History

2023-12-03 22:10:18 +04:00
<?php
namespace nur\b\io;
use nur\b\coll\AbstractIterator;
use nur\str;
class StringReader extends AbstractIterator implements IReader {
use Treader;
static final function next_line(string $string, int $index, ?int $length=null): ?array {
if ($length === null) $length = strlen($string);
$poscr = strpos($string, "\r", $index);
$poslf = strpos($string, "\n", $index);
if ($poscr !== false && $poslf !== false) {
$pos = min($poscr, $poslf);
} elseif ($poscr !== false) {
$pos = $poscr;
} elseif ($poslf !== false) {
$pos = $poslf;
} else {
$pos = false;
}
# ligne se terminant par CR[LF]
if ($pos !== false && $pos === $poscr) {
$pos++;
if ($pos < $length && $string[$pos] == "\n") $pos++;
$line = substr($string, $index, $pos - $index);
return [str::strip_nl($line), $pos];
}
# ligne se terminant par LF
if ($pos !== false && $pos === $poslf) {
$pos++;
$line = substr($string, $index, $pos - $index);
return [str::strip_nl($line), $pos];
}
# ligne sans caractère de fin
return [substr($string, $index), $length];
}
function __construct(?string $string=null, int $index=0) {
$this->setString($string, $index);
}
/** @var string la chaine à lire */
private $string;
/** @var int longueur de la chaine */
private $length;
/** @var int position de lecture dans la chaine */
private $index;
private static function fix_index(int $index, int $length): int {
if ($index < 0) {
if ($length > 0) {
while ($index < 0) $index += $length;
} else {
$index = 0;
}
}
if ($index > $length) $index = $length;
return $index;
}
function setString(?string $string, int $index=0) {
if ($string === null) $string = "";
$length = strlen($string);
$index = self::fix_index($index, $length);
$this->string = $string;
$this->index = $index;
$this->length = $length;
}
function close(bool $close=true): void {
}
function getResource() {
return null;
}
function appendFilter(string $filterName, ?int $readWrite=null, $params=null): void {
}
function prependFilter(string $filterName, ?int $readWrite=null, $params=null): void {
}
function setEncodingFilter(string $from, string $to = "utf-8"): void {
}
function seek(int $index=0, int $whence=SEEK_SET): int {
if ($whence == SEEK_CUR) {
$index = $this->index + $index;
} elseif ($whence == SEEK_END) {
$index = $this->length - $index;
}
return $this->index = self::fix_index($index, $this->length);
}
function readLine(): string {
$index = $this->index;
$length = $this->length;
if ($index == $length) throw EOFException::no_more_data();
[$line, $this->index] = self::next_line($this->string, $index, $length);
return $line;
}
protected function _next(&$key) {
return $this->readLine();
}
function key() { return $this->_key(); }
function current() { return $this->_current(); }
function getContents(bool $close=true): string {
$contents = substr($this->string, $this->index);
$this->index = $this->length;
return $contents;
}
}