public function seek($offset = 0, $curr = true, $char = false)
    {
        if (!$offset) {
            return (bool)$curr ?: $this->rewind();
        }

        if ($offset < 0) {
            if (!$curr) {
                return true;
            } elseif (abs($offset) > $this->pos()) {
                return $this->rewind();
            }
        }

        if ($char && $this->_utf8_char) {
            if ($offset > 0) {
                if (!$curr) {
                    $this->rewind();
                }

                do {
                    $this->getChar();
                } while (--$offset);
            } else {
                $pos = $this->pos();
                $offset = abs($offset);

                while ($pos-- && $offset) {
                    fseek($this->stream, -1, SEEK_CUR);
                    if ((ord($this->peek()) & 0xC0) != 0x80) {
                        --$offset;
                    }
                }
            }

            return true;
        }

        return (fseek($this->stream, $offset, $curr ? SEEK_CUR : SEEK_SET) === 0);
    }