Ejemplo n.º 1
0
        /// <summary>
        /// Given that the next character is an ampersand ('&amp;'), attempt to interpret the
        /// following characters as an XML entity.  On success, populate the out parameters
        /// with the low and high UTF-16 surrogates for the character represented by the
        /// entity.
        /// </summary>
        /// <param name="ch">e.g. '&lt;' for &amp;lt;.</param>
        /// <param name="surrogate">e.g. '\uDC00' for &amp;#x10000; (ch == '\uD800').</param>
        /// <returns>True if a valid XML entity was consumed.</returns>
        /// <remarks>
        /// NOTE: Always advances, even on failure.
        /// </remarks>
        public bool TryScanXmlEntity(out char ch, out char surrogate)
        {
            Debug.Assert(this.PeekChar() == '&');

            ch = '&';
            this.AdvanceChar();

            surrogate = InvalidCharacter;

            switch (this.PeekChar())
            {
            case 'l':
                if (AdvanceIfMatches("lt;"))
                {
                    ch = '<';
                    return(true);
                }
                break;

            case 'g':
                if (AdvanceIfMatches("gt;"))
                {
                    ch = '>';
                    return(true);
                }
                break;

            case 'a':
                if (AdvanceIfMatches("amp;"))
                {
                    ch = '&';
                    return(true);
                }
                else if (AdvanceIfMatches("apos;"))
                {
                    ch = '\'';
                    return(true);
                }
                break;

            case 'q':
                if (AdvanceIfMatches("quot;"))
                {
                    ch = '"';
                    return(true);
                }
                break;

            case '#':
            {
                this.AdvanceChar();                                 //#

                uint uintChar = 0;

                if (AdvanceIfMatches("x"))
                {
                    char digit;
                    while (SyntaxKindFacts.IsHexDigit(digit = this.PeekChar()))
                    {
                        this.AdvanceChar();

                        // disallow overflow
                        if (uintChar <= 0x7FFFFFF)
                        {
                            uintChar = (uintChar << 4) + (uint)SyntaxKindFacts.HexValue(digit);
                        }
                        else
                        {
                            return(false);
                        }
                    }
                }
                else
                {
                    char digit;
                    while (SyntaxKindFacts.IsDecDigit(digit = this.PeekChar()))
                    {
                        this.AdvanceChar();

                        // disallow overflow
                        if (uintChar <= 0x7FFFFFF)
                        {
                            uintChar = (uintChar << 3) + (uintChar << 1) + (uint)SyntaxKindFacts.DecValue(digit);
                        }
                        else
                        {
                            return(false);
                        }
                    }
                }

                if (AdvanceIfMatches(";"))
                {
                    ch = GetCharsFromUtf32(uintChar, out surrogate);
                    return(true);
                }

                break;
            }
            }

            return(false);
        }