ignorer BOM
This commit is contained in:
parent
31d67148c3
commit
6a837fbcb3
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue