ignorer BOM

This commit is contained in:
Jephté Clain 2024-04-23 04:54:18 +04:00
parent 31d67148c3
commit 6a837fbcb3
3 changed files with 40 additions and 7 deletions

View File

@ -7,9 +7,17 @@ use nur\sery\os\IOException;
* Class FileReader: un fichier accédé en lecture
*/
class FileReader extends _File {
/** @var bool *à l'ouverture du fichier*, faut-il ignorer le BOM? */
const IGNORE_BOM = true;
const DEFAULT_MODE = "rb";
function __construct($input, ?string $mode=null, bool $throwOnError=true, ?bool $allowLocking=null) {
/** @var bool */
protected $ignoreBom;
function __construct($input, ?string $mode=null, bool $throwOnError=true, ?bool $allowLocking=null, ?bool $ignoreBom=null) {
if ($ignoreBom === null) $ignoreBom = static::IGNORE_BOM;
$this->ignoreBom = $ignoreBom;
if ($input === null) {
$fd = STDIN;
$close = false;
@ -26,4 +34,20 @@ class FileReader extends _File {
}
parent::__construct($fd, $close, $throwOnError, $allowLocking);
}
/** @return resource */
protected function open() {
$fd = parent::open();
$this->haveBom = false;
if ($this->ignoreBom) {
$bom = fread($fd, 3);
if ($bom === "\xEF\xBB\xBF") $this->seekOffset = 3;
else rewind($fd);
}
return $fd;
}
function haveBom(): bool {
return $this->seekOffset !== 0;
}
}

View File

@ -29,6 +29,9 @@ class Stream extends AbstractIterator implements IReader, IWriter {
/** @var bool */
protected $useLocking;
/** @var int nombre d'octets à ignorer au début du fichier lors d'un seek */
protected $seekOffset = 0;
/** @var int|null */
protected $serial;
@ -84,24 +87,28 @@ class Stream extends AbstractIterator implements IReader, IWriter {
return $this->stat;
}
function getSize(): int {
return $this->fstat()["size"];
function getSize(?int $seekOffset=null): int {
if ($seekOffset === null) $seekOffset = $this->seekOffset;
return $this->fstat()["size"] - $seekOffset;
}
/** @throws IOException */
function ftell(): int {
function ftell(?int $seekOffset=null): int {
$fd = $this->getResource();
return IOException::ensure_valid(ftell($fd), $this->throwOnError);
if ($seekOffset === null) $seekOffset = $this->seekOffset;
return IOException::ensure_valid(ftell($fd), $this->throwOnError) - $seekOffset;
}
/**
* @return int la position après avoir déplacé le pointeur
* @throws IOException
*/
function fseek(int $offset, int $whence=SEEK_SET): int {
function fseek(int $offset, int $whence=SEEK_SET, ?int $seekOffset=null): int {
$fd = $this->getResource();
if ($seekOffset === null) $seekOffset = $this->seekOffset;
if ($whence === SEEK_SET) $offset += $seekOffset;
IOException::ensure_valid(fseek($fd, $offset, $whence), $this->throwOnError, -1);
return $this->ftell();
return $this->ftell($seekOffset);
}
function seek(int $offset, int $whence=SEEK_SET): self {

View File

@ -15,10 +15,12 @@ abstract class _File extends Stream {
/** @var string */
protected $mode;
/** @return resource */
protected function open() {
return IOException::ensure_valid(@fopen($this->file, $this->mode));
}
/** @return resource */
function getResource() {
if ($this->fd === null && $this->file !== null) $this->fd = $this->open();
return parent::getResource();