src/Parser/Lexer.php
private function scanCodepoint(): string
    {
        $buffer = &$this->buffer;
        $offset = &$this->offset;

        $codepoint = $buffer[$offset++];
        $ord = \ord($codepoint);

        if (!($ord >> 7)) {
            return $codepoint;
        }

        if (!(($ord >> 5) ^ 0b110)) {
            $expect = 1;
        } elseif (!(($ord >> 4) ^ 0b1110)) {
            $expect = 2;
        } elseif (!(($ord >> 3) ^ 0b11110)) {
            $expect = 3;
        } else {
            $expect = 0; // This'll throw in just a moment.
        }

        $continuationBytes = "";
        do {
            $temp = \substr($buffer, $offset, $expect);
            $deltaLength = \strlen($temp);
            $expect -= $deltaLength;
            $continuationBytes .= $temp;
        } while ($expect > 0 && $this->refillBuffer());

        $offset += $deltaLength;

        for (
            $i = 0, $continuationBytesLength = \strlen($continuationBytes);
            $i < $continuationBytesLength;
            $i++
        ) {
            $byte = $continuationBytes[$i];

            if ((\ord($byte) >> 6) ^ 0b10) {
                break;
            }

            $codepoint .= $byte;
        }

        $chr = \IntlChar::chr($codepoint);

        if ($chr === null) {
            throw new ParseException($this->getIllFormedUtf8ExceptionMessage($codepoint));
        }

        return $chr;
    }
private function scanCodepoint(): string
    {
        $buffer = &$this->buffer;
        $offset = &$this->offset;

        $codepoint = $buffer[$offset++];
        $ord = \ord($codepoint);

        if (!($ord >> 7)) {
            return $codepoint;
        }

        if (!(($ord >> 5) ^ 0b110)) {
            $expect = 1;
        } elseif (!(($ord >> 4) ^ 0b1110)) {
            $expect = 2;
        } elseif (!(($ord >> 3) ^ 0b11110)) {
            $expect = 3;
        } else {
            $expect = 0; // This'll throw in just a moment.
        }

        $continuationBytes = "";
        do {
            $temp = \substr($buffer, $offset, $expect);
            $deltaLength = \strlen($temp);
            $expect -= $deltaLength;
            $continuationBytes .= $temp;
        } while ($expect > 0 && $this->refillBuffer());

        $offset += $deltaLength;

        for (
            $i = 0, $continuationBytesLength = \strlen($continuationBytes);
            $i < $continuationBytesLength;
            $i++
        ) {
            $byte = $continuationBytes[$i];

            if ((\ord($byte) >> 6) ^ 0b10) {
                break;
            }

            $codepoint .= $byte;
        }

        $chr = \IntlChar::chr($codepoint);

        if ($chr === null) {
            throw new ParseException($this->getIllFormedUtf8ExceptionMessage($codepoint));
        }

        return $chr;
    }
private function scanCodepoint ( ) : string { $ buffer = & $ this -> buffer ; $ offset = & $ this -> offset ; $ codepoint = $ buffer [ $ offset ++ ] ; $ ord = \ ord ( $ codepoint ) ; if ( ! ( $ ord >> 7 ) ) { return $ codepoint ; } if ( ! ( ( $ ord >> 5 ) ^ 0b110 ) ) { $ expect = 1 ; } elseif ( ! ( ( $ ord >> 4 ) ^ 0b1110 ) ) { $ expect = 2 ; } elseif ( ! ( ( $ ord >> 3 ) ^ 0b11110 ) ) { $ expect = 3 ; } else { $ expect = 0 ; // This'll throw in just a moment. } $ continuationBytes = "" ; do { $ temp = \ substr ( $ buffer , $ offset , $ expect ) ; $ deltaLength = \ strlen ( $ temp ) ; $ expect -= $ deltaLength ; $ continuationBytes .= $ temp ; } while ( $ expect > 0 && $ this -> refillBuffer ( ) ) ; $ offset += $ deltaLength ; for ( $ i = 0 , $ continuationBytesLength = \ strlen ( $ continuationBytes ) ; $ i < $ continuationBytesLength ; $ i ++ ) { $ byte = $ continuationBytes [ $ i ] ; if ( ( \ ord ( $ byte ) >> 6 ) ^ 0b10 ) { break ; } $ codepoint .= $ byte ; } $ chr = \ IntlChar :: chr ( $ codepoint ) ; if ( $ chr === null ) { throw new ParseException ( $ this -> getIllFormedUtf8ExceptionMessage ( $ codepoint ) ) ; } return $ chr ; }
Scans a single UTF-8 encoded Unicode codepoint, which can be up to four
bytes long.

0xxx xxxx   Single-byte codepoint.
110x xxxx   First of a two-byte codepoint.
1110 xxxx   First of three.
1111 0xxx   First of four.
10xx xxxx   A continuation of any of the three preceding.

@see https://en.wikipedia.org/wiki/UTF-8#Description
@see http://www.unicode.org/versions/Unicode9.0.0/ch03.pdf#page=54

@throws ParseException on ill-formed UTF-8.
Scans a single UTF - 8 encoded Unicode codepoint which can be up to four bytes long .