예제 #1
0
        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)
                {
                    if (converter.TryCreateNodeFromElement(element, parent, project.Classes, logger, out var customNode))
                    {
                        yield return(customNode);
                    }

                    continue;
                }

                if (!buildInStringToTypeMap.TryGetValue(element.Attribute(XmlTypeAttribute)?.Value ?? string.Empty, out var 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;

                if (node is BaseReferenceNode referenceNode)
                {
                    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);
                }

                switch (node)
                {
                case VTableNode vtableNode:
                {
                    element
                    .Elements(XmlMethodElement)
                    .Select(e => new VMethodNode
                        {
                            Name    = e.Attribute(XmlNameAttribute)?.Value ?? string.Empty,
                            Comment = e.Attribute(XmlCommentAttribute)?.Value ?? string.Empty
                        })
                    .ForEach(vtableNode.AddNode);
                    break;
                }

                case BaseArrayNode arrayNode:
                {
                    TryGetAttributeValue(element, XmlCountAttribute, out var count, logger);
                    arrayNode.Count = count;
                    break;
                }

                case BaseTextNode textNode:
                {
                    TryGetAttributeValue(element, XmlLengthAttribute, out var length, logger);
                    textNode.Length = length;
                    break;
                }

                case BitFieldNode bitFieldNode:
                {
                    TryGetAttributeValue(element, XmlBitsAttribute, out var bits, logger);
                    bitFieldNode.Bits = bits;
                    break;
                }

                case FunctionNode functionNode:
                {
                    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);
                    }
                    break;
                }
                }

                yield return(node);
            }
        }
예제 #2
0
        private static IEnumerable <XElement> CreateNodeElements(IEnumerable <BaseNode> nodes, ILogger logger)
        {
            Contract.Requires(nodes != null);
            Contract.Requires(Contract.ForAll(nodes, n => n != 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;
                }

                if (!buildInTypeToStringMap.TryGetValue(node.GetType(), out var 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)
                    );

                if (node is BaseReferenceNode referenceNode)
                {
                    element.SetAttributeValue(XmlReferenceAttribute, referenceNode.InnerNode.Uuid.ToBase64String());
                }

                switch (node)
                {
                case VTableNode vtableNode:
                {
                    element.Add(vtableNode.Nodes.Select(n => new XElement(
                                                            XmlMethodElement,
                                                            new XAttribute(XmlNameAttribute, n.Name ?? string.Empty),
                                                            new XAttribute(XmlCommentAttribute, n.Comment ?? string.Empty)
                                                            )));
                    break;
                }

                case BaseArrayNode arrayNode:
                {
                    element.SetAttributeValue(XmlCountAttribute, arrayNode.Count);
                    break;
                }

                case BaseTextNode textNode:
                {
                    element.SetAttributeValue(XmlLengthAttribute, textNode.Length);
                    break;
                }

                case BitFieldNode bitFieldNode:
                {
                    element.SetAttributeValue(XmlBitsAttribute, bitFieldNode.Bits);
                    break;
                }

                case FunctionNode functionNode:
                {
                    var uuid = functionNode.BelongsToClass == null ? NodeUuid.Zero : functionNode.BelongsToClass.Uuid;
                    element.SetAttributeValue(XmlReferenceAttribute, uuid.ToBase64String());
                    element.SetAttributeValue(XmlSignatureAttribute, functionNode.Signature);
                    break;
                }
                }

                yield return(element);
            }
        }