Skip to content

Instantly share code, notes, and snippets.

@clue
Created July 30, 2019 12:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save clue/e646b99cf54fb47d05f37ac08a472993 to your computer and use it in GitHub Desktop.
Save clue/e646b99cf54fb47d05f37ac08a472993 to your computer and use it in GitHub Desktop.
<?php
namespace Clue\React\Foo;
use Evenement\EventEmitter;
use React\Stream\ReadableStreamInterface;
use React\Stream\WritableStreamInterface;
use React\Stream\Util;
class MagicBytesSplitter extends EventEmitter implements ReadableStreamInterface
{
private $input;
private $magicBytes;
private $buffer = '';
private $closed = false;
public function __construct(ReadableStreamInterface $input, $magicBytes)
{
$this->input = $input;
$this->magicBytes = $magicBytes;
if (!$input->isReadable()) {
$this->close();
return;
}
$this->input->on('data', array($this, 'handleData'));
$this->input->on('end', array($this, 'handleEnd'));
$this->input->on('error', array($this, 'handleError'));
$this->input->on('close', array($this, 'close'));
}
public function pause()
{
$this->input->pause();
}
public function resume()
{
$this->input->resume();
}
public function isReadable()
{
return $this->input->isReadable();
}
public function pipe(WritableStreamInterface $dest, array $options = [])
{
Util::pipe($this, $dest, $options);
return $dest;
}
public function close()
{
if ($this->closed) {
return;
}
$this->closed = true;
$this->buffer = '';
$this->input->close();
$this->emit('close');
$this->removeAllListeners();
}
/** @internal */
public function handleData($chunk)
{
$this->buffer .= $chunk;
while (($pos = \strpos($this->buffer, $this->magicBytes, 1)) !== false) {
$chunk = \substr($this->buffer, 0, $pos);
$this->buffer = (string)\substr($this->buffer, $pos + \strlen($this->magicBytes));
$this->emit('data', array($chunk));
}
}
/** @internal */
public function handleEnd()
{
if ($this->buffer !== '') {
$this->emit('data', array($this->buffer));
}
if (!$this->closed) {
$this->emit('end');
$this->close();
}
}
/** @internal */
public function handleError(\Exception $e)
{
$this->emit('error', array($e));
$this->close();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment