initial commit

This commit is contained in:
2024-04-29 13:12:44 +05:45
commit 34887303c5
19300 changed files with 5268802 additions and 0 deletions

View File

@ -0,0 +1,94 @@
=========
Changelog
=========
3.0.0 (2014-10-12)
------------------
* Now supports creating streams from functions and iterators.
* Supports creating buffered streams and asynchronous streams.
* Removed ``functions.php``. Use the corresponding functions provided by
``GuzzleHttp\Streams\Utils`` instead.
* Moved ``GuzzleHttp\Stream\MetadataStreamInterface::getMetadata`` to
``GuzzleHttp\Stream\StreamInterface``. MetadataStreamInterface is no longer
used and is marked as deprecated.
* Added ``attach()`` to ``GuzzleHttp\Stream\StreamInterface`` for PSR-7
compatibility.
* Removed ``flush()`` from StreamInterface.
* Removed the ``$maxLength`` parameter from
``GuzzleHttp\Stream\StreamInterface::getContents()``. This function now
returns the entire remainder of the stream. If you want to limit the maximum
amount of data read from the stream, use the
``GuzzleHttp\Stream\Utils::copyToString()`` function.
* Streams that return an empty string, ``''``, are no longer considered a
failure. You MUST return ``false`` to mark the read as a failure, and ensure
that any decorators you create properly return ``true`` in response to the
``eof()`` method when the stream is consumed.
* ``GuzzleHttp\Stream\Stream::__construct``,
``GuzzleHttp\Stream\Stream::factory``, and
``GuzzleHttp\Stream\Utils::create`` no longer accept a size in the second
argument. They now accept an associative array of options, including the
"size" key and "metadata" key which can be used to provide custom metadata.
* Added ``GuzzleHttp\Stream\BufferStream`` to add support for buffering data,
and when read, shifting data off of the buffer.
* Added ``GuzzleHttp\Stream\NullBuffer`` which can be used as a buffer that
does not actually store any data.
* Added ``GuzzleHttp\Stream\AsyncStream`` to provide support for non-blocking
streams that can be filled by a remote source (e.g., an event-loop). If a
``drain`` option is provided, the stream can also act as if it is a blocking
stream.
2.1.0 (2014-08-17)
------------------
* Added an InflateStream to inflate gzipped or deflated content.
* Added ``flush`` to stream wrapper.
* Added the ability to easily register the GuzzleStreamWrapper if needed.
2.0.0 (2014-08-16)
------------------
* Deprecated functions.php and moved all of those methods to
``GuzzleHttp\Streams\Utils``. Use ``GuzzleHttp\Stream\Stream::factory()``
instead of ``GuzzleHttp\Stream\create()`` to create new streams.
* Added ``flush()`` to ``StreamInterface``. This method is used to flush any
underlying stream write buffers.
* Added ``FnStream`` to easily decorate stream behavior with callables.
* ``Utils::hash`` now throws an exception when the stream cannot seek to 0.
1.5.1 (2014-09-10)
------------------
* Stream metadata is grabbed from the underlying stream each time
``getMetadata`` is called rather than returning a value from a cache.
* Properly closing all underlying streams when AppendStream is closed.
* Seek functions no longer throw exceptions.
* LazyOpenStream now correctly returns the underlying stream resource when
detached.
1.5.0 (2014-08-07)
------------------
* Added ``Stream\safe_open`` to open stream resources and throw exceptions
instead of raising errors.
1.4.0 (2014-07-19)
------------------
* Added a LazyOpenStream
1.3.0 (2014-07-15)
------------------
* Added an AppendStream to stream over multiple stream one after the other.
1.2.0 (2014-07-15)
------------------
* Updated the ``detach()`` method to return the underlying stream resource or
``null`` if it does not wrap a resource.
* Multiple fixes for how streams behave when the underlying resource is
detached
* Do not clear statcache when a stream does not have a 'uri'
* Added a fix to LimitStream
* Added a condition to ensure that functions.php can be required multiple times

View File

@ -0,0 +1,36 @@
==============
Guzzle Streams
==============
Provides a simple abstraction over streams of data.
This library is used in `Guzzle 5 <https://github.com/guzzle/guzzle>`_, and is
(currently) compatible with the WIP PSR-7.
Installation
============
This package can be installed easily using `Composer <http://getcomposer.org>`_.
Simply add the following to the composer.json file at the root of your project:
.. code-block:: javascript
{
"require": {
"guzzlehttp/streams": "~3.0"
}
}
Then install your dependencies using ``composer.phar install``.
Documentation
=============
The documentation for this package can be found on the main Guzzle website at
http://docs.guzzlephp.org/en/guzzle4/streams.html.
Testing
=======
This library is tested using PHPUnit. You'll need to install the dependencies
using `Composer <http://getcomposer.org>`_ then run ``make test``.

View File

