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