You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
205 lines
3.8 KiB
205 lines
3.8 KiB
7 years ago
|
<?php
|
||
|
/**
|
||
|
* @link http://www.yiiframework.com/
|
||
|
* @copyright Copyright (c) 2008 Yii Software LLC
|
||
|
* @license http://www.yiiframework.com/license/
|
||
|
*/
|
||
|
|
||
|
namespace yii\http;
|
||
|
|
||
|
use Psr\Http\Message\StreamInterface;
|
||
|
use yii\base\BaseObject;
|
||
|
use yii\base\InvalidArgumentException;
|
||
|
|
||
|
/**
|
||
|
* MemoryStream uses internal field as a stream source. Thus data associated with this stream exists only in
|
||
|
* memory and will be lost once stream is closed.
|
||
|
*
|
||
|
* Example:
|
||
|
*
|
||
|
* ```php
|
||
|
* $stream = new MemoryStream();
|
||
|
*
|
||
|
* $stream->write('some content...');
|
||
|
* // ...
|
||
|
* $stream->rewind();
|
||
|
* echo $stream->getContents();
|
||
|
* ```
|
||
|
*
|
||
|
* @author Paul Klimov <klimov.paul@gmail.com>
|
||
|
* @since 2.1.0
|
||
|
*/
|
||
|
class MemoryStream extends BaseObject implements StreamInterface
|
||
|
{
|
||
|
/**
|
||
|
* @var string internal content.
|
||
|
*/
|
||
|
private $buffer = '';
|
||
|
/**
|
||
|
* @var int internal stream pointer.
|
||
|
*/
|
||
|
private $pointer = 0;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function __toString()
|
||
|
{
|
||
|
return $this->buffer;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function close()
|
||
|
{
|
||
|
$this->buffer = '';
|
||
|
$this->pointer = 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function detach()
|
||
|
{
|
||
|
$this->close();
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function getSize()
|
||
|
{
|
||
|
return strlen($this->buffer);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function tell()
|
||
|
{
|
||
|
return $this->pointer;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function eof()
|
||
|
{
|
||
|
return $this->pointer >= $this->getSize();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function isSeekable()
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function seek($offset, $whence = SEEK_SET)
|
||
|
{
|
||
|
switch ($whence) {
|
||
|
case SEEK_SET:
|
||
|
$this->pointer = $offset;
|
||
|
break;
|
||
|
case SEEK_CUR:
|
||
|
$this->pointer += $offset;
|
||
|
break;
|
||
|
case SEEK_END:
|
||
|
$this->pointer = $this->getSize() + $offset;
|
||
|
break;
|
||
|
default:
|
||
|
throw new InvalidArgumentException("Unknown seek whence: '{$whence}'.");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function rewind()
|
||
|
{
|
||
|
$this->seek(0);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function isWritable()
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function write($string)
|
||
|
{
|
||
|
$size = $this->getSize();
|
||
|
$writeSize = strlen($string);
|
||
|
|
||
|
if ($this->pointer >= $size) {
|
||
|
$this->buffer .= $string;
|
||
|
$this->pointer = $size + $writeSize;
|
||
|
return $writeSize;
|
||
|
}
|
||
|
|
||
|
$begin = substr($this->buffer, 0, $this->pointer);
|
||
|
$end = substr($this->buffer, $this->pointer + $writeSize);
|
||
|
|
||
|
$this->buffer = $begin . $string . $end;
|
||
|
$this->pointer += $writeSize;
|
||
|
return $writeSize;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function isReadable()
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function read($length)
|
||
|
{
|
||
|
$data = substr($this->buffer, $this->pointer, $length);
|
||
|
$this->pointer += $length;
|
||
|
return $data;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function getContents()
|
||
|
{
|
||
|
if ($this->pointer === 0) {
|
||
|
return $this->buffer;
|
||
|
}
|
||
|
return substr($this->buffer, $this->pointer);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function getMetadata($key = null)
|
||
|
{
|
||
|
$metadata = [
|
||
|
'mode' => 'rw',
|
||
|
'seekable' => $this->isSeekable(),
|
||
|
];
|
||
|
|
||
|
if ($key === null) {
|
||
|
return $metadata;
|
||
|
}
|
||
|
|
||
|
return (isset($metadata[$key])) ? $metadata[$key] : null;
|
||
|
}
|
||
|
}
|