<?php
namespace nur\b\io;

/**
 * Class FileWriter: écriture dans un flux
 */
class StreamWriter implements IWriter {
  use Twriter, Tfilter;

  /** @var resource */
  protected $fd;

  /** @var bool */
  protected $close;

  /** @throws IOException */
  function __construct($fd, ?bool $close=null) {
    if ($close === null) $close = $fd !== null;
    if ($fd === null) $fd = STDOUT;
    $this->fd = $fd;
    $this->close = $close;
  }

  function setEncodingFilter(string $to, string $from="utf-8"): void {
    $this->_setEncodingFilter($from, $to);
  }

  /**
   * @throws IOException
   * @return resource
   */
  protected final function open() {
    IOException::ensure_open($this->fd === null);
    $this->_streamAppendFilters($this->fd);
    return $this->fd;
  }

  /** @throws IOException */
  function getResource() {
    return $this->open();
  }

  /** @throws IOException */
  function seek(int $offset=0, int $whence=SEEK_SET): int {
    return fseek($this->open(), $offset, $whence);
  }

  /** @throws IOException */
  function _write(string $value): void {
    IOException::ensure_not_false(fwrite($this->open(), $value), "write");
  }

  function putContents(string $contents): void {
    try {
      $this->_write($contents);
    } finally {
      $this->close();
    }
  }

  function serialize($object): void {
    $this->putContents(serialize($object));
  }

  function close(bool $close=true): void {
    if ($this->fd !== null && $this->close && $close) {
      fclose($this->fd);
      $this->fd = null;
    }
  }
}
