private static AtomDataKind ParseStateForReader(XmlReader reader) { Debug.Assert(reader != null, "reader != null"); Debug.Assert( reader.NodeType == XmlNodeType.Element || reader.NodeType == XmlNodeType.EndElement, "reader.NodeType == XmlNodeType.Element || EndElement -- otherwise can't determine"); AtomDataKind result = AtomDataKind.Custom; string elementName = reader.LocalName; string namespaceURI = reader.NamespaceURI; if (Util.AreSame(XmlConstants.AtomNamespace, namespaceURI)) { if (Util.AreSame(XmlConstants.AtomEntryElementName, elementName)) { result = AtomDataKind.Entry; } else if (Util.AreSame(XmlConstants.AtomFeedElementName, elementName)) { result = AtomDataKind.Feed; } else if (Util.AreSame(XmlConstants.AtomLinkElementName, elementName) && Util.AreSame(XmlConstants.AtomLinkNextAttributeString, reader.GetAttribute(XmlConstants.AtomLinkRelationAttributeName))) { result = AtomDataKind.PagingLinks; } } else if (Util.AreSame(XmlConstants.DataWebMetadataNamespace, namespaceURI)) { if (Util.AreSame(XmlConstants.RowCountElement, elementName)) { result = AtomDataKind.FeedCount; } } return(result); }
/// <summary>Consumes the next chunk of content from the underlying XML reader.</summary> /// <returns> /// true if another piece of content is available, identified by DataKind. /// false if there is no more content. /// </returns> internal bool Read() { // When an external caller 'insists', we'll come all the way down (which is the 'most local' // scope at which this is known), and unwind as a no-op. if (this.DataKind == AtomDataKind.Finished) { return false; } while (this.reader.Read()) { if (ShouldIgnoreNode(this.reader)) { continue; } Debug.Assert( this.reader.NodeType == XmlNodeType.Element || this.reader.NodeType == XmlNodeType.EndElement, "this.reader.NodeType == XmlNodeType.Element || this.reader.NodeType == XmlNodeType.EndElement -- otherwise we should have ignored or thrown"); AtomDataKind readerData = ParseStateForReader(this.reader); if (this.reader.NodeType == XmlNodeType.EndElement) { // The only case in which we expect to see an end-element at the top level // is for a feed. Custom elements and entries should be consumed by // their own parsing methods. However we are tolerant of additional EndElements, // which at this point mean we have nothing else to consume. break; } switch (readerData) { case AtomDataKind.Custom: if (this.DataKind == AtomDataKind.None) { this.kind = AtomDataKind.Custom; return true; } else { MaterializeAtom.SkipToEnd(this.reader); continue; } case AtomDataKind.Entry: this.kind = AtomDataKind.Entry; this.ParseCurrentEntry(out this.entry); return true; case AtomDataKind.Feed: if (this.DataKind == AtomDataKind.None) { this.feed = new AtomFeed(); this.kind = AtomDataKind.Feed; return true; } throw new InvalidOperationException(Strings.AtomParser_FeedUnexpected); case AtomDataKind.FeedCount: this.ParseCurrentFeedCount(); break; case AtomDataKind.PagingLinks: if (this.feed == null) { // paging link outside of feed? throw new InvalidOperationException(Strings.AtomParser_PagingLinkOutsideOfFeed); } this.kind = AtomDataKind.PagingLinks; this.ParseCurrentFeedPagingLinks(); return true; default: Debug.Assert(false, "Atom Parser is in a wrong state...Did you add a new AtomDataKind?"); break; } } this.kind = AtomDataKind.Finished; this.entry = null; return false; }
internal bool Read() { if (this.DataKind == AtomDataKind.Finished) { return false; } while (this.reader.Read()) { if (ShouldIgnoreNode(this.reader)) { continue; } Debug.Assert( this.reader.NodeType == XmlNodeType.Element || this.reader.NodeType == XmlNodeType.EndElement, "this.reader.NodeType == XmlNodeType.Element || this.reader.NodeType == XmlNodeType.EndElement -- otherwise we should have ignored or thrown"); AtomDataKind readerData = ParseStateForReader(this.reader); if (this.reader.NodeType == XmlNodeType.EndElement) { break; } switch (readerData) { case AtomDataKind.Custom: if (this.DataKind == AtomDataKind.None) { this.kind = AtomDataKind.Custom; return true; } else { MaterializeAtom.SkipToEnd(this.reader); continue; } case AtomDataKind.Entry: this.kind = AtomDataKind.Entry; this.ParseCurrentEntry(out this.entry); return true; case AtomDataKind.Feed: if (this.DataKind == AtomDataKind.None) { this.feed = new AtomFeed(); this.kind = AtomDataKind.Feed; return true; } throw new InvalidOperationException(Strings.AtomParser_FeedUnexpected); case AtomDataKind.FeedCount: this.ParseCurrentFeedCount(); break; case AtomDataKind.PagingLinks: if (this.feed == null) { throw new InvalidOperationException(Strings.AtomParser_PagingLinkOutsideOfFeed); } this.kind = AtomDataKind.PagingLinks; this.ParseCurrentFeedPagingLinks(); return true; default: Debug.Assert(false, "Atom Parser is in a wrong state...Did you add a new AtomDataKind?"); break; } } this.kind = AtomDataKind.Finished; this.entry = null; return false; }
internal bool Read() { if (this.DataKind == AtomDataKind.Finished) { return(false); } while (this.reader.Read()) { if (ShouldIgnoreNode(this.reader)) { continue; } Debug.Assert( this.reader.NodeType == XmlNodeType.Element || this.reader.NodeType == XmlNodeType.EndElement, "this.reader.NodeType == XmlNodeType.Element || this.reader.NodeType == XmlNodeType.EndElement -- otherwise we should have ignored or thrown"); AtomDataKind readerData = ParseStateForReader(this.reader); if (this.reader.NodeType == XmlNodeType.EndElement) { break; } switch (readerData) { case AtomDataKind.Custom: if (this.DataKind == AtomDataKind.None) { this.kind = AtomDataKind.Custom; return(true); } else { MaterializeAtom.SkipToEnd(this.reader); continue; } case AtomDataKind.Entry: this.kind = AtomDataKind.Entry; this.ParseCurrentEntry(out this.entry); return(true); case AtomDataKind.Feed: if (this.DataKind == AtomDataKind.None) { this.feed = new AtomFeed(); this.kind = AtomDataKind.Feed; return(true); } throw new InvalidOperationException(Strings.AtomParser_FeedUnexpected); case AtomDataKind.FeedCount: this.ParseCurrentFeedCount(); break; case AtomDataKind.PagingLinks: if (this.feed == null) { throw new InvalidOperationException(Strings.AtomParser_PagingLinkOutsideOfFeed); } this.kind = AtomDataKind.PagingLinks; this.ParseCurrentFeedPagingLinks(); return(true); default: Debug.Assert(false, "Atom Parser is in a wrong state...Did you add a new AtomDataKind?"); break; } } this.kind = AtomDataKind.Finished; this.entry = null; return(false); }
/// <summary>Consumes the next chunk of content from the underlying XML reader.</summary> /// <returns> /// true if another piece of content is available, identified by DataKind. /// false if there is no more content. /// </returns> internal bool Read() { // When an external caller 'insists', we'll come all the way down (which is the 'most local' // scope at which this is known), and unwind as a no-op. if (this.DataKind == AtomDataKind.Finished) { return(false); } while (this.reader.Read()) { if (ShouldIgnoreNode(this.reader)) { continue; } Debug.Assert( this.reader.NodeType == XmlNodeType.Element || this.reader.NodeType == XmlNodeType.EndElement, "this.reader.NodeType == XmlNodeType.Element || this.reader.NodeType == XmlNodeType.EndElement -- otherwise we should have ignored or thrown"); AtomDataKind readerData = ParseStateForReader(this.reader); if (this.reader.NodeType == XmlNodeType.EndElement) { // The only case in which we expect to see an end-element at the top level // is for a feed. Custom elements and entries should be consumed by // their own parsing methods. However we are tolerant of additional EndElements, // which at this point mean we have nothing else to consume. break; } switch (readerData) { case AtomDataKind.Custom: if (this.DataKind == AtomDataKind.None) { this.kind = AtomDataKind.Custom; return(true); } else { MaterializeAtom.SkipToEnd(this.reader); continue; } case AtomDataKind.Entry: this.kind = AtomDataKind.Entry; this.ParseCurrentEntry(out this.entry); return(true); case AtomDataKind.Feed: if (this.DataKind == AtomDataKind.None) { this.feed = new AtomFeed(); this.kind = AtomDataKind.Feed; return(true); } throw new InvalidOperationException(Strings.AtomParser_FeedUnexpected); case AtomDataKind.FeedCount: this.ParseCurrentFeedCount(); break; case AtomDataKind.PagingLinks: if (this.feed == null) { // paging link outside of feed? throw new InvalidOperationException(Strings.AtomParser_PagingLinkOutsideOfFeed); } this.kind = AtomDataKind.PagingLinks; this.ParseCurrentFeedPagingLinks(); return(true); default: Debug.Assert(false, "Atom Parser is in a wrong state...Did you add a new AtomDataKind?"); break; } } this.kind = AtomDataKind.Finished; this.entry = null; return(false); }