@ -0,0 +1,186 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
use Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\CannotAttachException;
/**
* Reads from multiple streams, one after the other.
*
* This is a read-only stream decorator.
*/
class AppendStream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
/** @var StreamInterface[] Streams being decorated */
private $streams = [];
private $seekable = \true;
private $current = 0;
private $pos = 0;
private $detached = \false;
/**
* @param StreamInterface[] $streams Streams to decorate. Each stream must
* be readable.
*/
public function __construct(array $streams = [])
{
foreach ($streams as $stream) {
$this->addStream($stream);
}
}
public function __toString()
{
try {
$this->seek(0);
return $this->getContents();
} catch (\Exception $e) {
return '';
}
}
/**
* Add a stream to the AppendStream
*
* @param StreamInterface $stream Stream to append. Must be readable.
*
* @throws \InvalidArgumentException if the stream is not readable
*/
public function addStream(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $stream)
{
if (!$stream->isReadable()) {
throw new \InvalidArgumentException('Each stream must be readable');
}
// The stream is only seekable if all streams are seekable
if (!$stream->isSeekable()) {
$this->seekable = \false;
}
$this->streams[] = $stream;
}
public function getContents()
{
return \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Utils::copyToString($this);
}
/**
* Closes each attached stream.
*
* {@inheritdoc}
*/
public function close()
{
$this->pos = $this->current = 0;
foreach ($this->streams as $stream) {
$stream->close();
}
$this->streams = [];
}
/**
* Detaches each attached stream
*
* {@inheritdoc}
*/
public function detach()
{
$this->close();
$this->detached = \true;
}
public function attach($stream)
{
throw new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\CannotAttachException();
}
public function tell()
{
return $this->pos;
}
/**
* Tries to calculate the size by adding the size of each stream.
*
* If any of the streams do not return a valid number, then the size of the
* append stream cannot be determined and null is returned.
*
* {@inheritdoc}
*/
public function getSize()
{
$size = 0;
foreach ($this->streams as $stream) {
$s = $stream->getSize();
if ($s === null) {
return null;
}
$size += $s;
}
return $size;
}
public function eof()
{
return !$this->streams || $this->current >= \count($this->streams) - 1 && $this->streams[$this->current]->eof();
}
/**
* Attempts to seek to the given position. Only supports SEEK_SET.
*
* {@inheritdoc}
*/
public function seek($offset, $whence = \SEEK_SET)
{
if (!$this->seekable || $whence !== \SEEK_SET) {
return \false;
}
$success = \true;
$this->pos = $this->current = 0;
// Rewind each stream
foreach ($this->streams as $stream) {
if (!$stream->seek(0)) {
$success = \false;
}
}
if (!$success) {
return \false;
}
// Seek to the actual position by reading from each stream
while ($this->pos < $offset && !$this->eof()) {
$this->read(\min(8096, $offset - $this->pos));
}
return $this->pos == $offset;
}
/**
* Reads from all of the appended streams until the length is met or EOF.
*
* {@inheritdoc}
*/
public function read($length)
{
$buffer = '';
$total = \count($this->streams) - 1;
$remaining = $length;
while ($remaining > 0) {
// Progress to the next stream if needed.
if ($this->streams[$this->current]->eof()) {
if ($this->current == $total) {
break;
}
$this->current++;
}
$buffer .= $this->streams[$this->current]->read($remaining);
$remaining = $length - \strlen($buffer);
}
$this->pos += \strlen($buffer);
return $buffer;
}
public function isReadable()
{
return \true;
}
public function isWritable()
{
return \false;
}
public function isSeekable()
{
return $this->seekable;
}
public function write($string)
{
return \false;
}
public function getMetadata($key = null)
{
return $key ? null : [];
}
}

View File

@ -0,0 +1,173 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
/**
* Represents an asynchronous read-only stream that supports a drain event and
* pumping data from a source stream.
*
* The AsyncReadStream can be used as a completely asynchronous stream, meaning
* the data you can read from the stream will immediately return only
* the data that is currently buffered.
*
* AsyncReadStream can also be used in a "blocking" manner if a "pump" function
* is provided. When a caller requests more bytes than are available in the
* buffer, then the pump function is used to block until the requested number
* of bytes are available or the remote source stream has errored, closed, or
* timed-out. This behavior isn't strictly "blocking" because the pump function
* can send other transfers while waiting on the desired buffer size to be
* ready for reading (e.g., continue to tick an event loop).
*
* @unstable This class is subject to change.
*/
class AsyncReadStream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
use StreamDecoratorTrait;
/** @var callable|null Fn used to notify writers the buffer has drained */
private $drain;
/** @var callable|null Fn used to block for more data */
private $pump;
/** @var int|null Highwater mark of the underlying buffer */
private $hwm;
/** @var bool Whether or not drain needs to be called at some point */
private $needsDrain;
/** @var int The expected size of the remote source */
private $size;
/**
* In order to utilize high water marks to tell writers to slow down, the
* provided stream must answer to the "hwm" stream metadata variable,
* providing the high water mark. If no "hwm" metadata value is available,
* then the "drain" functionality is not utilized.
*
* This class accepts an associative array of configuration options.
*
* - drain: (callable) Function to invoke when the stream has drained,
* meaning the buffer is now writable again because the size of the
* buffer is at an acceptable level (e.g., below the high water mark).
* The function accepts a single argument, the buffer stream object that
* has drained.
* - pump: (callable) A function that accepts the number of bytes to read
* from the source stream. This function will block until all of the data
* that was requested has been read, EOF of the source stream, or the
* source stream is closed.
* - size: (int) The expected size in bytes of the data that will be read
* (if known up-front).
*
* @param StreamInterface $buffer Buffer that contains the data that has
* been read by the event loop.
* @param array $config Associative array of options.
*
* @throws \InvalidArgumentException if the buffer is not readable and
* writable.
*/
public function __construct(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $buffer, array $config = [])
{
if (!$buffer->isReadable() || !$buffer->isWritable()) {
throw new \InvalidArgumentException('Buffer must be readable and writable');
}
if (isset($config['size'])) {
$this->size = $config['size'];
}
static $callables = ['pump', 'drain'];
foreach ($callables as $check) {
if (isset($config[$check])) {
if (!\is_callable($config[$check])) {
throw new \InvalidArgumentException($check . ' must be callable');
}
$this->{$check} = $config[$check];
}
}
$this->hwm = $buffer->getMetadata('hwm');
// Cannot drain when there's no high water mark.
if ($this->hwm === null) {
$this->drain = null;
}
$this->stream = $buffer;
}
/**
* Factory method used to create new async stream and an underlying buffer
* if no buffer is provided.
*
* This function accepts the same options as AsyncReadStream::__construct,
* but added the following key value pairs:
*
* - buffer: (StreamInterface) Buffer used to buffer data. If none is
* provided, a default buffer is created.
* - hwm: (int) High water mark to use if a buffer is created on your
* behalf.
* - max_buffer: (int) If provided, wraps the utilized buffer in a
* DroppingStream decorator to ensure that buffer does not exceed a given
* length. When exceeded, the stream will begin dropping data. Set the
* max_buffer to 0, to use a NullStream which does not store data.
* - write: (callable) A function that is invoked when data is written
* to the underlying buffer. The function accepts the buffer as the first
* argument, and the data being written as the second. The function MUST
* return the number of bytes that were written or false to let writers
* know to slow down.
* - drain: (callable) See constructor documentation.
* - pump: (callable) See constructor documentation.
*
* @param array $options Associative array of options.
*
* @return array Returns an array containing the buffer used to buffer
* data, followed by the ready to use AsyncReadStream object.
*/
public static function create(array $options = [])
{
$maxBuffer = isset($options['max_buffer']) ? $options['max_buffer'] : null;
if ($maxBuffer === 0) {
$buffer = new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\NullStream();
} elseif (isset($options['buffer'])) {
$buffer = $options['buffer'];
} else {
$hwm = isset($options['hwm']) ? $options['hwm'] : 16384;
$buffer = new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\BufferStream($hwm);
}
if ($maxBuffer > 0) {
$buffer = new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\DroppingStream($buffer, $options['max_buffer']);
}
// Call the on_write callback if an on_write function was provided.
if (isset($options['write'])) {
$onWrite = $options['write'];
$buffer = \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\FnStream::decorate($buffer, ['write' => function ($string) use($buffer, $onWrite) {
$result = $buffer->write($string);
$onWrite($buffer, $string);
return $result;
}]);
}
return [$buffer, new self($buffer, $options)];
}
public function getSize()
{
return $this->size;
}
public function isWritable()
{
return \false;
}
public function write($string)
{
return \false;
}
public function read($length)
{
if (!$this->needsDrain && $this->drain) {
$this->needsDrain = $this->stream->getSize() >= $this->hwm;
}
$result = $this->stream->read($length);
// If we need to drain, then drain when the buffer is empty.
if ($this->needsDrain && $this->stream->getSize() === 0) {
$this->needsDrain = \false;
$drainFn = $this->drain;
$drainFn($this->stream);
}
$resultLen = \strlen($result);
// If a pump was provided, the buffer is still open, and not enough
// data was given, then block until the data is provided.
if ($this->pump && $resultLen < $length) {
$pumpFn = $this->pump;
$result .= $pumpFn($length - $resultLen);
}
return $result;
}
}

