private static FileFormats.Property.Node ParseObject(XPathNavigator nav) { var node = new FileFormats.Property.Node(); if (nav.MoveToAttribute("tag", "") == true) { node.Tag = nav.Value; nav.MoveToParent(); } var values = nav.Select("value"); while (values.MoveNext() == true) { var current = values.Current; if (current == null) { throw new InvalidOperationException(); } string name; var id = GetIdOrName(current, out name); var type = current.GetAttribute("type", ""); var variant = FileFormats.Property.VariantFactory.GetVariant(type); variant.Parse(current.Value); if (node.Variants.ContainsKey(id) == true) { var lineInfo = (IXmlLineInfo)current; if (string.IsNullOrEmpty(name) == true) { throw new FormatException(string.Format("duplicate object id 0x{0:X8} at line {1} position {2}", id, lineInfo.LineNumber, lineInfo.LinePosition)); } throw new FormatException(string.Format("duplicate object id 0x{0:X8} ('{1}') at line {2} position {3}", id, name, lineInfo.LineNumber, lineInfo.LinePosition)); } node.Variants.Add(id, variant); } var children = nav.Select("object"); while (children.MoveNext() == true) { var child = children.Current; if (child == null) { throw new InvalidOperationException(); } string name; uint id = GetIdOrName(child, out name); var obj = ParseObject(child); if (node.Nodes.ContainsKey(id) == true) { var lineInfo = (IXmlLineInfo)child; if (string.IsNullOrEmpty(name) == true) { throw new FormatException(string.Format("duplicate object id 0x{0:X8} at line {1} position {2}", id, lineInfo.LineNumber, lineInfo.LinePosition)); } throw new FormatException(string.Format("duplicate object id 0x{0:X8} ('{1}') at line {2} position {3}", id, name, lineInfo.LineNumber, lineInfo.LinePosition)); } node.Nodes.Add(id, obj); } return(node); }
private static void WriteObject(XmlWriter writer, FileFormats.Property.Node node) { if (node.Tag != null) { writer.WriteAttributeString("tag", node.Tag); } // is this ridiculous? // yeeeeep. var nodesByName = node.Nodes .Where(kv => node.KnownNames.ContainsKey(kv.Key) == true) .Select(kv => new KeyValuePair <string, FileFormats.Property.Node>(node.KnownNames[kv.Key], kv.Value)) .Concat( node.Nodes .Where(kv => node.KnownNames.ContainsKey(kv.Key) == false && _Names.Contains(kv.Key) == true) .Select(kv => new KeyValuePair <string, FileFormats.Property.Node>(_Names[kv.Key], kv.Value))) .ToArray(); var nodesByHash = node.Nodes .Where(kv => node.KnownNames.ContainsKey(kv.Key) == false && _Names.Contains(kv.Key) == false) .Select(kv => kv) .ToArray(); var variantsByName = node.Variants .Where(kv => node.KnownNames.ContainsKey(kv.Key) == true) .Select(kv => new KeyValuePair <string, FileFormats.Property.IVariant>(node.KnownNames[kv.Key], kv.Value)) .Concat( node.Variants .Where(kv => node.KnownNames.ContainsKey(kv.Key) == false && _Names.Contains(kv.Key) == true) .Select(kv => new KeyValuePair <string, FileFormats.Property.IVariant>(_Names[kv.Key], kv.Value))) .ToArray(); var variantsByHash = node.Variants .Where(kv => node.KnownNames.ContainsKey(kv.Key) == false && _Names.Contains(kv.Key) == false) .Select(kv => kv) .ToArray(); if (variantsByName.Length > 0) { foreach (var kv in variantsByName.OrderBy(kv => kv.Key)) { writer.WriteStartElement("value"); writer.WriteAttributeString("name", kv.Key); WriteProperty(writer, kv.Value); writer.WriteEndElement(); } } if (nodesByName.Length > 0) { foreach (var kv in nodesByName.OrderBy(kv => kv.Key)) { writer.WriteStartElement("object"); writer.WriteAttributeString("name", kv.Key); WriteObject(writer, kv.Value); writer.WriteEndElement(); } } if (variantsByHash.Length > 0) { foreach (var kv in variantsByHash.OrderBy(p => p.Key, new NameComparer(_Names))) { writer.WriteStartElement("value"); if (_Names.Contains(kv.Key) == true) { writer.WriteAttributeString("name", _Names[kv.Key]); } else { writer.WriteAttributeString("id", kv.Key.ToString("X8")); } WriteProperty(writer, kv.Value); writer.WriteEndElement(); } } if (nodesByHash.Length > 0) { foreach (var kv in nodesByHash.OrderBy(n => n.Key, new NameComparer(_Names))) { writer.WriteStartElement("object"); if (_Names.Contains(kv.Key) == true) { writer.WriteAttributeString("name", _Names[kv.Key]); } else { writer.WriteAttributeString("id", kv.Key.ToString("X8")); } WriteObject(writer, kv.Value); writer.WriteEndElement(); } } }