120 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?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;
 | 
						|
  }
 | 
						|
}
 |