View File

@ -0,0 +1,116 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
use Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\CannotAttachException;
/**
* Provides a buffer stream that can be written to to fill a buffer, and read
* from to remove bytes from the buffer.
*
* This stream returns a "hwm" metadata value that tells upstream consumers
* what the configured high water mark of the stream is, or the maximum
* preferred size of the buffer.
*
* @package GuzzleHttp\Stream
*/
class BufferStream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
private $hwm;
private $buffer = '';
/**
* @param int $hwm High water mark, representing the preferred maximum
* buffer size. If the size of the buffer exceeds the high
* water mark, then calls to write will continue to succeed
* but will return false to inform writers to slow down
* until the buffer has been drained by reading from it.
*/
public function __construct($hwm = 16384)
{
$this->hwm = $hwm;
}
public function __toString()
{
return $this->getContents();
}
public function getContents()
{
$buffer = $this->buffer;
$this->buffer = '';
return $buffer;
}
public function close()
{
$this->buffer = '';
}
public function detach()
{
$this->close();
}
public function attach($stream)
{
throw new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\CannotAttachException();
}
public function getSize()
{
return \strlen($this->buffer);
}
public function isReadable()
{
return \true;
}
public function isWritable()
{
return \true;
}
public function isSeekable()
{
return \false;
}
public function seek($offset, $whence = \SEEK_SET)
{
return \false;
}
public function eof()
{
return \strlen($this->buffer) === 0;
}
public function tell()
{
return \false;
}
/**
* Reads data from the buffer.
*/
public function read($length)
{
$currentLength = \strlen($this->buffer);
if ($length >= $currentLength) {
// No need to slice the buffer because we don't have enough data.
$result = $this->buffer;
$this->buffer = '';
} else {
// Slice up the result to provide a subset of the buffer.
$result = \substr($this->buffer, 0, $length);
$this->buffer = \substr($this->buffer, $length);
}
return $result;
}
/**
* Writes data to the buffer.
*/
public function write($string)
{
$this->buffer .= $string;
if (\strlen($this->buffer) >= $this->hwm) {
return \false;
}
return \strlen($string);
}
public function getMetadata($key = null)
{
if ($key == 'hwm') {
return $this->hwm;
}
return $key ? null : [];
}
}

View File

@ -0,0 +1,97 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
use Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\SeekException;
/**
* Stream decorator that can cache previously read bytes from a sequentially
* read stream.
*/
class CachingStream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
use StreamDecoratorTrait;
/** @var StreamInterface Stream being wrapped */
private $remoteStream;
/** @var int Number of bytes to skip reading due to a write on the buffer */
private $skipReadBytes = 0;
/**
* We will treat the buffer object as the body of the stream
*
* @param StreamInterface $stream Stream to cache
* @param StreamInterface $target Optionally specify where data is cached
*/
public function __construct(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $stream, \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $target = null)
{
$this->remoteStream = $stream;
$this->stream = $target ?: new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Stream(\fopen('php://temp', 'r+'));
}
public function getSize()
{
return \max($this->stream->getSize(), $this->remoteStream->getSize());
}
/**
* {@inheritdoc}
* @throws SeekException When seeking with SEEK_END or when seeking
* past the total size of the buffer stream
*/
public function seek($offset, $whence = \SEEK_SET)
{
if ($whence == \SEEK_SET) {
$byte = $offset;
} elseif ($whence == \SEEK_CUR) {
$byte = $offset + $this->tell();
} else {
return \false;
}
// You cannot skip ahead past where you've read from the remote stream
if ($byte > $this->stream->getSize()) {
throw new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\SeekException($this, $byte, \sprintf('Cannot seek to byte %d when the buffered stream only' . ' contains %d bytes', $byte, $this->stream->getSize()));
}
return $this->stream->seek($byte);
}
public function read($length)
{
// Perform a regular read on any previously read data from the buffer
$data = $this->stream->read($length);
$remaining = $length - \strlen($data);
// More data was requested so read from the remote stream
if ($remaining) {
// If data was written to the buffer in a position that would have
// been filled from the remote stream, then we must skip bytes on
// the remote stream to emulate overwriting bytes from that
// position. This mimics the behavior of other PHP stream wrappers.
$remoteData = $this->remoteStream->read($remaining + $this->skipReadBytes);
if ($this->skipReadBytes) {
$len = \strlen($remoteData);
$remoteData = \substr($remoteData, $this->skipReadBytes);
$this->skipReadBytes = \max(0, $this->skipReadBytes - $len);
}
$data .= $remoteData;
$this->stream->write($remoteData);
}
return $data;
}
public function write($string)
{
// When appending to the end of the currently read stream, you'll want
// to skip bytes from being read from the remote stream to emulate
// other stream wrappers. Basically replacing bytes of data of a fixed
// length.
$overflow = \strlen($string) + $this->tell() - $this->remoteStream->tell();
if ($overflow > 0) {
$this->skipReadBytes += $overflow;
}
return $this->stream->write($string);
}
public function eof()
{
return $this->stream->eof() && $this->remoteStream->eof();
}
/**
* Close both the remote stream and buffer stream
*/
public function close()
{
$this->remoteStream->close() && $this->stream->close();
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
/**
* Stream decorator that begins dropping data once the size of the underlying
* stream becomes too full.
*/
class DroppingStream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
use StreamDecoratorTrait;
private $maxLength;
/**
* @param StreamInterface $stream Underlying stream to decorate.
* @param int $maxLength Maximum size before dropping data.
*/
public function __construct(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $stream, $maxLength)
{
$this->stream = $stream;
$this->maxLength = $maxLength;
}
public function write($string)
{
$diff = $this->maxLength - $this->stream->getSize();
// Begin returning false when the underlying stream is too large.
if ($diff <= 0) {
return \false;
}
// Write the stream or a subset of the stream if needed.
if (\strlen($string) < $diff) {
return $this->stream->write($string);
}
$this->stream->write(\substr($string, 0, $diff));
return \false;
}
}

View File

@ -0,0 +1,7 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception;
class CannotAttachException extends \RuntimeException
{
}

View File

@ -0,0 +1,25 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception;
use Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface;
/**
* Exception thrown when a seek fails on a stream.
*/
class SeekException extends \RuntimeException
{
private $stream;
public function __construct(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $stream, $pos = 0, $msg = '')
{
$this->stream = $stream;
$msg = $msg ?: 'Could not seek the stream to position ' . $pos;
parent::__construct($msg);
}
/**
* @return StreamInterface
*/
public function getStream()
{
return $this->stream;
}
}

View File

@ -0,0 +1,123 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
/**
* Compose stream implementations based on a hash of functions.
*
* Allows for easy testing and extension of a provided stream without needing
* to create a concrete class for a simple extension point.
*/
class FnStream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
/** @var array */
private $methods;
/** @var array Methods that must be implemented in the given array */
private static $slots = ['__toString', 'close', 'detach', 'attach', 'getSize', 'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write', 'isReadable', 'read', 'getContents', 'getMetadata'];
/**
* @param array $methods Hash of method name to a callable.
*/
public function __construct(array $methods)
{
$this->methods = $methods;
// Create the functions on the class
foreach ($methods as $name => $fn) {
$this->{'_fn_' . $name} = $fn;
}
}
/**
* Lazily determine which methods are not implemented.
* @throws \BadMethodCallException
*/
public function __get($name)
{
throw new \BadMethodCallException(\str_replace('_fn_', '', $name) . '() is not implemented in the FnStream');
}
/**
* The close method is called on the underlying stream only if possible.
*/
public function __destruct()
{
if (isset($this->_fn_close)) {
\call_user_func($this->_fn_close);
}
}
/**
* Adds custom functionality to an underlying stream by intercepting
* specific method calls.
*
* @param StreamInterface $stream Stream to decorate
* @param array $methods Hash of method name to a closure
*
* @return FnStream
*/
public static function decorate(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $stream, array $methods)
{
// If any of the required methods were not provided, then simply
// proxy to the decorated stream.
foreach (\array_diff(self::$slots, \array_keys($methods)) as $diff) {
$methods[$diff] = [$stream, $diff];
}
return new self($methods);
}
public function __toString()
{
return \call_user_func($this->_fn___toString);
}
public function close()
{
return \call_user_func($this->_fn_close);
}
public function detach()
{
return \call_user_func($this->_fn_detach);
}
public function attach($stream)
{
return \call_user_func($this->_fn_attach, $stream);
}
public function getSize()
{
return \call_user_func($this->_fn_getSize);
}
public function tell()
{
return \call_user_func($this->_fn_tell);
}
public function eof()
{
return \call_user_func($this->_fn_eof);
}
public function isSeekable()
{
return \call_user_func($this->_fn_isSeekable);
}
public function seek($offset, $whence = \SEEK_SET)
{
return \call_user_func($this->_fn_seek, $offset, $whence);
}
public function isWritable()
{
return \call_user_func($this->_fn_isWritable);
}
public function write($string)
{
return \call_user_func($this->_fn_write, $string);
}
public function isReadable()
{
return \call_user_func($this->_fn_isReadable);
}
public function read($length)
{
return \call_user_func($this->_fn_read, $length);
}
public function getContents()
{
return \call_user_func($this->_fn_getContents);
}
public function getMetadata($key = null)
{
return \call_user_func($this->_fn_getMetadata, $key);
}
}

View File

