Returns next char (maybe multibyte) or false if end is reached,
@returns string|bool
517917
function ReadChar()
    {
        if ($this->IsAtEnd())
            return false;
        
        $ch = $this->string{$this->idx};
        ++$this->idx;
        if ($ch >= $this->utf8Start && !$this->IsAtEnd())
        {
            $ch .= $this->string{$this->idx};
            ++$this->idx;
        }
        return $ch;
    }
1036127
protected function getChar()
    {
        // Check to see if we had anything in the look ahead buffer and use that.
        if (isset($this->c)) {
            $char = $this->c;
            unset($this->c);

        // Otherwise we start pulling from the input.
        } else {
            $char = substr($this->input, $this->index, 1);

            // If the next character doesn't exist return false.
            if (isset($char) && $char === false) {
                return false;
            }

            // Otherwise increment the pointer and use this char.
            $this->index++;
        }

        // Normalize all whitespace except for the newline character into a
        // standard space.
        if($char !== "\n" && ord($char) < 32)

            return ' ';

        return $char;
    }
570970
public function readString()
    {
        $strlen = $this->readVInt();
        if ($strlen == 0) {
            return '';
        } else {
            /**
             * This implementation supports only Basic Multilingual Plane
             * (BMP) characters (from 0x0000 to 0xFFFF) and doesn't support
             * "supplementary characters" (characters whose code points are
             * greater than 0xFFFF)
             * Java 2 represents these characters as a pair of char (16-bit)
             * values, the first from the high-surrogates range (0xD800-0xDBFF),
             * the second from the low-surrogates range (0xDC00-0xDFFF). Then
             * they are encoded as usual UTF-8 characters in six bytes.
             * Standard UTF-8 representation uses four bytes for supplementary
             * characters.
             */

            $str_val = substr($this->_data, $this->_position, $strlen);
            $this->_position += $strlen;

            for ($count = 0; $count < $strlen; $count++ ) {
                if (( ord($str_val[$count]) & 0xC0 ) == 0xC0) {
                    $addBytes = 1;
                    if (ord($str_val[$count]) & 0x20 ) {
                        $addBytes++;

                        // Never used. Java2 doesn't encode strings in four bytes
                        if (ord($str_val[$count]) & 0x10 ) {
                            $addBytes++;
                        }
                    }
                    $str_val .= substr($this->_data, $this->_position, $addBytes);
                    $this->_position += $addBytes;
                    $strlen          += $addBytes;

                    // Check for null character. Java2 encodes null character
                    // in two bytes.
                    if (ord($str_val[$count])   == 0xC0 
                        && ord($str_val[$count+1]) == 0x80   
                    ) {
                        $str_val[$count] = 0;
                        $str_val = substr($str_val, 0, $count+1)
                                 . substr($str_val, $count+2);
                    }
                    $count += $addBytes;
                }
            }

            return $str_val;
        }
    }
1328355
public function next()
    {
        if (!mb_strlen($this->input)) {
            return false;
        }

        foreach ($this->engine->getPatterns() as $pattern) {
            if ($token = $this->scan($pattern->regex, $pattern->type)) {
                if (in_array($pattern->type, $this->disallow)) {
                    throw new Exception($pattern->type . ' is disallowed.', 3);
                }

                return $token;
            }
        }

        throw new Exception('Unknow pattern found at: ' . mb_substr($this->input, 0, 100), 12);
    }
880116
public function getColumnOffset() {
        // strrpos is weird, and the offset needs to be negative for what we
        // want (i.e., the last \n before $this->char). This needs to not have
        // one (to make it point to the next character, the one we want the
        // position of) added to it because strrpos's behaviour includes the
        // final offset byte.
        $lastLine = strrpos($this->data, "\n", $this->char - 1 - strlen($this->data));

        // However, for here we want the length up until the next byte to be
        // processed, so add one to the current byte ($this->char).
        if ($lastLine !== false) {
            $findLengthOf = substr($this->data, $lastLine + 1, $this->char - 1 - $lastLine);
        } else {
            $findLengthOf = substr($this->data, 0, $this->char);
        }

        // Get the length for the string we need.
        if (extension_loaded('iconv')) {
            return iconv_strlen($findLengthOf, 'utf-8');
        } elseif (extension_loaded('mbstring')) {
            return mb_strlen($findLengthOf, 'utf-8');
        } elseif (extension_loaded('xml')) {
            return strlen(utf8_decode($findLengthOf));
        } else {
            $count = count_chars($findLengthOf);
            // 0x80 = 0x7F - 0 + 1 (one added to get inclusive range)
            // 0x33 = 0xF4 - 0x2C + 1 (one added to get inclusive range)
            return array_sum(array_slice($count, 0, 0x80)) +
                   array_sum(array_slice($count, 0xC2, 0x33));
        }
    }
