private static boolean scanExpr()

in src/main/java/org/apache/maven/xinclude/stax/XPointerParser.java [333:494]


        private static boolean scanExpr(Tokens tokens, String data, int currentOffset, int endOffset)
                throws InvalidXPointerException {
            int ch;
            int openParen = 0;
            int closeParen = 0;
            int nameOffset, dataOffset;
            String name = null;
            String prefix;
            String schemeData;
            StringBuffer schemeDataBuff = new StringBuffer();

            while (true) {

                if (currentOffset == endOffset) {
                    break;
                }
                ch = data.charAt(currentOffset);

                //
                while (ch == ' ' || ch == 0x0A || ch == 0x09 || ch == 0x0D) {
                    if (++currentOffset == endOffset) {
                        break;
                    }
                    ch = data.charAt(currentOffset);
                }
                if (currentOffset == endOffset) {
                    break;
                }

                //
                // [1]    Pointer      ::=    Shorthand | SchemeBased
                // [2]    Shorthand    ::=    NCName
                // [3]    SchemeBased  ::=    PointerPart (S? PointerPart)*
                // [4]    PointerPart  ::=    SchemeName '(' SchemeData ')'
                // [5]    SchemeName   ::=    QName
                // [6]    SchemeData   ::=    EscapedData*
                // [7]    EscapedData  ::=    NormalChar | '^(' | '^)' | '^^' | '(' SchemeData ')'
                // [8]    NormalChar   ::=    UnicodeChar - [()^]
                // [9]    UnicodeChar  ::=    [#x0-#x10FFFF]
                // [?]    QName        ::=    (NCName ':')? NCName
                // [?]    NCName       ::=    (Letter | '_') (NCNameChar)*
                // [?]    NCNameChar   ::=    Letter | Digit | '.' | '-' | '_'  (ascii subset of 'NCNameChar')
                // [?]    Letter       ::=    [A-Za-z]                              (ascii subset of 'Letter')
                // [?]    Digit        ::=    [0-9]                                  (ascii subset of 'Digit')
                //
                byte chartype = (ch >= 0x80) ? CHARTYPE_NONASCII : ASCII_CHAR_MAP[ch];

                switch (chartype) {
                    case CHARTYPE_OPEN_PAREN: // '('
                        addToken(tokens, Tokens.XPTRTOKEN_OPEN_PAREN);
                        openParen++;
                        ++currentOffset;
                        break;

                    case CHARTYPE_CLOSE_PAREN: // ')'
                        addToken(tokens, Tokens.XPTRTOKEN_CLOSE_PAREN);
                        closeParen++;
                        ++currentOffset;
                        break;

                    case CHARTYPE_CARRET:
                    case CHARTYPE_COLON:
                    case CHARTYPE_DIGIT:
                    case CHARTYPE_EQUAL:
                    case CHARTYPE_LETTER:
                    case CHARTYPE_MINUS:
                    case CHARTYPE_NONASCII:
                    case CHARTYPE_OTHER:
                    case CHARTYPE_PERIOD:
                    case CHARTYPE_SLASH:
                    case CHARTYPE_UNDERSCORE:
                    case CHARTYPE_WHITESPACE:
                        // Scanning SchemeName | Shorthand
                        if (openParen == 0) {
                            nameOffset = currentOffset;
                            currentOffset = scanNCName(data, endOffset, currentOffset);

                            if (currentOffset == nameOffset) {
                                throw new InvalidXPointerException("InvalidShortHandPointer", data);
                            }

                            if (currentOffset < endOffset) {
                                ch = data.charAt(currentOffset);
                            } else {
                                ch = -1;
                            }

                            name = data.substring(nameOffset, currentOffset).intern();
                            prefix = "";

                            // The name is a QName => a SchemeName
                            if (ch == ':') {
                                if (++currentOffset == endOffset) {
                                    return false;
                                }

                                ch = data.charAt(currentOffset);
                                prefix = name;
                                nameOffset = currentOffset;
                                currentOffset = scanNCName(data, endOffset, currentOffset);

                                if (currentOffset == nameOffset) {
                                    return false;
                                }

                                if (currentOffset < endOffset) {
                                    ch = data.charAt(currentOffset);
                                } else {
                                    ch = -1;
                                }

                                name = data.substring(nameOffset, currentOffset).intern();
                            }

                            // REVISIT:
                            if (currentOffset != endOffset) {
                                addToken(tokens, Tokens.XPTRTOKEN_SCHEMENAME);
                                tokens.addToken(prefix);
                                tokens.addToken(name);
                            } else {
                                // NCName => Shorthand
                                addToken(tokens, Tokens.XPTRTOKEN_SHORTHAND);
                                tokens.addToken(name);
                            }

                            // reset open/close paren for the next pointer part
                            closeParen = 0;

                            break;

                        } else if (openParen > 0 && closeParen == 0 && name != null) {
                            // Scanning SchemeData
                            dataOffset = currentOffset;
                            currentOffset = scanData(data, schemeDataBuff, endOffset, currentOffset);

                            if (currentOffset == dataOffset) {
                                throw new InvalidXPointerException("InvalidSchemeDataInXPointer", data);
                            }

                            if (currentOffset < endOffset) {
                                ch = data.charAt(currentOffset);
                            } else {
                                ch = -1;
                            }

                            schemeData = schemeDataBuff.toString().intern();
                            addToken(tokens, Tokens.XPTRTOKEN_SCHEMEDATA);
                            tokens.addToken(schemeData);

                            // reset open/close paren for the next pointer part
                            openParen = 0;
                            schemeDataBuff.delete(0, schemeDataBuff.length());

                        } else {
                            // ex. schemeName()
                            // Should we throw an exception with a more suitable message instead??
                            return false;
                        }
                }
            } // end while
            return true;
        }