protected int handleEntityInText()

in sdk/serialization/azure-xml/src/main/java/com/azure/xml/implementation/aalto/in/Utf8Scanner.java [490:660]


    protected int handleEntityInText() throws XMLStreamException {
        if (_inputPtr >= _inputEnd) {
            loadMoreGuaranteed();
        }
        byte b = _inputBuffer[_inputPtr++];
        if (b == BYTE_HASH) {
            return handleCharEntity();
        }
        String start;
        if (b == BYTE_a) { // amp or apos?
            b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
            if (b == BYTE_m) { // amp?
                b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
                if (b == BYTE_p) {
                    b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
                    if (b == BYTE_SEMICOLON) {
                        return INT_AMP;
                    }
                    start = "amp";
                } else {
                    start = "am";
                }
            } else if (b == BYTE_p) { // apos?
                b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
                if (b == BYTE_o) {
                    b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
                    if (b == BYTE_s) {
                        b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
                        if (b == BYTE_SEMICOLON) {
                            return INT_APOS;
                        }
                        start = "apos";
                    } else {
                        start = "apo";
                    }
                } else {
                    start = "ap";
                }
            } else {
                start = "a";
            }
        } else if (b == BYTE_l) { // lt?
            b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
            if (b == BYTE_t) {
                b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
                if (b == BYTE_SEMICOLON) {
                    return INT_LT;
                }
                start = "lt";
            } else {
                start = "l";
            }
        } else if (b == BYTE_g) { // gt?
            b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
            if (b == BYTE_t) {
                b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
                if (b == BYTE_SEMICOLON) {
                    return INT_GT;
                }
                start = "gt";
            } else {
                start = "g";
            }
        } else if (b == BYTE_q) { // quot?
            b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
            if (b == BYTE_u) {
                b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
                if (b == BYTE_o) {
                    b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
                    if (b == BYTE_t) {
                        b = (_inputPtr < _inputEnd) ? _inputBuffer[_inputPtr++] : loadOne();
                        if (b == BYTE_SEMICOLON) {
                            return INT_QUOTE;
                        }
                        start = "quot";
                    } else {
                        start = "quo";
                    }
                } else {
                    start = "qu";
                }
            } else {
                start = "q";
            }
        } else {
            start = "";
        }

        final int[] TYPES = _charTypes.NAME_CHARS;

        /* All righty: we have the beginning of the name, plus the first
         * byte too. So let's see what we can do with it.
         */
        char[] cbuf = _nameBuffer;
        int cix = 0;
        for (int len = start.length(); cix < len; ++cix) {
            cbuf[cix] = start.charAt(cix);
        }
        //int colon = -1;
        while (b != BYTE_SEMICOLON) {
            boolean ok;
            int c = (int) b & 0xFF;

            // Has to be a valid name start char though:
            switch (TYPES[c]) {
                case XmlCharTypes.CT_NAME_NONE:
                case XmlCharTypes.CT_NAME_COLON: // not ok for entities?
                case XmlCharTypes.CT_NAME_NONFIRST:
                    ok = (cix > 0);
                    break;

                case XmlCharTypes.CT_NAME_ANY:
                    ok = true;
                    break;

                case InputCharTypes.CT_INPUT_NAME_MB_2:
                    c = decodeUtf8_2(c);
                    ok = XmlChars.is10NameStartChar(c);
                    break;

                case InputCharTypes.CT_INPUT_NAME_MB_3:
                    c = decodeUtf8_3(c);
                    ok = XmlChars.is10NameStartChar(c);
                    break;

                case InputCharTypes.CT_INPUT_NAME_MB_4:
                    c = decodeUtf8_4(c);
                    ok = XmlChars.is10NameStartChar(c);
                    if (ok) {
                        if (cix >= cbuf.length) {
                            _nameBuffer = cbuf = DataUtil.growArrayBy(cbuf, cbuf.length);
                        }
                        // Let's add first part right away:
                        c -= 0x10000;
                        cbuf[cix++] = (char) (0xD800 | (c >> 10));
                        c = 0xDC00 | (c & 0x3FF);
                    }
                    break;

                case InputCharTypes.CT_INPUT_NAME_MB_N:
                default:
                    ok = false;
                    break;
            }
            if (!ok) {
                reportInvalidNameChar(c, cix);
            }
            if (cix >= cbuf.length) {
                _nameBuffer = cbuf = DataUtil.growArrayBy(cbuf, cbuf.length);
            }
            cbuf[cix++] = (char) c;
            if (_inputPtr >= _inputEnd) {
                loadMoreGuaranteed();
            }
            b = _inputBuffer[_inputPtr++];
        }

        // Ok, let's construct a (temporary) entity name, then:
        String pname = new String(cbuf, 0, cix);
        // (note: hash is dummy... not to be compared to anything etc)
        _tokenName = new PNameC(pname, null, pname, 0);

        /* One more thing: do we actually allow entities in this mode
         * and with this event?
         */
        if (_config.willExpandEntities()) {
            reportInputProblem("General entity reference (&" + pname
                + ";) encountered in entity expanding mode: operation not (yet) implemented");
        }
        return 0;
    }