990187
@Deprecated
    public char next()
    {
        if (pos < end - 1) {
            pos++;
            return text.charAt(pos);
        }
        else {
            pos = end;
            return DONE;
        }
    }
700929
public function getPrevChar()
	{
		if( $this->direction == ">" )
			$this->pointer--;
		if( $this->pointer <= $this->count() &&  $this->pointer > 0 )
		{
			$this->direction = "<";
			$this->pointer--;
			$character = $this->buffer[$this->pointer];
		}
		return $character;
	}
1226463
public function currentLine() {
        if (empty($this->EOF) || $this->char == 0) {
            return 1;
        }
        // Add one to $this->char because we want the number for the next
        // byte to be processed.
        return substr_count($this->data, "\n", 0, min($this->char, $this->EOF)) + 1;
    }
915111
public static function isMBString(): bool
    {
        static $isLoaded;

        if (null === $isLoaded) {
            $isLoaded = extension_loaded('mbstring');

            if ($isLoaded) {
                mb_internal_encoding(self::$encoding);
            }
        }

        return $isLoaded;
    }
682301
public static function getIsMbstringEnabled()
	{
		if (isset(self::$_isMbstringEnabled)) {
			return self::$_isMbstringEnabled;
		}

		self::$_isMbstringEnabled = function_exists('mb_convert_encoding') ?
			true : false;

		return self::$_isMbstringEnabled;
	}
360927
public function toUnicode()
  {
    $h = ord($this->char{0});

    if($h <= 0x7F)
    {
      return $h;
    }
    else if($h < 0xC2)
    {
      return FALSE;
    }
    else if($h <= 0xDF)
    {
      return ($h & 0x1F) << 6 | (ord($this->char{1}) & 0x3F);
    }
    else if($h <= 0xEF)
    {
      return ($h & 0x0F) << 12 | (ord($this->char{1}) & 0x3F) << 6 | (ord($this->char{2}) & 0x3F);
    }
    else if($h <= 0xF4)
    {
      return ($h & 0x0F) << 18 | (ord($this->char{1}) & 0x3F) << 12 | (ord($this->char{2}) & 0x3F) << 6 | (ord($this->char{3}) & 0x3F);
    }
    else
    {
      return FALSE;
    }
  }
1174362
public function peek() {
        if (($this->char + 1) <= $this->EOF) {
            return $this->data[$this->char + 1];
        }

        return false;
    }
1358580
public function getNext()
    {
        if ($this->currentToken !== null || strlen($this->currentInput) > 0) {
            $this->parseNextToken();

            return $this->currentToken;
        }

        return null;
    }
382668
function hasNext()
    {
        if (isset($this->_limit) && $this->offset >= $this->_limit)
        {
            return false;
        }
    
        if (!isset($this->data))
        {
            $this->loadNextPage();
        }

        if ($this->pos < sizeof($this->data))
        {
            return true;
        }

        if (!$this->truncated)
        {
            return false;            
        }
        
        $this->loadNextPage();
        return $this->pos < sizeof($this->data);        
    }
1059982
protected function _getNextCode()
    {
        if ($this->_bytePointer == $this->_dataLength) {
            return 257;
        }

        $this->_nextData = ($this->_nextData << 8) | (ord($this->_data[$this->_bytePointer++]) & 0xff);
        $this->_nextBits += 8;

        if ($this->_nextBits < $this->_bitsToGet) {
            $this->_nextData = ($this->_nextData << 8) | (ord($this->_data[$this->_bytePointer++]) & 0xff);
            $this->_nextBits += 8;
        }

        $code = ($this->_nextData >> ($this->_nextBits - $this->_bitsToGet)) & $this->_andTable[$this->_bitsToGet-9];
        $this->_nextBits -= $this->_bitsToGet;

        return $code;
    }
608331
public function getNextLine()
    {
        if ( $this->hasMoreMailData === false )
        {
            $this->nextMail();
        }
        // finished?
        if ( $this->fp == null || feof( $this->fp ) )
        {
            if ( $this->fp != null )
            {
                fclose( $this->fp );
                $this->fp = null;
            }
            return null;
        }

        // get one line
        $next = fgets( $this->fp );
        if ( $next == "" && feof( $this->fp ) )
        {
            return null;
        }
        return $next;
    }
704510
public function take(): string
    {
        if ($this->atEnd()) {
            $this->lastTaken = self::END;

            return self::END;
        }

        $char = $this->input[$this->index];

        $this->index += 1;

        $this->lastTaken = $char;

        return $char;
    }