StreamParser.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Xml;
  5. using System.IO;
  6. using System.Globalization;
  7. namespace FastReport.Messaging.Xmpp
  8. {
  9. /// <summary>
  10. /// The parser for XMPP XML-streams.
  11. /// </summary>
  12. internal class StreamParser : IDisposable
  13. {
  14. #region Fields
  15. private XmlReader reader;
  16. private Stream stream;
  17. private bool leaveOpen;
  18. private CultureInfo language;
  19. #endregion // Fields
  20. #region Constructors
  21. /// <summary>
  22. /// Initializes a new instance of the <see cref="StreamParser"/> class.
  23. /// </summary>
  24. /// <param name="stream">The stream for parsing.</param>
  25. /// <param name="leaveOpen">True to leave the stream opened after closing the StreamReader instance.</param>
  26. public StreamParser(Stream stream, bool leaveOpen)
  27. {
  28. this.stream = stream;
  29. this.leaveOpen = leaveOpen;
  30. XmlReaderSettings settings = new XmlReaderSettings();
  31. settings.IgnoreComments = true;
  32. settings.IgnoreWhitespace = true;
  33. settings.IgnoreProcessingInstructions = true;
  34. reader = XmlReader.Create(stream, settings);
  35. ReadRootElement();
  36. }
  37. #endregion // Constructors
  38. #region Private Methods
  39. /// <summary>
  40. /// Read the XML stream up to opening "stream:stream" tag.
  41. /// </summary>
  42. private void ReadRootElement()
  43. {
  44. while (reader.Read())
  45. {
  46. switch (reader.NodeType)
  47. {
  48. case XmlNodeType.XmlDeclaration:
  49. break;
  50. case XmlNodeType.Element:
  51. if (reader.Name == "stream:stream")
  52. {
  53. string lang = reader.GetAttribute("xml:lang");
  54. if (!String.IsNullOrEmpty(lang))
  55. {
  56. language = new CultureInfo(lang);
  57. return;
  58. }
  59. }
  60. break;
  61. }
  62. }
  63. }
  64. #endregion // Private Methods
  65. #region Public Methods
  66. /// <summary>
  67. /// Reads the next XML element from the stream.
  68. /// </summary>
  69. /// <param name="expected">The list of XML elements that are expected.</param>
  70. /// <returns>The XML element.</returns>
  71. public XmlElement ReadNextElement(List<string> expected)
  72. {
  73. reader.Read();
  74. using (XmlReader innerReader = reader.ReadSubtree())
  75. {
  76. innerReader.Read();
  77. string xml = innerReader.ReadOuterXml();
  78. XmlDocument doc = new XmlDocument();
  79. using (XmlTextReader xtr = new XmlTextReader(new StringReader(xml)))
  80. {
  81. doc.Load(xtr);
  82. }
  83. XmlElement element = doc.FirstChild as XmlElement;
  84. if (expected.Count > 0 && !expected.Contains(element.Name))
  85. {
  86. element = null;
  87. }
  88. return element;
  89. }
  90. }
  91. /// <summary>
  92. /// Closes the stream parser.
  93. /// </summary>
  94. public void Close()
  95. {
  96. Dispose();
  97. }
  98. /// <summary>
  99. /// Releases all resources used by the current instance of the <see cref="StreamParser"/> class.
  100. /// </summary>
  101. public void Dispose()
  102. {
  103. reader.Close();
  104. if (!leaveOpen)
  105. {
  106. stream.Close();
  107. }
  108. }
  109. #endregion // Public Methods
  110. }
  111. }