public function read($length)
    {
        $length = max(0, (int) $length);
        $encoder = $this->getEncoder();

        while (strlen($this->buffer) < $length && $encoder->valid()) {
            $this->buffer .= $encoder->current();
            $encoder->next();
        }

        if (strlen($this->buffer) > $length || $encoder->valid()) {
            $output = substr($this->buffer, 0, $length);
            $this->buffer = substr($this->buffer, $length);
        } else {
            $output = (string) $this->buffer;
            $this->buffer = null;
        }

        $this->cursor += strlen($output);

        return $output;
    }