/vendor/guzzlehttp/streams/src/FnStream.php |
@@ -0,0 +1,147 @@ |
<?php |
namespace 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 MetadataStreamInterface |
{ |
/** @var array */ |
private $methods; |
|
/** @var array Methods that must be implemented in the given array */ |
private static $slots = ['__toString', 'close', 'detach', 'getSize', |
'tell', 'eof', 'isSeekable', 'seek', 'isWritable', 'write', 'flush', |
'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(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 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 flush() |
{ |
return call_user_func($this->_fn_flush); |
} |
|
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($maxLength = -1) |
{ |
return call_user_func($this->_fn_getContents, $maxLength); |
} |
|
public function getMetadata($key = null) |
{ |
return call_user_func($this->_fn_getMetadata, $key); |
} |
} |