예제 #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);
        }
예제 #2
0
        private char ScanUnicodeEscape(bool peek, out char surrogateCharacter, out SyntaxDiagnosticInfo info)
        {
            surrogateCharacter = InvalidCharacter;
            info = null;

            int  start     = this.Position;
            char character = this.PeekChar();

            Debug.Assert(character == '\\');
            this.AdvanceChar();

            character = this.PeekChar();
            if (character == 'U')
            {
                uint uintChar = 0;

                this.AdvanceChar();
                if (!SyntaxKindFacts.IsHexDigit(this.PeekChar()))
                {
                    if (!peek)
                    {
                        info = CreateIllegalEscapeDiagnostic(start);
                    }
                }
                else
                {
                    for (int i = 0; i < 8; i++)
                    {
                        character = this.PeekChar();
                        if (!SyntaxKindFacts.IsHexDigit(character))
                        {
                            if (!peek)
                            {
                                info = CreateIllegalEscapeDiagnostic(start);
                            }

                            break;
                        }

                        uintChar = (uint)((uintChar << 4) + SyntaxKindFacts.HexValue(character));
                        this.AdvanceChar();
                    }

                    if (uintChar > 0x0010FFFF)
                    {
                        if (!peek)
                        {
                            info = CreateIllegalEscapeDiagnostic(start);
                        }
                    }
                    else
                    {
                        character = GetCharsFromUtf32(uintChar, out surrogateCharacter);
                    }
                }
            }
            else if (character == 'u' || character == 'x')
            {
                Debug.Assert(character == 'u' || character == 'x');

                int intChar = 0;
                this.AdvanceChar();
                if (!SyntaxKindFacts.IsHexDigit(this.PeekChar()))
                {
                    if (!peek)
                    {
                        info = CreateIllegalEscapeDiagnostic(start);
                    }
                }
                else
                {
                    for (int i = 0; i < 4; i++)
                    {
                        char ch2 = this.PeekChar();
                        if (!SyntaxKindFacts.IsHexDigit(ch2))
                        {
                            if (character == 'u')
                            {
                                if (!peek)
                                {
                                    info = CreateIllegalEscapeDiagnostic(start);
                                }
                            }

                            break;
                        }

                        intChar = (intChar << 4) + SyntaxKindFacts.HexValue(ch2);
                        this.AdvanceChar();
                    }

                    character = (char)intChar;
                }
            }
            else             //Octal
            {
                Debug.Assert(SyntaxKindFacts.IsOctalDigit(character));

                List <char> chars   = new List <char>();
                int         intChar = 0;

                chars.Add(character);
                intChar = Convert.ToInt32(new string(chars.ToArray()), 8);


                this.AdvanceChar();
                character = this.PeekChar();                // 第二个
                if (SyntaxKindFacts.IsOctalDigit(character))
                {
                    chars.Add(character);
                    intChar = Convert.ToInt32(new string(chars.ToArray()), 8);

                    this.AdvanceChar();
                    character = this.PeekChar();                     //第三个
                    if (SyntaxKindFacts.IsOctalDigit(character))
                    {
                        if (SyntaxKindFacts.IsZeroToThreeDigit(chars[0]))
                        {
                            chars.Add(character);
                            intChar = Convert.ToInt32(new string(chars.ToArray()), 8);
                            this.AdvanceChar();
                        }
                        else
                        {
                            if (!peek)
                            {
                                info = CreateIllegalEscapeDiagnostic(start);
                            }
                        }
                    }
                }

                character = (char)intChar;
                //else
                //{
                //	for (int i = 0; i < 2; i++)
                //	{
                //		char ch2 = this.PeekChar();
                //		if (!SyntaxKindFacts.IsOctalDigit(ch2))
                //		{
                //			if (character == 'u')
                //			{
                //				if (!peek)
                //				{
                //					info = CreateIllegalEscapeDiagnostic(start);
                //				}
                //			}

                //			break;
                //		}

                //		intChar = (intChar << 4) + SyntaxKindFacts.HexValue(ch2);
                //		this.AdvanceChar();
                //	}

                //	character = (char)intChar;
                //}
            }

            return(character);
        }