<?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; } }