using System; using System.Collections.Generic; using System.Text; using System.Xml; using System.IO; using System.Globalization; namespace FastReport.Messaging.Xmpp { /// /// The parser for XMPP XML-streams. /// internal class StreamParser : IDisposable { #region Fields private XmlReader reader; private Stream stream; private bool leaveOpen; private CultureInfo language; #endregion // Fields #region Constructors /// /// Initializes a new instance of the class. /// /// The stream for parsing. /// True to leave the stream opened after closing the StreamReader instance. public StreamParser(Stream stream, bool leaveOpen) { this.stream = stream; this.leaveOpen = leaveOpen; XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreComments = true; settings.IgnoreWhitespace = true; settings.IgnoreProcessingInstructions = true; reader = XmlReader.Create(stream, settings); ReadRootElement(); } #endregion // Constructors #region Private Methods /// /// Read the XML stream up to opening "stream:stream" tag. /// private void ReadRootElement() { while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.XmlDeclaration: break; case XmlNodeType.Element: if (reader.Name == "stream:stream") { string lang = reader.GetAttribute("xml:lang"); if (!String.IsNullOrEmpty(lang)) { language = new CultureInfo(lang); return; } } break; } } } #endregion // Private Methods #region Public Methods /// /// Reads the next XML element from the stream. /// /// The list of XML elements that are expected. /// The XML element. public XmlElement ReadNextElement(List expected) { reader.Read(); using (XmlReader innerReader = reader.ReadSubtree()) { innerReader.Read(); string xml = innerReader.ReadOuterXml(); XmlDocument doc = new XmlDocument(); using (XmlTextReader xtr = new XmlTextReader(new StringReader(xml))) { doc.Load(xtr); } XmlElement element = doc.FirstChild as XmlElement; if (expected.Count > 0 && !expected.Contains(element.Name)) { element = null; } return element; } } /// /// Closes the stream parser. /// public void Close() { Dispose(); } /// /// Releases all resources used by the current instance of the class. /// public void Dispose() { reader.Close(); if (!leaveOpen) { stream.Close(); } } #endregion // Public Methods } }