src/MemoryStream.php
public function read(int $length = 0, string $byte = null, float $timeout = 0): \Generator
    {
        while (null !== $this->delayed) {
            yield $this->delayed;
        }

        if (!$this->isReadable()) {
            throw new UnreadableException('The stream is no longer readable.');
        }

        $this->length = $length;
        if (0 > $this->length) {
            throw new InvalidArgumentError('The length should be a positive integer.');
        }

        $this->byte = strlen($byte) ? $byte[0] : null;

        if (!$this->buffer->isEmpty()) {
            $data = $this->remove();

            if (0 !== $this->hwm && $this->buffer->getLength() <= $this->hwm) {
                while (!$this->queue->isEmpty()) {
                    /** @var \Icicle\Awaitable\Delayed $delayed */
                    $delayed = $this->queue->shift();
                    $delayed->resolve();
                }
            }

            if (!$this->writable && $this->buffer->isEmpty()) {
                $this->free();
            }

            return $data;
        }

        $awaitable = $this->delayed = new Delayed();

        if ($timeout) {
            $awaitable = $this->delayed->timeout($timeout);
        }

        try {
            $data = yield $awaitable;
        } finally {
            $this->delayed = null;
        }

        return $data;
    }
public function read(int $length = 0, string $byte = null, float $timeout = 0): \Generator
    {
        while (null !== $this->delayed) {
            yield $this->delayed;
        }

        if (!$this->isReadable()) {
            throw new UnreadableException('The stream is no longer readable.');
        }

        $this->length = $length;
        if (0 > $this->length) {
            throw new InvalidArgumentError('The length should be a positive integer.');
        }

        $this->byte = strlen($byte) ? $byte[0] : null;

        if (!$this->buffer->isEmpty()) {
            $data = $this->remove();

            if (0 !== $this->hwm && $this->buffer->getLength() <= $this->hwm) {
                while (!$this->queue->isEmpty()) {
                    /** @var \Icicle\Awaitable\Delayed $delayed */
                    $delayed = $this->queue->shift();
                    $delayed->resolve();
                }
            }

            if (!$this->writable && $this->buffer->isEmpty()) {
                $this->free();
            }

            return $data;
        }

        $awaitable = $this->delayed = new Delayed();

        if ($timeout) {
            $awaitable = $this->delayed->timeout($timeout);
        }

        try {
            $data = yield $awaitable;
        } finally {
            $this->delayed = null;
        }

        return $data;
    }
{@inheritdoc}