protected override bool ReadAtFeedStartImplementation() { if ((this.atomEntryAndFeedDeserializer.XmlReader.NodeType == XmlNodeType.EndElement) || this.CurrentFeedState.FeedElementEmpty) { IODataAtomReaderFeedState currentFeedState = this.CurrentFeedState; ODataFeed currentFeed = base.CurrentFeed; if (this.atomInputContext.MessageReaderSettings.EnableAtomMetadataReading) { currentFeed.SetAnnotation <AtomFeedMetadata>(currentFeedState.AtomFeedMetadata); } this.ReplaceScope(ODataReaderState.FeedEnd); } else { this.ReadEntryStart(); } return(true); }
/// <summary> /// Reads the content of a feed (child nodes of the atom:feed). /// </summary> /// <param name="feedState">The reader feed state for the feed being read.</param> /// <param name="isExpandedLinkContent">true if the feed is inside an expanded link.</param> /// <returns>true if an entry was found or false if no more entries were found in the feed.</returns> /// <remarks> /// Pre-Condition: Anything but Attribute - the child node of the atom:feed element, can be pretty much anything, the method will skip over insignificant nodes and text nodes if found. /// Post-Condition: XmlNodeType.EndElement atom:feed - The end of the atom:feed element if no entry was found and the end of the feed was reached. /// XmlNodeType.Element atom:entry - The start tag of the atom:entry element representing an entry in the feed. /// </remarks> internal bool ReadFeedContent(IODataAtomReaderFeedState feedState, bool isExpandedLinkContent) { Debug.Assert(feedState != null, "feedState != null"); this.XmlReader.AssertNotBuffering(); Debug.Assert(this.XmlReader.NodeType != XmlNodeType.Attribute, "The reader must be positioned on a child node of the atom:feed element."); bool entryFound = false; while (this.XmlReader.NodeType != XmlNodeType.EndElement) { if (this.XmlReader.NodeType != XmlNodeType.Element) { Debug.Assert(this.XmlReader.NodeType != XmlNodeType.EndElement, "EndElement should have been handled already."); // Skip everything but elements, including insignificant nodes, text nodes and CDATA nodes this.XmlReader.Skip(); continue; } if (this.XmlReader.NamespaceEquals(this.AtomNamespace)) { if (this.ReadAtomElementInFeed(feedState, isExpandedLinkContent)) { // We've found an entry - return. entryFound = true; break; } } else if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataMetadataNamespace)) { AtomInstanceAnnotation annotation; // We should not read the m:count element in request payloads. if (this.ReadingResponse && !isExpandedLinkContent && this.XmlReader.LocalNameEquals(this.ODataCountElementName)) { // m:count // The default behavior is to disallow duplicates of feed/m:count element defined in ODATA spec. this.ValidateDuplicateElement(feedState.HasCount); // Note that we allow negative values to be read. long countValue = (long)AtomValueUtils.ReadPrimitiveValue(this.XmlReader, EdmCoreModel.Instance.GetInt64(true)); feedState.Feed.Count = countValue; // Read over the end element or the empty start element. this.XmlReader.Read(); feedState.HasCount = true; } else if (this.atomAnnotationReader.TryReadAnnotation(out annotation)) { // Note: There is some uncertainty over whether annotations on an expanded feed should appear on the ODataNavigationLink, the ODataFeed, or both. // In the short term, we are failing when we encounter this scenario so that we can enable it later without causing a breaking change. if (isExpandedLinkContent) { throw new ODataException(ODataErrorStrings.ODataAtomEntryAndFeedDeserializer_EncounteredAnnotationInNestedFeed); } // An annotation occurring as a direct child of a feed element can only target the feed it was found in. // If we find an annotation breaking this rule, fail. if (annotation.IsTargetingCurrentElement) { feedState.Feed.InstanceAnnotations.Add(new ODataInstanceAnnotation(annotation.TermName, annotation.Value)); } else { throw new ODataException(ODataErrorStrings.ODataAtomEntryAndFeedDeserializer_AnnotationWithNonDotTarget(annotation.Target, annotation.TermName)); } } else { // Any other element in the m namespace is to be ignored. this.XmlReader.Skip(); } } else { // non-ATOM elements, ignore them this.XmlReader.Skip(); } } Debug.Assert( this.XmlReader.NodeType != XmlNodeType.EndElement || (this.XmlReader.NamespaceURI == AtomConstants.AtomNamespace && this.XmlReader.LocalName == AtomConstants.AtomFeedElementName), "EndElement found but for element other than atom:feed."); Debug.Assert( this.XmlReader.NodeType != XmlNodeType.Element || (this.XmlReader.NamespaceURI == AtomConstants.AtomNamespace && this.XmlReader.LocalName == AtomConstants.AtomEntryElementName), "Only atom:entry elements can be reported as entries."); this.AssertXmlCondition(XmlNodeType.Element, XmlNodeType.EndElement); this.XmlReader.AssertNotBuffering(); return entryFound; }
/// <summary> /// Reads the atom:link element with one of the standard relation values in the atom:feed element. /// </summary> /// <param name="feedState">The reader feed state for the feed being read.</param> /// <param name="linkRelation">The rel attribute value for the link.</param> /// <param name="linkHRef">The href attribute value for the link (or null if the href attribute was not present).</param> /// <param name="isExpandedLinkContent">true if the feed is inside an expanded link.</param> /// <returns>If the rel was one of the recognized standard relations and this method read the link /// the return value is true. Otherwise the method doesn't move the reader and returns false.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element atom:link - The atom:link element to read. /// Post-Condition: Any - The node after the atom:link element if the link was read by this method. /// XmlNodeType.Element atom:link - The atom:link element to read if the link was not read by this method. /// </remarks> private bool ReadAtomStandardRelationLinkInFeed(IODataAtomReaderFeedState feedState, string linkRelation, string linkHRef, bool isExpandedLinkContent) { Debug.Assert(feedState != null, "feedState != null"); Debug.Assert(linkRelation != null, "linkRelation != null"); this.XmlReader.AssertNotBuffering(); this.AssertXmlCondition(XmlNodeType.Element); Debug.Assert( this.XmlReader.NamespaceURI == AtomConstants.AtomNamespace && this.XmlReader.LocalName == AtomConstants.AtomLinkElementName, "The XML reader must be on the atom:link element for this method to work."); if (string.CompareOrdinal(linkRelation, AtomConstants.AtomNextRelationAttributeValue) == 0) { // We should not read the next link in feed in request payloads. // WCF DS V2 Server ignores next link on a feed, since it's always request we also ignore it here. // Reader versioning: next link should be recognized only in >=V2 payloads. if (!this.ReadingResponse) { // Return false which means the rel for the link was not recognized and it will be read as any other link. return false; } // The default behavior is to disallow duplicates of feed/link[@rel='next'] element defined in ODATA spec. // We only target valid duplicates. We will not throw if there are duplicates with nonexistant href (client treats empty href as a valid relative URI). // WCF DS client behavior does not allow duplicate feed/link[@rel='next'] elements. WCF DS server never reads next link on responses. if (feedState.HasNextPageLink) { throw new ODataException(ODataErrorStrings.ODataAtomEntryAndFeedDeserializer_MultipleLinksInFeed(AtomConstants.AtomNextRelationAttributeValue)); } // next link // [Client-ODataLib-Integration] Astoria client handling of next link of feed. // We decided to keep the behavior consistent with other links, which means ignore empty and nonexistant href. We decided to relax the client behavior // since V2 and allow missing href (we will ignore the link then) and also allow empty hread and treat that as a valid relative URL (client already did that). if (linkHRef != null) { feedState.Feed.NextPageLink = this.ProcessUriFromPayload(linkHRef, this.XmlReader.XmlBaseUri); } feedState.HasNextPageLink = true; this.ReadLinkMetadataIfRequired(linkRelation, linkHRef, (linkMetadata) => { feedState.AtomFeedMetadata.NextPageLink = linkMetadata; }); return true; } if (string.CompareOrdinal(linkRelation, AtomConstants.AtomSelfRelationAttributeValue) == 0) { // The default behavior is to disallow duplicates of feed/link[@rel='self'] element defined in ODATA spec. // We only target valid duplicates. We will not throw if there are duplicates with nonexistant href (client treats empty href as a valid relative URI). if (feedState.HasReadLink && this.AtomInputContext.UseDefaultFormatBehavior) { throw new ODataException(ODataErrorStrings.ODataAtomEntryAndFeedDeserializer_MultipleLinksInFeed(AtomConstants.AtomSelfRelationAttributeValue)); } this.ReadLinkMetadataIfRequired(linkRelation, linkHRef, (linkMetadata) => { feedState.AtomFeedMetadata.SelfLink = linkMetadata; }); feedState.HasReadLink = true; return true; } if (string.CompareOrdinal(linkRelation, AtomConstants.AtomDeltaRelationAttributeValue) == 0) { if (!this.ReadingResponse) { // Return false which means the rel for the link was not recognized and it will be read as any other link. return false; } if (feedState.HasDeltaLink) { throw new ODataException(ODataErrorStrings.ODataAtomEntryAndFeedDeserializer_MultipleLinksInFeed(AtomConstants.AtomDeltaRelationAttributeValue)); } if (isExpandedLinkContent) { throw new ODataException(ODataErrorStrings.ODataAtomEntryAndFeedDeserializer_EncounteredDeltaLinkInNestedFeed); } if (linkHRef != null) { feedState.Feed.DeltaLink = this.ProcessUriFromPayload(linkHRef, this.XmlReader.XmlBaseUri); } this.ReadLinkMetadataIfRequired(linkRelation, linkHRef, (linkMetadata) => feedState.AtomFeedMetadata.AddLink(linkMetadata)); feedState.HasDeltaLink = true; return true; } return false; }
/// <summary> /// Reads an ATOM element inside the atom:feed from the input. /// </summary> /// <param name="feedState">The reader feed state for the feed being read.</param> /// <param name="isExpandedLinkContent">true if the feed is inside an expanded link.</param> /// <returns>true if the atom:entry element was found and the reader was not moved; /// false otherwise and the reader is positioned on the next node after the ATOM element.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element in ATOM namespace - The element in ATOM namespace to read. /// Post-Condition: Any - The node after the ATOM element which was consumed. /// XmlNodeType.Element atom:entry - The start of the atom:entry element (the reader did not move in this case). /// </remarks> private bool ReadAtomElementInFeed(IODataAtomReaderFeedState feedState, bool isExpandedLinkContent) { Debug.Assert(feedState != null, "feedState != null"); this.XmlReader.AssertNotBuffering(); this.AssertXmlCondition(XmlNodeType.Element); Debug.Assert( this.XmlReader.NamespaceURI == AtomConstants.AtomNamespace, "The reader must be on an element in the ATOM namespace for this method to work."); // ATOM elements if (this.XmlReader.LocalNameEquals(this.AtomEntryElementName)) { // atom:entry return true; } if (this.XmlReader.LocalNameEquals(this.AtomLinkElementName)) { // atom:link // NOTE: this method does not move the reader; thus a potential xml:base definition on the element // works correctly for the values read from the attributes until we move the reader. string linkRelation, linkHRef; this.ReadAtomLinkRelationAndHRef(out linkRelation, out linkHRef); if (linkRelation != null) { if (this.ReadAtomStandardRelationLinkInFeed(feedState, linkRelation, linkHRef, isExpandedLinkContent)) { return false; } string unescapedLinkRelation = AtomUtils.UnescapeAtomLinkRelationAttribute(linkRelation); if (unescapedLinkRelation != null) { string ianaRelation = AtomUtils.GetNameFromAtomLinkRelationAttribute(linkRelation, AtomConstants.IanaLinkRelationsNamespace); if (ianaRelation != null && this.ReadAtomStandardRelationLinkInFeed(feedState, ianaRelation, linkHRef, isExpandedLinkContent)) { return false; } } } if (this.ReadAtomMetadata) { AtomLinkMetadata linkMetadata = this.FeedMetadataDeserializer.ReadAtomLinkElementInFeed(linkRelation, linkHRef); feedState.AtomFeedMetadata.AddLink(linkMetadata); } else { // Ignore content of atom:link elements (unless they are expanded nav. links) this.XmlReader.Skip(); } } else if (this.XmlReader.LocalNameEquals(this.AtomIdElementName)) { // atom:id // The id should be an IRI (so text only), but we already allow much more for entry/id, so we should do the same for feed/id // just to be consistent. // WCF DS V2 server fails on mixed and element content in the id element. The ReadElementValue also fails on mixed and element content // so this is a compatible behavior. string idValue = this.XmlReader.ReadElementValue(); // We do not validate ID values on feeds when reading. feedState.Feed.Id = UriUtils.CreateUriAsEntryOrFeedId(idValue, UriKind.Absolute); } else { if (this.ReadAtomMetadata) { this.FeedMetadataDeserializer.ReadAtomElementAsFeedMetadata(feedState.AtomFeedMetadata); } else { this.XmlReader.Skip(); } } return false; }
/// <summary> /// Reads the content of a feed (child nodes of the atom:feed). /// </summary> /// <param name="feedState">The reader feed state for the feed being read.</param> /// <param name="isExpandedLinkContent">true if the feed is inside an expanded link.</param> /// <returns>true if an entry was found or false if no more entries were found in the feed.</returns> /// <remarks> /// Pre-Condition: Anything but Attribute - the child node of the atom:feed element, can be pretty much anything, the method will skip over insignificant nodes and text nodes if found. /// Post-Condition: XmlNodeType.EndElement atom:feed - The end of the atom:feed element if no entry was found and the end of the feed was reached. /// XmlNodeType.Element atom:entry - The start tag of the atom:entry element representing an entry in the feed. /// </remarks> internal bool ReadFeedContent(IODataAtomReaderFeedState feedState, bool isExpandedLinkContent) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(feedState != null, "feedState != null"); this.XmlReader.AssertNotBuffering(); Debug.Assert(this.XmlReader.NodeType != XmlNodeType.Attribute, "The reader must be positioned on a child node of the atom:feed element."); bool entryFound = false; while (this.XmlReader.NodeType != XmlNodeType.EndElement) { if (this.XmlReader.NodeType != XmlNodeType.Element) { Debug.Assert(this.XmlReader.NodeType != XmlNodeType.EndElement, "EndElement should have been handled already."); // Skip everything but elements, including insignificant nodes, text nodes and CDATA nodes this.XmlReader.Skip(); continue; } if (this.XmlReader.NamespaceEquals(this.AtomNamespace)) { if (this.ReadAtomElementInFeed(feedState)) { // We've found an entry - return. entryFound = true; break; } } else if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataMetadataNamespace)) { if (this.ReadingResponse && this.Version >= ODataVersion.V2 && !isExpandedLinkContent && this.XmlReader.LocalNameEquals(this.ODataCountElementName)) { // m:count this.ValidateDuplicateElement(feedState.HasCount); // Note that we allow negative values to be read. long countValue = (long)AtomValueUtils.ReadPrimitiveValue(this.XmlReader, EdmCoreModel.Instance.GetInt64(true)); feedState.Feed.Count = countValue; // Read over the end element or the empty start element. this.XmlReader.Read(); feedState.HasCount = true; } else { // Any other element in the m namespace is to be ignored. this.XmlReader.Skip(); } } else { // non-ATOM elements, ignore them this.XmlReader.Skip(); } } Debug.Assert( this.XmlReader.NodeType != XmlNodeType.EndElement || (this.XmlReader.NamespaceURI == AtomConstants.AtomNamespace && this.XmlReader.LocalName == AtomConstants.AtomFeedElementName), "EndElement found but for element other than atom:feed."); Debug.Assert( this.XmlReader.NodeType != XmlNodeType.Element || (this.XmlReader.NamespaceURI == AtomConstants.AtomNamespace && this.XmlReader.LocalName == AtomConstants.AtomEntryElementName), "Only atom:entry elements can be reported as entries."); this.AssertXmlCondition(XmlNodeType.Element, XmlNodeType.EndElement); this.XmlReader.AssertNotBuffering(); return entryFound; }
/// <summary> /// Reads the atom:link element with one of the standard relation values in the atom:feed element. /// </summary> /// <param name="feedState">The reader feed state for the feed being read.</param> /// <param name="linkRelation">The rel attribute value for the link.</param> /// <param name="linkHRef">The href attribute value for the link (or null if the href attribute was not present).</param> /// <returns>If the rel was one of the recognized standard relations and this method read the link /// the return value is true. Otherwise the method doesn't move the reader and returns false.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element atom:link - The atom:link element to read. /// Post-Condition: Any - The node after the atom:link element if the link was read by this method. /// XmlNodeType.Element atom:link - The atom:link element to read if the link was not read by this method. /// </remarks> private bool ReadAtomStandardRelationLinkInFeed(IODataAtomReaderFeedState feedState, string linkRelation, string linkHRef) { Debug.Assert(feedState != null, "feedState != null"); Debug.Assert(linkRelation != null, "linkRelation != null"); this.XmlReader.AssertNotBuffering(); this.AssertXmlCondition(XmlNodeType.Element); Debug.Assert( this.XmlReader.NamespaceURI == AtomConstants.AtomNamespace && this.XmlReader.LocalName == AtomConstants.AtomLinkElementName, "The XML reader must be on the atom:link element for this method to work."); if (string.CompareOrdinal(linkRelation, AtomConstants.AtomNextRelationAttributeValue) == 0) { if (!this.ReadingResponse || this.Version < ODataVersion.V2) { // Return false which means the rel for the link was not recognized and it will be read as any other link. return false; } if (feedState.HasNextPageLink) { throw new ODataException(o.Strings.ODataAtomEntryAndFeedDeserializer_MultipleLinksInFeed(AtomConstants.AtomNextRelationAttributeValue)); } // next link if (linkHRef != null) { feedState.Feed.NextPageLink = this.ProcessUriFromPayload(linkHRef, this.XmlReader.XmlBaseUri); } feedState.HasNextPageLink = true; if (this.ReadAtomMetadata) { AtomLinkMetadata linkMetadata = this.FeedMetadataDeserializer.ReadAtomLinkElementInFeed(linkRelation, linkHRef); feedState.AtomFeedMetadata.NextPageLink = linkMetadata; } else { this.XmlReader.Skip(); } return true; } if (string.CompareOrdinal(linkRelation, AtomConstants.AtomSelfRelationAttributeValue) == 0) { if (feedState.HasReadLink && this.AtomInputContext.UseDefaultFormatBehavior) { throw new ODataException(o.Strings.ODataAtomEntryAndFeedDeserializer_MultipleLinksInFeed(AtomConstants.AtomSelfRelationAttributeValue)); } if (this.ReadAtomMetadata) { // Capture the ATOM metadata of the self link. AtomLinkMetadata linkMetadata = this.FeedMetadataDeserializer.ReadAtomLinkElementInFeed(linkRelation, linkHRef); feedState.AtomFeedMetadata.SelfLink = linkMetadata; } else { this.XmlReader.Skip(); } feedState.HasReadLink = true; return true; } return false; }
/// <summary> /// Reads an ATOM element inside the atom:feed from the input. /// </summary> /// <param name="feedState">The reader feed state for the feed being read.</param> /// <returns>true if the atom:entry element was found and the reader was not moved; /// false otherwise and the reader is positioned on the next node after the ATOM element.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element in ATOM namespace - The element in ATOM namespace to read. /// Post-Condition: Any - The node after the ATOM element which was consumed. /// XmlNodeType.Element atom:entry - The start of the atom:entry element (the reader did not move in this case). /// </remarks> private bool ReadAtomElementInFeed(IODataAtomReaderFeedState feedState) { Debug.Assert(feedState != null, "feedState != null"); this.XmlReader.AssertNotBuffering(); this.AssertXmlCondition(XmlNodeType.Element); Debug.Assert( this.XmlReader.NamespaceURI == AtomConstants.AtomNamespace, "The reader must be on an element in the ATOM namespace for this method to work."); // ATOM elements if (this.XmlReader.LocalNameEquals(this.AtomEntryElementName)) { // atom:entry return true; } if (this.XmlReader.LocalNameEquals(this.AtomLinkElementName)) { // atom:link // NOTE: this method does not move the reader; thus a potential xml:base definition on the element // works correctly for the values read from the attributes until we move the reader. string linkRelation, linkHRef; this.ReadAtomLinkRelationAndHRef(out linkRelation, out linkHRef); if (linkRelation != null) { if (this.ReadAtomStandardRelationLinkInFeed(feedState, linkRelation, linkHRef)) { return false; } string unescapedLinkRelation = AtomUtils.UnescapeAtomLinkRelationAttribute(linkRelation); if (unescapedLinkRelation != null) { string ianaRelation = AtomUtils.GetNameFromAtomLinkRelationAttribute(linkRelation, AtomConstants.IanaLinkRelationsNamespace); if (ianaRelation != null && this.ReadAtomStandardRelationLinkInFeed(feedState, ianaRelation, linkHRef)) { return false; } } } if (this.ReadAtomMetadata) { AtomLinkMetadata linkMetadata = this.FeedMetadataDeserializer.ReadAtomLinkElementInFeed(linkRelation, linkHRef); AtomMetadataReaderUtils.AddLinkToFeedMetadata(feedState.AtomFeedMetadata, linkMetadata); } else { this.XmlReader.Skip(); } } else if (this.XmlReader.LocalNameEquals(this.AtomIdElementName)) { // atom:id // The id should be an IRI (so text only), but we already allow much more for entry/id, so we should do the same for feed/id // just to be consistent. string idValue = this.XmlReader.ReadElementValue(); feedState.Feed.Id = idValue; } else { if (this.ReadAtomMetadata) { this.FeedMetadataDeserializer.ReadAtomElementAsFeedMetadata(feedState.AtomFeedMetadata); } else { this.XmlReader.Skip(); } } return false; }
internal bool ReadFeedContent(IODataAtomReaderFeedState feedState, bool isExpandedLinkContent) { while (base.XmlReader.NodeType != XmlNodeType.EndElement) { if (base.XmlReader.NodeType != XmlNodeType.Element) { base.XmlReader.Skip(); } else { if (base.XmlReader.NamespaceEquals(this.AtomNamespace)) { if (this.ReadAtomElementInFeed(feedState)) { return true; } continue; } if (base.XmlReader.NamespaceEquals(base.XmlReader.ODataMetadataNamespace)) { if ((base.ReadingResponse && (base.Version >= ODataVersion.V2)) && (!isExpandedLinkContent && base.XmlReader.LocalNameEquals(this.ODataCountElementName))) { this.ValidateDuplicateElement(feedState.HasCount); long num = (long) AtomValueUtils.ReadPrimitiveValue(base.XmlReader, EdmCoreModel.Instance.GetInt64(true)); feedState.Feed.Count = new long?(num); base.XmlReader.Read(); feedState.HasCount = true; } else { base.XmlReader.Skip(); } continue; } base.XmlReader.Skip(); } } return false; }
private bool ReadAtomStandardRelationLinkInFeed(IODataAtomReaderFeedState feedState, string linkRelation, string linkHRef) { if (string.CompareOrdinal(linkRelation, "next") == 0) { if (!base.ReadingResponse || (base.Version < ODataVersion.V2)) { return false; } if (feedState.HasNextPageLink) { throw new ODataException(Microsoft.Data.OData.Strings.ODataAtomEntryAndFeedDeserializer_MultipleLinksInFeed("next")); } if (linkHRef != null) { feedState.Feed.NextPageLink = base.ProcessUriFromPayload(linkHRef, base.XmlReader.XmlBaseUri); } feedState.HasNextPageLink = true; if (this.ReadAtomMetadata) { AtomLinkMetadata metadata = this.FeedMetadataDeserializer.ReadAtomLinkElementInFeed(linkRelation, linkHRef); feedState.AtomFeedMetadata.NextPageLink = metadata; } else { base.XmlReader.Skip(); } return true; } if (string.CompareOrdinal(linkRelation, "self") != 0) { return false; } if (feedState.HasReadLink && base.AtomInputContext.UseDefaultFormatBehavior) { throw new ODataException(Microsoft.Data.OData.Strings.ODataAtomEntryAndFeedDeserializer_MultipleLinksInFeed("self")); } if (this.ReadAtomMetadata) { AtomLinkMetadata metadata2 = this.FeedMetadataDeserializer.ReadAtomLinkElementInFeed(linkRelation, linkHRef); feedState.AtomFeedMetadata.SelfLink = metadata2; } else { base.XmlReader.Skip(); } feedState.HasReadLink = true; return true; }
private bool ReadAtomElementInFeed(IODataAtomReaderFeedState feedState) { if (base.XmlReader.LocalNameEquals(this.AtomEntryElementName)) { return true; } if (base.XmlReader.LocalNameEquals(this.AtomLinkElementName)) { string str; string str2; this.ReadAtomLinkRelationAndHRef(out str, out str2); if (str != null) { if (this.ReadAtomStandardRelationLinkInFeed(feedState, str, str2)) { return false; } if (AtomUtils.UnescapeAtomLinkRelationAttribute(str) != null) { string nameFromAtomLinkRelationAttribute = AtomUtils.GetNameFromAtomLinkRelationAttribute(str, "http://www.iana.org/assignments/relation/"); if ((nameFromAtomLinkRelationAttribute != null) && this.ReadAtomStandardRelationLinkInFeed(feedState, nameFromAtomLinkRelationAttribute, str2)) { return false; } } } if (this.ReadAtomMetadata) { AtomLinkMetadata linkMetadata = this.FeedMetadataDeserializer.ReadAtomLinkElementInFeed(str, str2); AtomMetadataReaderUtils.AddLinkToFeedMetadata(feedState.AtomFeedMetadata, linkMetadata); } else { base.XmlReader.Skip(); } } else if (base.XmlReader.LocalNameEquals(this.AtomIdElementName)) { string str5 = base.XmlReader.ReadElementValue(); feedState.Feed.Id = str5; } else if (this.ReadAtomMetadata) { this.FeedMetadataDeserializer.ReadAtomElementAsFeedMetadata(feedState.AtomFeedMetadata); } else { base.XmlReader.Skip(); } return false; }