@ -0,0 +1,80 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
/**
* Converts Guzzle streams into PHP stream resources.
*/
class GuzzleStreamWrapper
{
/** @var resource */
public $context;
/** @var StreamInterface */
private $stream;
/** @var string r, r+, or w */
private $mode;
/**
* Returns a resource representing the stream.
*
* @param StreamInterface $stream The stream to get a resource for
*
* @return resource
* @throws \InvalidArgumentException if stream is not readable or writable
*/
public static function getResource(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $stream)
{
self::register();
if ($stream->isReadable()) {
$mode = $stream->isWritable() ? 'r+' : 'r';
} elseif ($stream->isWritable()) {
$mode = 'w';
} else {
throw new \InvalidArgumentException('The stream must be readable, ' . 'writable, or both.');
}
return \fopen('guzzle://stream', $mode, null, \stream_context_create(['guzzle' => ['stream' => $stream]]));
}
/**
* Registers the stream wrapper if needed
*/
public static function register()
{
if (!\in_array('guzzle', \stream_get_wrappers())) {
\stream_wrapper_register('guzzle', __CLASS__);
}
}
public function stream_open($path, $mode, $options, &$opened_path)
{
$options = \stream_context_get_options($this->context);
if (!isset($options['guzzle']['stream'])) {
return \false;
}
$this->mode = $mode;
$this->stream = $options['guzzle']['stream'];
return \true;
}
public function stream_read($count)
{
return $this->stream->read($count);
}
public function stream_write($data)
{
return (int) $this->stream->write($data);
}
public function stream_tell()
{
return $this->stream->tell();
}
public function stream_eof()
{
return $this->stream->eof();
}
public function stream_seek($offset, $whence)
{
return $this->stream->seek($offset, $whence);
}
public function stream_stat()
{
static $modeMap = ['r' => 33060, 'r+' => 33206, 'w' => 33188];
return ['dev' => 0, 'ino' => 0, 'mode' => $modeMap[$this->mode], 'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => $this->stream->getSize() ?: 0, 'atime' => 0, 'mtime' => 0, 'ctime' => 0, 'blksize' => 0, 'blocks' => 0];
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
/**
* Uses PHP's zlib.inflate filter to inflate deflate or gzipped content.
*
* This stream decorator skips the first 10 bytes of the given stream to remove
* the gzip header, converts the provided stream to a PHP stream resource,
* then appends the zlib.inflate filter. The stream is then converted back
* to a Guzzle stream resource to be used as a Guzzle stream.
*
* @link http://tools.ietf.org/html/rfc1952
* @link http://php.net/manual/en/filters.compression.php
*/
class InflateStream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
use StreamDecoratorTrait;
public function __construct(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $stream)
{
// Skip the first 10 bytes
$stream = new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\LimitStream($stream, -1, 10);
$resource = \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\GuzzleStreamWrapper::getResource($stream);
\stream_filter_append($resource, 'zlib.inflate', \STREAM_FILTER_READ);
$this->stream = new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Stream($resource);
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
/**
* Lazily reads or writes to a file that is opened only after an IO operation
* take place on the stream.
*/
class LazyOpenStream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
use StreamDecoratorTrait;
/** @var string File to open */
private $filename;
/** @var string $mode */
private $mode;
/**
* @param string $filename File to lazily open
* @param string $mode fopen mode to use when opening the stream
*/
public function __construct($filename, $mode)
{
$this->filename = $filename;
$this->mode = $mode;
}
/**
* Creates the underlying stream lazily when required.
*
* @return StreamInterface
*/
protected function createStream()
{
return \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Stream::factory(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Utils::open($this->filename, $this->mode));
}
}

View File

@ -0,0 +1,137 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
use Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\SeekException;
/**
* Decorator used to return only a subset of a stream
*/
class LimitStream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
use StreamDecoratorTrait;
/** @var int Offset to start reading from */
private $offset;
/** @var int Limit the number of bytes that can be read */
private $limit;
/**
* @param StreamInterface $stream Stream to wrap
* @param int $limit Total number of bytes to allow to be read
* from the stream. Pass -1 for no limit.
* @param int|null $offset Position to seek to before reading (only
* works on seekable streams).
*/
public function __construct(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $stream, $limit = -1, $offset = 0)
{
$this->stream = $stream;
$this->setLimit($limit);
$this->setOffset($offset);
}
public function eof()
{
// Always return true if the underlying stream is EOF
if ($this->stream->eof()) {
return \true;
}
// No limit and the underlying stream is not at EOF
if ($this->limit == -1) {
return \false;
}
$tell = $this->stream->tell();
if ($tell === \false) {
return \false;
}
return $tell >= $this->offset + $this->limit;
}
/**
* Returns the size of the limited subset of data
* {@inheritdoc}
*/
public function getSize()
{
if (null === ($length = $this->stream->getSize())) {
return null;
} elseif ($this->limit == -1) {
return $length - $this->offset;
} else {
return \min($this->limit, $length - $this->offset);
}
}
/**
* Allow for a bounded seek on the read limited stream
* {@inheritdoc}
*/
public function seek($offset, $whence = \SEEK_SET)
{
if ($whence !== \SEEK_SET || $offset < 0) {
return \false;
}
$offset += $this->offset;
if ($this->limit !== -1) {
if ($offset > $this->offset + $this->limit) {
$offset = $this->offset + $this->limit;
}
}
return $this->stream->seek($offset);
}
/**
* Give a relative tell()
* {@inheritdoc}
*/
public function tell()
{
return $this->stream->tell() - $this->offset;
}
/**
* Set the offset to start limiting from
*
* @param int $offset Offset to seek to and begin byte limiting from
*
* @return self
* @throws SeekException
*/
public function setOffset($offset)
{
$current = $this->stream->tell();
if ($current !== $offset) {
// If the stream cannot seek to the offset position, then read to it
if (!$this->stream->seek($offset)) {
if ($current > $offset) {
throw new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\SeekException($this, $offset);
} else {
$this->stream->read($offset - $current);
}
}
}
$this->offset = $offset;
return $this;
}
/**
* Set the limit of bytes that the decorator allows to be read from the
* stream.
*
* @param int $limit Number of bytes to allow to be read from the stream.
* Use -1 for no limit.
* @return self
*/
public function setLimit($limit)
{
$this->limit = $limit;
return $this;
}
public function read($length)
{
if ($this->limit == -1) {
return $this->stream->read($length);
}
// Check if the current position is less than the total allowed
// bytes + original offset
$remaining = $this->offset + $this->limit - $this->stream->tell();
if ($remaining > 0) {
// Only return the amount of requested data, ensuring that the byte
// limit is not exceeded
return $this->stream->read(\min($remaining, $length));
} else {
return \false;
}
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
/**
* This interface is deprecated and should no longer be used. Just use
* StreamInterface now that the getMetadata method has been added to
* StreamInterface.
*
* @deprecated
*/
interface MetadataStreamInterface extends \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
}

View File

@ -0,0 +1,23 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
/**
* Stream decorator that prevents a stream from being seeked
*/
class NoSeekStream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
use StreamDecoratorTrait;
public function seek($offset, $whence = \SEEK_SET)
{
return \false;
}
public function isSeekable()
{
return \false;
}
public function attach($stream)
{
$this->stream->attach($stream);
}
}

View File

@ -0,0 +1,69 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
use Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\CannotAttachException;
/**
* Does not store any data written to it.
*/
class NullStream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
public function __toString()
{
return '';
}
public function getContents()
{
return '';
}
public function close()
{
}
public function detach()
{
}
public function attach($stream)
{
throw new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\CannotAttachException();
}
public function getSize()
{
return 0;
}
public function isReadable()
{
return \true;
}
public function isWritable()
{
return \true;
}
public function isSeekable()
{
return \true;
}
public function eof()
{
return \true;
}
public function tell()
{
return 0;
}
public function seek($offset, $whence = \SEEK_SET)
{
return \false;
}
public function read($length)
{
return \false;
}
public function write($string)
{
return \strlen($string);
}
public function getMetadata($key = null)
{
return $key ? null : [];
}
}

View File

@ -0,0 +1,136 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
use Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\CannotAttachException;
/**
* Provides a read only stream that pumps data from a PHP callable.
*
* When invoking the provided callable, the PumpStream will pass the amount of
* data requested to read to the callable. The callable can choose to ignore
* this value and return fewer or more bytes than requested. Any extra data
* returned by the provided callable is buffered internally until drained using
* the read() function of the PumpStream. The provided callable MUST return
* false when there is no more data to read.
*/
class PumpStream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
/** @var callable */
private $source;
/** @var int */
private $size;
/** @var int */
private $tellPos = 0;
/** @var array */
private $metadata;
/** @var BufferStream */
private $buffer;
/**
* @param callable $source Source of the stream data. The callable MAY
* accept an integer argument used to control the
* amount of data to return. The callable MUST
* return a string when called, or false on error
* or EOF.
* @param array $options Stream options:
* - metadata: Hash of metadata to use with stream.
* - size: Size of the stream, if known.
*/
public function __construct(callable $source, array $options = [])
{
$this->source = $source;
$this->size = isset($options['size']) ? $options['size'] : null;
$this->metadata = isset($options['metadata']) ? $options['metadata'] : [];
$this->buffer = new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\BufferStream();
}
public function __toString()
{
return \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Utils::copyToString($this);
}
public function close()
{
$this->detach();
}
public function detach()
{
$this->tellPos = \false;
$this->source = null;
}
public function attach($stream)
{
throw new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\CannotAttachException();
}
public function getSize()
{
return $this->size;
}
public function tell()
{
return $this->tellPos;
}
public function eof()
{
return !$this->source;
}
public function isSeekable()
{
return \false;
}
public function seek($offset, $whence = \SEEK_SET)
{
return \false;
}
public function isWritable()
{
return \false;
}
public function write($string)
{
return \false;
}
public function isReadable()
{
return \true;
}
public function read($length)
{
$data = $this->buffer->read($length);
$readLen = \strlen($data);
$this->tellPos += $readLen;
$remaining = $length - $readLen;
if ($remaining) {
$this->pump($remaining);
$data .= $this->buffer->read($remaining);
$this->tellPos += \strlen($data) - $readLen;
}
return $data;
}
public function getContents()
{
$result = '';
while (!$this->eof()) {
$result .= $this->read(1000000);
}
return $result;
}
public function getMetadata($key = null)
{
if (!$key) {
return $this->metadata;
}
return isset($this->metadata[$key]) ? $this->metadata[$key] : null;
}
private function pump($length)
{
if ($this->source) {
do {
$data = \call_user_func($this->source, $length);
if ($data === \false || $data === null) {
$this->source = null;
return;
}
$this->buffer->write($data);
$length -= \strlen($data);
} while ($length > 0);
}
}
}

View File

@ -0,0 +1,203 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
/**
* PHP stream implementation
*/
class Stream implements \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface
{
private $stream;
private $size;
private $seekable;
private $readable;
private $writable;
private $uri;
private $customMetadata;
/** @var array Hash of readable and writable stream types */
private static $readWriteHash = ['read' => ['r' => \true, 'w+' => \true, 'r+' => \true, 'x+' => \true, 'c+' => \true, 'rb' => \true, 'w+b' => \true, 'r+b' => \true, 'x+b' => \true, 'c+b' => \true, 'rt' => \true, 'w+t' => \true, 'r+t' => \true, 'x+t' => \true, 'c+t' => \true, 'a+' => \true], 'write' => ['w' => \true, 'w+' => \true, 'rw' => \true, 'r+' => \true, 'x+' => \true, 'c+' => \true, 'wb' => \true, 'w+b' => \true, 'r+b' => \true, 'x+b' => \true, 'c+b' => \true, 'w+t' => \true, 'r+t' => \true, 'x+t' => \true, 'c+t' => \true, 'a' => \true, 'a+' => \true]];
/**
* Create a new stream based on the input type.
*
* This factory accepts the same associative array of options as described
* in the constructor.
*
* @param resource|string|StreamInterface $resource Entity body data
* @param array $options Additional options
*
* @return Stream
* @throws \InvalidArgumentException if the $resource arg is not valid.
*/
public static function factory($resource = '', array $options = [])
{
$type = \gettype($resource);
if ($type == 'string') {
$stream = \fopen('php://temp', 'r+');
if ($resource !== '') {
\fwrite($stream, $resource);
\fseek($stream, 0);
}
return new self($stream, $options);
}
if ($type == 'resource') {
return new self($resource, $options);
}
if ($resource instanceof \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface) {
return $resource;
}
if ($type == 'object' && \method_exists($resource, '__toString')) {
return self::factory((string) $resource, $options);
}
if (\is_callable($resource)) {
return new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\PumpStream($resource, $options);
}
if ($resource instanceof \Iterator) {
return new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\PumpStream(function () use($resource) {
if (!$resource->valid()) {
return \false;
}
$result = $resource->current();
$resource->next();
return $result;
}, $options);
}
throw new \InvalidArgumentException('Invalid resource type: ' . $type);
}
/**
* This constructor accepts an associative array of options.
*
* - size: (int) If a read stream would otherwise have an indeterminate
* size, but the size is known due to foreknownledge, then you can
* provide that size, in bytes.
* - metadata: (array) Any additional metadata to return when the metadata
* of the stream is accessed.
*
* @param resource $stream Stream resource to wrap.
* @param array $options Associative array of options.
*
* @throws \InvalidArgumentException if the stream is not a stream resource
*/
public function __construct($stream, $options = [])
{
if (!\is_resource($stream)) {
throw new \InvalidArgumentException('Stream must be a resource');
}
if (isset($options['size'])) {
$this->size = $options['size'];
}
$this->customMetadata = isset($options['metadata']) ? $options['metadata'] : [];
$this->attach($stream);
}
/**
* Closes the stream when the destructed
*/
public function __destruct()
{
$this->close();
}
public function __toString()
{
if (!$this->stream) {
return '';
}
$this->seek(0);
return (string) \stream_get_contents($this->stream);
}
public function getContents()
{
return $this->stream ? \stream_get_contents($this->stream) : '';
}
public function close()
{
if (\is_resource($this->stream)) {
\fclose($this->stream);
}
$this->detach();
}
public function detach()
{
$result = $this->stream;
$this->stream = $this->size = $this->uri = null;
$this->readable = $this->writable = $this->seekable = \false;
return $result;
}
public function attach($stream)
{
$this->stream = $stream;
$meta = \stream_get_meta_data($this->stream);
$this->seekable = $meta['seekable'];
$this->readable = isset(self::$readWriteHash['read'][$meta['mode']]);
$this->writable = isset(self::$readWriteHash['write'][$meta['mode']]);
$this->uri = $this->getMetadata('uri');
}
public function getSize()
{
if ($this->size !== null) {
return $this->size;
}
if (!$this->stream) {
return null;
}
// Clear the stat cache if the stream has a URI
if ($this->uri) {
\clearstatcache(\true, $this->uri);
}
$stats = \fstat($this->stream);
if (isset($stats['size'])) {
$this->size = $stats['size'];
return $this->size;
}
return null;
}
public function isReadable()
{
return $this->readable;
}
public function isWritable()
{
return $this->writable;
}
public function isSeekable()
{
return $this->seekable;
}
public function eof()
{
return !$this->stream || \feof($this->stream);
}
public function tell()
{
return $this->stream ? \ftell($this->stream) : \false;
}
public function setSize($size)
{
$this->size = $size;
return $this;
}
public function seek($offset, $whence = \SEEK_SET)
{
return $this->seekable ? \fseek($this->stream, $offset, $whence) === 0 : \false;
}
public function read($length)
{
return $this->readable ? \fread($this->stream, $length) : \false;
}
public function write($string)
{
// We can't know the size after writing anything
$this->size = null;
return $this->writable ? \fwrite($this->stream, $string) : \false;
}
public function getMetadata($key = null)
{
if (!$this->stream) {
return $key ? null : [];
} elseif (!$key) {
return $this->customMetadata + \stream_get_meta_data($this->stream);
} elseif (isset($this->customMetadata[$key])) {
return $this->customMetadata[$key];
}
$meta = \stream_get_meta_data($this->stream);
return isset($meta[$key]) ? $meta[$key] : null;
}
}

