System.Xml.XmlTextReaderImpl.ParseAttributes C# (CSharp) Méthode

ParseAttributes() private méthode

private ParseAttributes ( ) : void
Résultat void
        private void ParseAttributes()
        {
            int pos = _ps.charPos;
            char[] chars = _ps.chars;
            NodeData attr = null;

            Debug.Assert(_attrCount == 0);

            for (;;)
            {
                // eat whitespaces
                int lineNoDelta = 0;
                char tmpch0;
                unsafe
                {
                    while (_xmlCharType.IsWhiteSpace(tmpch0 = chars[pos]))
                    {
                        if (tmpch0 == (char)0xA)
                        {
                            OnNewLine(pos + 1);
                            lineNoDelta++;
                        }
                        else if (tmpch0 == (char)0xD)
                        {
                            if (chars[pos + 1] == (char)0xA)
                            {
                                OnNewLine(pos + 2);
                                lineNoDelta++;
                                pos++;
                            }
                            else if (pos + 1 != _ps.charsUsed)
                            {
                                OnNewLine(pos + 1);
                                lineNoDelta++;
                            }
                            else
                            {
                                _ps.charPos = pos;
                                goto ReadData;
                            }
                        }
                        pos++;
                    }
                }

                char tmpch1;
                int startNameCharSize = 0;

                unsafe
                {
                    if (_xmlCharType.IsStartNCNameSingleChar(tmpch1 = chars[pos]))
                    {
                        startNameCharSize = 1;
                    }
#if XML10_FIFTH_EDITION
                    else if (pos + 1 < ps.charsUsed && xmlCharType.IsNCNameSurrogateChar(chars[pos + 1], tmpch1))
                    {
                        startNameCharSize = 2;
                    }
#endif
                }

                if (startNameCharSize == 0)
                {
                    // element end
                    if (tmpch1 == '>')
                    {
                        Debug.Assert(_curNode.type == XmlNodeType.Element);
                        _ps.charPos = pos + 1;
                        _parsingFunction = ParsingFunction.MoveToElementContent;
                        goto End;
                    }
                    // empty element end
                    else if (tmpch1 == '/')
                    {
                        Debug.Assert(_curNode.type == XmlNodeType.Element);
                        if (pos + 1 == _ps.charsUsed)
                        {
                            goto ReadData;
                        }
                        if (chars[pos + 1] == '>')
                        {
                            _ps.charPos = pos + 2;
                            _curNode.IsEmptyElement = true;
                            _nextParsingFunction = _parsingFunction;
                            _parsingFunction = ParsingFunction.PopEmptyElementContext;
                            goto End;
                        }
                        else
                        {
                            ThrowUnexpectedToken(pos + 1, ">");
                        }
                    }
                    else if (pos == _ps.charsUsed)
                    {
                        goto ReadData;
                    }
                    else if (tmpch1 != ':' || _supportNamespaces)
                    {
                        Throw(pos, SR.Xml_BadStartNameChar, XmlException.BuildCharExceptionArgs(chars, _ps.charsUsed, pos));
                    }
                }

                if (pos == _ps.charPos)
                {
                    ThrowExpectingWhitespace(pos);
                }
                _ps.charPos = pos;

                // save attribute name line position
                int attrNameLinePos = _ps.LinePos;

#if DEBUG
                int attrNameLineNo = _ps.LineNo;
#endif

                // parse attribute name
                int colonPos = -1;

                // PERF: we intentionally don't call ParseQName here to parse the element name unless a special 
                // case occurs (like end of buffer, invalid name char)
                pos += startNameCharSize; // start name char has already been checked

            // parse attribute name
            ContinueParseName:
                char tmpch2;

                unsafe
                {
                    for (;;)
                    {
                        if (_xmlCharType.IsNCNameSingleChar(tmpch2 = chars[pos]))
                        {
                            pos++;
                        }
#if XML10_FIFTH_EDITION
                        else if (pos + 1 < ps.charsUsed && xmlCharType.IsNCNameSurrogateChar(chars[pos + 1], tmpch2))
                        {
                            pos += 2;
                        }
#endif
                        else
                        {
                            break;
                        }
                    }
                }

                // colon -> save prefix end position and check next char if it's name start char
                if (tmpch2 == ':')
                {
                    if (colonPos != -1)
                    {
                        if (_supportNamespaces)
                        {
                            Throw(pos, SR.Xml_BadNameChar, XmlException.BuildCharExceptionArgs(':', '\0'));
                        }
                        else
                        {
                            pos++;
                            goto ContinueParseName;
                        }
                    }
                    else
                    {
                        colonPos = pos;
                        pos++;

                        unsafe
                        {
                            if (_xmlCharType.IsStartNCNameSingleChar(chars[pos]))
                            {
                                pos++;
                                goto ContinueParseName;
                            }
#if XML10_FIFTH_EDITION
                            else if ( pos + 1 < ps.charsUsed && xmlCharType.IsNCNameSurrogateChar( chars[pos + 1], chars[pos] ) ) {
                                pos += 2;
                                goto ContinueParseName;
                            }
#endif
                        }
                        // else fallback to full name parsing routine
                        pos = ParseQName(out colonPos);
                        chars = _ps.chars;
                    }
                }
                else if (pos + 1 >= _ps.charsUsed)
                {
                    pos = ParseQName(out colonPos);
                    chars = _ps.chars;
                }

                attr = AddAttribute(pos, colonPos);
                attr.SetLineInfo(_ps.LineNo, attrNameLinePos);

#if DEBUG
                Debug.Assert(attrNameLineNo == _ps.LineNo);
#endif

                // parse equals and quote char; 
                if (chars[pos] != '=')
                {
                    _ps.charPos = pos;
                    EatWhitespaces(null);
                    pos = _ps.charPos;
                    if (chars[pos] != '=')
                    {
                        ThrowUnexpectedToken("=");
                    }
                }
                pos++;

                char quoteChar = chars[pos];
                if (quoteChar != '"' && quoteChar != '\'')
                {
                    _ps.charPos = pos;
                    EatWhitespaces(null);
                    pos = _ps.charPos;
                    quoteChar = chars[pos];
                    if (quoteChar != '"' && quoteChar != '\'')
                    {
                        ThrowUnexpectedToken("\"", "'");
                    }
                }
                pos++;
                _ps.charPos = pos;

                attr.quoteChar = quoteChar;
                attr.SetLineInfo2(_ps.LineNo, _ps.LinePos);

                // parse attribute value
                char tmpch3;
                unsafe
                {
                    while (_xmlCharType.IsAttributeValueChar(tmpch3 = chars[pos]))
                    {
                        pos++;
                    }
                }
                if (tmpch3 == quoteChar)
                {
#if DEBUG
                    if (normalize)
                    {
                        string val = new string(chars, ps.charPos, pos - ps.charPos);
                        Debug.Assert(val == XmlComplianceUtil.CDataNormalize(val), "The attribute value is not CDATA normalized!"); 
                    }
#endif
                    attr.SetValue(chars, _ps.charPos, pos - _ps.charPos);
                    pos++;
                    _ps.charPos = pos;
                }
                else
                {
                    ParseAttributeValueSlow(pos, quoteChar, attr);
                    pos = _ps.charPos;
                    chars = _ps.chars;
                }

                // handle special attributes:
                if (attr.prefix.Length == 0)
                {
                    // default namespace declaration
                    if (Ref.Equal(attr.localName, _xmlNs))
                    {
                        OnDefaultNamespaceDecl(attr);
                    }
                }
                else
                {
                    // prefixed namespace declaration
                    if (Ref.Equal(attr.prefix, _xmlNs))
                    {
                        OnNamespaceDecl(attr);
                    }
                    // xml: attribute
                    else if (Ref.Equal(attr.prefix, _xml))
                    {
                        OnXmlReservedAttribute(attr);
                    }
                }
                continue;

            ReadData:
                _ps.lineNo -= lineNoDelta;
                if (ReadData() != 0)
                {
                    pos = _ps.charPos;
                    chars = _ps.chars;
                }
                else
                {
                    ThrowUnclosedElements();
                }
            }

        End:
            if (_addDefaultAttributesAndNormalize)
            {
                AddDefaultAttributesAndNormalize();
            }
            // lookup namespaces: element
            ElementNamespaceLookup();

            // lookup namespaces: attributes
            if (_attrNeedNamespaceLookup)
            {
                AttributeNamespaceLookup();
                _attrNeedNamespaceLookup = false;
            }

            // check duplicate attributes
            if (_attrDuplWalkCount >= MaxAttrDuplWalkCount)
            {
                AttributeDuplCheck();
            }
        }
XmlTextReaderImpl