using System; using System.IO; using System.Text; using System.Xml; using Sprache; using XNeedle.Parser; using XNeedle.Parser.Elements; namespace XNeedle.Transformation { public class ContextFunctions { public static string hex(Context ctx, double value) { uint v = (uint)value; return $"#x{v:X8}"; } public static int GetLevel(XmlNode node) { int level = 0; XmlNode? currentNode = node; while (null != (currentNode = currentNode.ParentNode)) level++; return level; } public static double crc(Context ctx) { if (ctx.Node is null) { return 0; } int crc = 0xAFFE; XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.ConformanceLevel = ConformanceLevel.Document; settings.OmitXmlDeclaration = true; // This isn't performant, but the whole document has to be rendered // for an accurate data stream string docrender = ""; string fragrender = ""; using (var sw = new StringWriter()) { using (var xw = XmlWriter.Create(sw, settings)) { if (ctx.Node.OwnerDocument is not null) { ctx.Node.OwnerDocument.WriteContentTo(xw); } } docrender = sw.ToString(); } settings.Indent = false; settings.ConformanceLevel = ConformanceLevel.Fragment; using (var sw = new StringWriter()) { using (var xw = XmlWriter.Create(sw, settings)) { ctx.Node.WriteTo(xw); } fragrender = sw.ToString(); } string tagname = ctx.Node.Name; string anchor = XmlFragParser.OpeningTagAnchor(tagname).Parse(fragrender); string preamble = $"<{tagname}{anchor}>"; //string data = FragXmlParser.ChecksumData(preamble, tagname).TryParse(docrender); Console.WriteLine("preamble: " + preamble); var crc32 = new System.IO.Hashing.Crc32(); var bytes = Encoding.UTF8.GetBytes(""); crc32.Append(bytes); crc = BitConverter.ToInt32(crc32.GetCurrentHash()); return (double)crc; } public static string text(Context ctx) { if (ctx.Node is null) return ""; return ctx.Node.InnerText; } public static string text(Context ctx, string txt) { if (ctx.Node is null) return ""; return ctx.Node.InnerText = txt; } public static string attr(Context ctx, string name, string value) { if (ctx.Node is null || ctx.Node.Attributes is null) return ""; var attr = ctx.Node.Attributes[name]; if (attr != null) { attr.Value = value; } else { if (ctx.Node.OwnerDocument is null) return ""; var add = ctx.Node.OwnerDocument.CreateAttribute(name); add.Value = value; ctx.Node.Attributes.SetNamedItem(add); } return ""; } public static string attr(Context ctx, string name) { if (ctx.Node?.Attributes?[name]?.Value is string val) { return val; } return ""; } } }