View File

@ -0,0 +1,122 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
use Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\CannotAttachException;
/**
* Stream decorator trait
* @property StreamInterface stream
*/
trait StreamDecoratorTrait
{
/**
* @param StreamInterface $stream Stream to decorate
*/
public function __construct(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $stream)
{
$this->stream = $stream;
}
/**
* Magic method used to create a new stream if streams are not added in
* the constructor of a decorator (e.g., LazyOpenStream).
*/
public function __get($name)
{
if ($name == 'stream') {
$this->stream = $this->createStream();
return $this->stream;
}
throw new \UnexpectedValueException("{$name} not found on class");
}
public function __toString()
{
try {
$this->seek(0);
return $this->getContents();
} catch (\Exception $e) {
// Really, PHP? https://bugs.php.net/bug.php?id=53648
\trigger_error('StreamDecorator::__toString exception: ' . (string) $e, \E_USER_ERROR);
return '';
}
}
public function getContents()
{
return \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Utils::copyToString($this);
}
/**
* Allow decorators to implement custom methods
*
* @param string $method Missing method name
* @param array $args Method arguments
*
* @return mixed
*/
public function __call($method, array $args)
{
$result = \call_user_func_array(array($this->stream, $method), $args);
// Always return the wrapped object if the result is a return $this
return $result === $this->stream ? $this : $result;
}
public function close()
{
$this->stream->close();
}
public function getMetadata($key = null)
{
return $this->stream->getMetadata($key);
}
public function detach()
{
return $this->stream->detach();
}
public function attach($stream)
{
throw new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\CannotAttachException();
}
public function getSize()
{
return $this->stream->getSize();
}
public function eof()
{
return $this->stream->eof();
}
public function tell()
{
return $this->stream->tell();
}
public function isReadable()
{
return $this->stream->isReadable();
}
public function isWritable()
{
return $this->stream->isWritable();
}
public function isSeekable()
{
return $this->stream->isSeekable();
}
public function seek($offset, $whence = \SEEK_SET)
{
return $this->stream->seek($offset, $whence);
}
public function read($length)
{
return $this->stream->read($length);
}
public function write($string)
{
return $this->stream->write($string);
}
/**
* Implement in subclasses to dynamically create streams when requested.
*
* @return StreamInterface
* @throws \BadMethodCallException
*/
protected function createStream()
{
throw new \BadMethodCallException('createStream() not implemented in ' . \get_class($this));
}
}

View File

@ -0,0 +1,146 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
/**
* Describes a stream instance.
*/
interface StreamInterface
{
/**
* Attempts to seek to the beginning of the stream and reads all data into
* a string until the end of the stream is reached.
*
* Warning: This could attempt to load a large amount of data into memory.
*
* @return string
*/
public function __toString();
/**
* Closes the stream and any underlying resources.
*/
public function close();
/**
* Separates any underlying resources from the stream.
*
* After the underlying resource has been detached, the stream object is in
* an unusable state. If you wish to use a Stream object as a PHP stream
* but keep the Stream object in a consistent state, use
* {@see GuzzleHttp\Stream\GuzzleStreamWrapper::getResource}.
*
* @return resource|null Returns the underlying PHP stream resource or null
* if the Stream object did not utilize an underlying
* stream resource.
*/
public function detach();
/**
* Replaces the underlying stream resource with the provided stream.
*
* Use this method to replace the underlying stream with another; as an
* example, in server-side code, if you decide to return a file, you
* would replace the original content-oriented stream with the file
* stream.
*
* Any internal state such as caching of cursor position should be reset
* when attach() is called, as the stream has changed.
*
* @param resource $stream
*
* @return void
*/
public function attach($stream);
/**
* Get the size of the stream if known
*
* @return int|null Returns the size in bytes if known, or null if unknown
*/
public function getSize();
/**
* Returns the current position of the file read/write pointer
*
* @return int|bool Returns the position of the file pointer or false on error
*/
public function tell();
/**
* Returns true if the stream is at the end of the stream.
*
* @return bool
*/
public function eof();
/**
* Returns whether or not the stream is seekable
*
* @return bool
*/
public function isSeekable();
/**
* Seek to a position in the stream
*
* @param int $offset Stream offset
* @param int $whence Specifies how the cursor position will be calculated
* based on the seek offset. Valid values are identical
* to the built-in PHP $whence values for `fseek()`.
* SEEK_SET: Set position equal to offset bytes
* SEEK_CUR: Set position to current location plus offset
* SEEK_END: Set position to end-of-stream plus offset
*
* @return bool Returns true on success or false on failure
* @link http://www.php.net/manual/en/function.fseek.php
*/
public function seek($offset, $whence = \SEEK_SET);
/**
* Returns whether or not the stream is writable
*
* @return bool
*/
public function isWritable();
/**
* Write data to the stream
*
* @param string $string The string that is to be written.
*
* @return int|bool Returns the number of bytes written to the stream on
* success returns false on failure (e.g., broken pipe,
* writer needs to slow down, buffer is full, etc.)
*/
public function write($string);
/**
* Returns whether or not the stream is readable
*
* @return bool
*/
public function isReadable();
/**
* Read data from the stream
*
* @param int $length Read up to $length bytes from the object and return
* them. Fewer than $length bytes may be returned if
* underlying stream call returns fewer bytes.
*
* @return string Returns the data read from the stream.
*/
public function read($length);
/**
* Returns the remaining contents of the stream as a string.
*
* Note: this could potentially load a large amount of data into memory.
*
* @return string
*/
public function getContents();
/**
* Get stream metadata as an associative array or retrieve a specific key.
*
* The keys returned are identical to the keys returned from PHP's
* stream_get_meta_data() function.
*
* @param string $key Specific metadata to retrieve.
*
* @return array|mixed|null Returns an associative array if no key is
* no key is provided. Returns a specific key
* value if a key is provided and the value is
* found, or null if the key is not found.
* @see http://php.net/manual/en/function.stream-get-meta-data.php
*/
public function getMetadata($key = null);
}

