Files
ZuneUIXTools/libs/UIX.DecompXml/IrisXmlWriter.cs
T

101 lines
2.6 KiB
C#

using Microsoft.Iris.Debug.Symbols;
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace Microsoft.Iris.DecompXml;
internal class IrisXmlWriter : IDisposable
{
private readonly IrisTextWriter _textWriter;
private readonly XmlWriter _xmlWriter;
private readonly XDocument _xDoc;
private readonly FileDebugSymbols _symbols;
public IrisXmlWriter(XDocument xDoc, FileDebugSymbols symbols)
{
_xDoc = xDoc;
_symbols = symbols;
_textWriter = new();
_xmlWriter = XmlWriter.Create(_textWriter, new XmlWriterSettings
{
Indent = true,
NamespaceHandling = NamespaceHandling.OmitDuplicates,
Encoding = Encoding.UTF8,
});
}
public void Dispose() => _xmlWriter.Dispose();
public string WriteToString()
{
Write();
return _textWriter.ToString();
}
private void Write()
{
if (_symbols is null)
{
// If we're not generating symbols, there's no reason to
// use our custom implementation.
_xDoc.WriteTo(_xmlWriter);
_xmlWriter.Flush();
return;
}
_xmlWriter.WriteStartDocument();
foreach (var node in _xDoc.Nodes())
WriteXObject(node);
_xmlWriter.WriteEndDocument();
_xmlWriter.Flush();
}
private void WriteXObject(XObject obj)
{
_xmlWriter.Flush();
var startPos = _textWriter.Position;
if (obj is XElement element)
{
_xmlWriter.WriteStartElement(element.Name.LocalName, element.Name.NamespaceName);
foreach (var attribute in element.Attributes())
WriteXObject(attribute);
foreach (var childNode in element.Nodes())
WriteXObject(childNode);
_xmlWriter.WriteEndElement();
}
else if (obj is XIrisScriptContent script)
{
_xmlWriter.WriteCData(script.Value);
}
else if (obj is XCData cdata)
{
_xmlWriter.WriteCData(cdata.Value);
}
else if (obj is XAttribute attribute)
{
_xmlWriter.WriteAttributeString(attribute.Name.LocalName, attribute.Name.NamespaceName, attribute.Value);
}
var offset = obj.GetOffset();
if (offset is not null)
{
_xmlWriter.Flush();
var endPos = _textWriter.Position;
var span = new SourceSpan(startPos, endPos);
_symbols.SourceMap.Xml[offset.Value] = span;
}
}
}