/** * 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(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; }
/** * 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(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]])); }
/** * 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(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; }