View File

@ -0,0 +1,167 @@
<?php
namespace Google\Site_Kit_Dependencies\GuzzleHttp\Stream;
use Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\SeekException;
/**
* Static utility class because PHP's autoloaders don't support the concept
* of namespaced function autoloading.
*/
class Utils
{
/**
* Safely opens a PHP stream resource using a filename.
*
* When fopen fails, PHP normally raises a warning. This function adds an
* error handler that checks for errors and throws an exception instead.
*
* @param string $filename File to open
* @param string $mode Mode used to open the file
*
* @return resource
* @throws \RuntimeException if the file cannot be opened
*/
public static function open($filename, $mode)
{
$ex = null;
\set_error_handler(function () use($filename, $mode, &$ex) {
$ex = new \RuntimeException(\sprintf('Unable to open %s using mode %s: %s', $filename, $mode, \func_get_args()[1]));
});
$handle = \fopen($filename, $mode);
\restore_error_handler();
if ($ex) {
/** @var $ex \RuntimeException */
throw $ex;
}
return $handle;
}
/**
* Copy the contents of a stream into a string until the given number of
* bytes have been read.
*
* @param StreamInterface $stream Stream to read
* @param int $maxLen Maximum number of bytes to read. Pass -1
* to read the entire stream.
* @return string
*/
public static function copyToString(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $stream, $maxLen = -1)
{
$buffer = '';
if ($maxLen === -1) {
while (!$stream->eof()) {
$buf = $stream->read(1048576);
if ($buf === \false) {
break;
}
$buffer .= $buf;
}
return $buffer;
}
$len = 0;
while (!$stream->eof() && $len < $maxLen) {
$buf = $stream->read($maxLen - $len);
if ($buf === \false) {
break;
}
$buffer .= $buf;
$len = \strlen($buffer);
}
return $buffer;
}
/**
* Copy the contents of a stream into another stream until the given number
* of bytes have been read.
*
* @param StreamInterface $source Stream to read from
* @param StreamInterface $dest Stream to write to
* @param int $maxLen Maximum number of bytes to read. Pass -1
* to read the entire stream.
*/
public static function copyToStream(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $source, \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $dest, $maxLen = -1)
{
if ($maxLen === -1) {
while (!$source->eof()) {
if (!$dest->write($source->read(1048576))) {
break;
}
}
return;
}
$bytes = 0;
while (!$source->eof()) {
$buf = $source->read($maxLen - $bytes);
if (!($len = \strlen($buf))) {
break;
}
$bytes += $len;
$dest->write($buf);
if ($bytes == $maxLen) {
break;
}
}
}
/**
* Calculate a hash of a Stream
*
* @param StreamInterface $stream Stream to calculate the hash for
* @param string $algo Hash algorithm (e.g. md5, crc32, etc)
* @param bool $rawOutput Whether or not to use raw output
*
* @return string Returns the hash of the stream
* @throws SeekException
*/
public static function hash(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $stream, $algo, $rawOutput = \false)
{
$pos = $stream->tell();
if ($pos > 0 && !$stream->seek(0)) {
throw new \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Exception\SeekException($stream);
}
$ctx = \hash_init($algo);
while (!$stream->eof()) {
\hash_update($ctx, $stream->read(1048576));
}
$out = \hash_final($ctx, (bool) $rawOutput);
$stream->seek($pos);
return $out;
}
/**
* Read a line from the stream up to the maximum allowed buffer length
*
* @param StreamInterface $stream Stream to read from
* @param int $maxLength Maximum buffer length
*
* @return string|bool
*/
public static function readline(\Google\Site_Kit_Dependencies\GuzzleHttp\Stream\StreamInterface $stream, $maxLength = null)
{
$buffer = '';
$size = 0;
while (!$stream->eof()) {
if (\false === ($byte = $stream->read(1))) {
return $buffer;
}
$buffer .= $byte;
// Break when a new line is found or the max length - 1 is reached
if ($byte == \PHP_EOL || ++$size == $maxLength - 1) {
break;
}
}
return $buffer;
}
/**
* Alias of GuzzleHttp\Stream\Stream::factory.
*
* @param mixed $resource Resource to create
* @param array $options Associative array of stream options defined in
* {@see \GuzzleHttp\Stream\Stream::__construct}
*
* @return StreamInterface
*
* @see GuzzleHttp\Stream\Stream::factory
* @see GuzzleHttp\Stream\Stream::__construct
*/
public static function create($resource, array $options = [])
{
return \Google\Site_Kit_Dependencies\GuzzleHttp\Stream\Stream::factory($resource, $options);
}
}