142 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace React\Stream;
 | |
| 
 | |
| use Evenement\EventEmitter;
 | |
| use React\EventLoop\LoopInterface;
 | |
| use InvalidArgumentException;
 | |
| 
 | |
| class Stream extends EventEmitter implements DuplexStreamInterface
 | |
| {
 | |
|     public $bufferSize = 4096;
 | |
|     public $stream;
 | |
|     protected $readable = true;
 | |
|     protected $writable = true;
 | |
|     protected $closing = false;
 | |
|     protected $loop;
 | |
|     protected $buffer;
 | |
| 
 | |
|     public function __construct($stream, LoopInterface $loop)
 | |
|     {
 | |
|         $this->stream = $stream;
 | |
|         if (!is_resource($this->stream) || get_resource_type($this->stream) !== "stream") {
 | |
|              throw new InvalidArgumentException('First parameter must be a valid stream resource');
 | |
|         }
 | |
| 
 | |
|         stream_set_blocking($this->stream, 0);
 | |
| 
 | |
|         $this->loop = $loop;
 | |
|         $this->buffer = new Buffer($this->stream, $this->loop);
 | |
| 
 | |
|         $this->buffer->on('error', function ($error) {
 | |
|             $this->emit('error', array($error, $this));
 | |
|             $this->close();
 | |
|         });
 | |
| 
 | |
|         $this->buffer->on('drain', function () {
 | |
|             $this->emit('drain', array($this));
 | |
|         });
 | |
| 
 | |
|         $this->resume();
 | |
|     }
 | |
| 
 | |
|     public function isReadable()
 | |
|     {
 | |
|         return $this->readable;
 | |
|     }
 | |
| 
 | |
|     public function isWritable()
 | |
|     {
 | |
|         return $this->writable;
 | |
|     }
 | |
| 
 | |
|     public function pause()
 | |
|     {
 | |
|         $this->loop->removeReadStream($this->stream);
 | |
|     }
 | |
| 
 | |
|     public function resume()
 | |
|     {
 | |
|         if ($this->readable) {
 | |
|             $this->loop->addReadStream($this->stream, array($this, 'handleData'));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public function write($data)
 | |
|     {
 | |
|         if (!$this->writable) {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         return $this->buffer->write($data);
 | |
|     }
 | |
| 
 | |
|     public function close()
 | |
|     {
 | |
|         if (!$this->writable && !$this->closing) {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         $this->closing = false;
 | |
| 
 | |
|         $this->readable = false;
 | |
|         $this->writable = false;
 | |
| 
 | |
|         $this->emit('end', array($this));
 | |
|         $this->emit('close', array($this));
 | |
|         $this->loop->removeStream($this->stream);
 | |
|         $this->buffer->removeAllListeners();
 | |
|         $this->removeAllListeners();
 | |
| 
 | |
|         $this->handleClose();
 | |
|     }
 | |
| 
 | |
|     public function end($data = null)
 | |
|     {
 | |
|         if (!$this->writable) {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         $this->closing = true;
 | |
| 
 | |
|         $this->readable = false;
 | |
|         $this->writable = false;
 | |
| 
 | |
|         $this->buffer->on('close', function () {
 | |
|             $this->close();
 | |
|         });
 | |
| 
 | |
|         $this->buffer->end($data);
 | |
|     }
 | |
| 
 | |
|     public function pipe(WritableStreamInterface $dest, array $options = array())
 | |
|     {
 | |
|         Util::pipe($this, $dest, $options);
 | |
| 
 | |
|         return $dest;
 | |
|     }
 | |
| 
 | |
|     public function handleData($stream)
 | |
|     {
 | |
|         $data = fread($stream, $this->bufferSize);
 | |
| 
 | |
|         $this->emit('data', array($data, $this));
 | |
| 
 | |
|         if (!is_resource($stream) || feof($stream)) {
 | |
|             $this->end();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public function handleClose()
 | |
|     {
 | |
|         if (is_resource($this->stream)) {
 | |
|             fclose($this->stream);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public function getBuffer()
 | |
|     {
 | |
|         return $this->buffer;
 | |
|     }
 | |
| }
 |