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
}
}