Your IP : 3.15.214.230


Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/main/lib/web/http/
Upload File :
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/main/lib/web/http/stream.php

<?php

namespace Bitrix\Main\Web\Http;

use Psr\Http\Message\StreamInterface;
use Bitrix\Main\ArgumentException;

class Stream implements StreamInterface
{
	/**
	 * @var resource
	 */
	protected $resource;

	/**
	 * @param string | resource | Stream $stream
	 * @param string $mode
	 * @throws ArgumentException
	 */
	public function __construct($stream, $mode = 'r')
	{
		if (is_resource($stream))
		{
			$this->resource = $stream;
		}
		elseif ($stream instanceof Stream)
		{
			$this->resource = $stream->resource;
		}
		elseif (is_string($stream))
		{
			$this->resource = fopen($stream, $mode);
		}
		else
		{
			throw new ArgumentException('Stream must be a Stream object, a string identifier, or a resource.', 'stream');
		}
	}

	/**
	 * @inheritdoc
	 */
	public function __toString(): string
	{
		if (!$this->isReadable())
		{
			return '';
		}

		try
		{
			$this->rewind();
			return $this->getContents();
		}
		catch (\RuntimeException)
		{
			return '';
		}
	}

	/**
	 * @inheritdoc
	 */
	public function close(): void
	{
		if ($this->resource)
		{
			$resource = $this->detach();
			fclose($resource);
		}
	}

	/**
	 * @inheritdoc
	 */
	public function detach()
	{
		$resource = $this->resource;
		$this->resource = null;
		return $resource;
	}

	/**
	 * @inheritdoc
	 */
	public function getSize(): ?int
	{
		if ($this->resource !== null)
		{
			$stats = fstat($this->resource);
			return $stats['size'];
		}
		return null;
	}

	/**
	 * @inheritdoc
	 */
	public function tell(): int
	{
		if (!$this->resource)
		{
			throw new \RuntimeException('No resource available, cannot tell position.');
		}

		$result = ftell($this->resource);
		if ($result === false)
		{
			throw new \RuntimeException('Error occurred during tell operation.');
		}

		return $result;
	}

	/**
	 * @inheritdoc
	 */
	public function eof(): bool
	{
		if ($this->resource)
		{
			return feof($this->resource);
		}
		return true;
	}

	/**
	 * @inheritdoc
	 */
	public function isSeekable(): bool
	{
		if ($this->resource)
		{
			return $this->getMetadata('seekable');
		}

		return false;
	}

	/**
	 * @inheritdoc
	 */
	public function seek(int $offset, int $whence = SEEK_SET): void
	{
		if (!$this->resource)
		{
			throw new \RuntimeException('No resource available, cannot seek position.');
		}

		if (!$this->isSeekable())
		{
			throw new \RuntimeException('Stream is not seekable.');
		}

		$result = fseek($this->resource, $offset, $whence);

		if ($result !== 0)
		{
			throw new \RuntimeException('Error seeking within stream.');
		}
	}

	/**
	 * @inheritdoc
	 */
	public function rewind(): void
	{
		$this->seek(0);
	}

	/**
	 * @inheritdoc
	 */
	public function isWritable(): bool
	{
		if ($this->resource)
		{
			return is_writable($this->getMetadata('uri'));
		}

		return false;
	}

	/**
	 * @inheritdoc
	 */
	public function write(string $string): int
	{
		if (!$this->resource)
		{
			throw new \RuntimeException('No resource available, cannot write.');
		}

		$result = fwrite($this->resource, $string);

		if ($result === false)
		{
			throw new \RuntimeException('Error writing to stream.');
		}

		return $result;
	}

	/**
	 * @inheritdoc
	 */
	public function isReadable(): bool
	{
		if ($this->resource)
		{
			$mode = $this->getMetadata('mode');

			return (str_contains($mode, 'r') || str_contains($mode, '+'));
		}

		return false;
	}

	/**
	 * @inheritdoc
	 */
	public function read(int $length): string
	{
		if (!$this->resource)
		{
			throw new \RuntimeException('No resource available, cannot read.');
		}

		if (!$this->isReadable())
		{
			throw new \RuntimeException('Stream is not readable.');
		}

		$result = fread($this->resource, $length);

		if ($result === false)
		{
			throw new \RuntimeException('Error reading stream.');
		}

		return $result;
	}

	/**
	 * @inheritdoc
	 */
	public function getContents(): string
	{
		if (!$this->isReadable())
		{
			return '';
		}

		$result = stream_get_contents($this->resource);

		if ($result === false)
		{
			throw new \RuntimeException('Error reading stream.');
		}

		return $result;
	}

	/**
	 * @inheritdoc
	 */
	public function getMetadata(?string $key = null)
	{
		$meta = stream_get_meta_data($this->resource);

		if ($key === null)
		{
			return $meta;
		}

		return $meta[$key] ?? null;
	}

	public function copyTo($stream)
	{
		$this->rewind();
		return stream_copy_to_stream($this->resource, $stream);
	}
}