private IEnumerable <XElement> CreateNodeElements(IEnumerable <BaseNode> nodes, ILogger logger) { Contract.Requires(nodes != null); Contract.Requires(logger != null); Contract.Ensures(Contract.Result <IEnumerable <XElement> >() != null); foreach (var node in nodes) { var converter = CustomNodeConvert.GetWriteConverter(node); if (converter != null) { yield return(converter.CreateElementFromNode(node, logger)); continue; } string typeString; if (!BuildInTypeToStringMap.TryGetValue(node.GetType(), out typeString)) { logger.Log(LogLevel.Error, $"Skipping node with unknown type: {node.Name}"); logger.Log(LogLevel.Warning, node.GetType().ToString()); continue; } var element = new XElement( XmlNodeElement, new XAttribute(XmlNameAttribute, node.Name ?? string.Empty), new XAttribute(XmlCommentAttribute, node.Comment ?? string.Empty), new XAttribute(XmlTypeAttribute, typeString) ); var referenceNode = node as BaseReferenceNode; if (referenceNode != null) { element.SetAttributeValue(XmlReferenceAttribute, referenceNode.InnerNode.Uuid.ToBase64String()); } var vtableNode = node as VTableNode; if (vtableNode != null) { element.Add(vtableNode.Nodes.Select(n => new XElement( XmlMethodElement, new XAttribute(XmlNameAttribute, n.Name ?? string.Empty), new XAttribute(XmlCommentAttribute, n.Comment ?? string.Empty) ))); } var arrayNode = node as BaseArrayNode; if (arrayNode != null) { element.SetAttributeValue(XmlCountAttribute, arrayNode.Count); } var textNode = node as BaseTextNode; if (textNode != null) { element.SetAttributeValue(XmlLengthAttribute, textNode.Length); } var bitFieldNode = node as BitFieldNode; if (bitFieldNode != null) { element.SetAttributeValue(XmlBitsAttribute, bitFieldNode.Bits); } yield return(element); } }
private IEnumerable <BaseNode> ReadNodeElements(IEnumerable <XElement> elements, ClassNode parent, ILogger logger) { Contract.Requires(elements != null); Contract.Requires(Contract.ForAll(elements, e => e != null)); Contract.Requires(parent != null); Contract.Requires(logger != null); foreach (var element in elements) { var converter = CustomNodeConvert.GetReadConverter(element); if (converter != null) { BaseNode customNode; if (converter.TryCreateNodeFromElement(element, parent, project.Classes, logger, out customNode)) { yield return(customNode); } continue; } Type nodeType; if (!BuildInStringToTypeMap.TryGetValue(element.Attribute(XmlTypeAttribute)?.Value, out nodeType)) { logger.Log(LogLevel.Error, $"Skipping node with unknown type: {element.Attribute(XmlTypeAttribute)?.Value}"); logger.Log(LogLevel.Warning, element.ToString()); continue; } var node = Activator.CreateInstance(nodeType) as BaseNode; if (node == null) { logger.Log(LogLevel.Error, $"Could not create node of type: {nodeType}"); continue; } node.Name = element.Attribute(XmlNameAttribute)?.Value ?? string.Empty; node.Comment = element.Attribute(XmlCommentAttribute)?.Value ?? string.Empty; var referenceNode = node as BaseReferenceNode; if (referenceNode != null) { var reference = NodeUuid.FromBase64String(element.Attribute(XmlReferenceAttribute)?.Value, false); if (!project.ContainsClass(reference)) { logger.Log(LogLevel.Error, $"Skipping node with unknown reference: {reference}"); logger.Log(LogLevel.Warning, element.ToString()); continue; } var innerClassNode = project.GetClassByUuid(reference); if (referenceNode.PerformCycleCheck && !ClassUtil.IsCycleFree(parent, innerClassNode, project.Classes)) { logger.Log(LogLevel.Error, $"Skipping node with cycle reference: {parent.Name}->{node.Name}"); continue; } referenceNode.ChangeInnerNode(innerClassNode); } var vtableNode = node as VTableNode; if (vtableNode != null) { element .Elements(XmlMethodElement) .Select(e => new VMethodNode { Name = e.Attribute(XmlNameAttribute)?.Value ?? string.Empty, Comment = e.Attribute(XmlCommentAttribute)?.Value ?? string.Empty }) .ForEach(vtableNode.AddNode); } var arrayNode = node as BaseArrayNode; if (arrayNode != null) { int count; TryGetAttributeValue(element, XmlCountAttribute, out count, logger); arrayNode.Count = count; } var textNode = node as BaseTextNode; if (textNode != null) { int length; TryGetAttributeValue(element, XmlLengthAttribute, out length, logger); textNode.Length = length; } var bitFieldNode = node as BitFieldNode; if (bitFieldNode != null) { int bits; TryGetAttributeValue(element, XmlBitsAttribute, out bits, logger); bitFieldNode.Bits = bits; } var functionNode = node as FunctionNode; if (functionNode != null) { functionNode.Signature = element.Attribute(XmlSignatureAttribute)?.Value ?? string.Empty; var reference = NodeUuid.FromBase64String(element.Attribute(XmlReferenceAttribute)?.Value, false); if (project.ContainsClass(reference)) { functionNode.BelongsToClass = project.GetClassByUuid(reference); } } yield return(node); } }