/// <summary>
        /// Transforms the given node into some other node if necessary.
        /// </summary>
        /// <param name="node">The node to transform.</param>
        /// <returns>The transformed node.</returns>
        private static BaseNode TransformNode(BaseNode node)
        {
            var custom = GetCustomCodeGeneratorForNode(node);

            if (custom != null)
            {
                return(custom.TransformNode(node));
            }

            BaseNode GetCharacterNodeForEncoding(Encoding encoding)
            {
                if (encoding.IsSameCodePage(Encoding.Unicode))
                {
                    return(new Utf16CharacterNode());
                }
                if (encoding.IsSameCodePage(Encoding.UTF32))
                {
                    return(new Utf32CharacterNode());
                }
                return(new Utf8CharacterNode());
            }

            if (node is BaseTextNode textNode)
            {
                var arrayNode = new ArrayNode {
                    Count = textNode.Length
                };
                arrayNode.CopyFromNode(node);
                arrayNode.ChangeInnerNode(GetCharacterNodeForEncoding(textNode.Encoding));
                return(arrayNode);
            }

            if (node is BaseTextPtrNode textPtrNode)
            {
                var pointerNode = new PointerNode();
                pointerNode.CopyFromNode(node);
                pointerNode.ChangeInnerNode(GetCharacterNodeForEncoding(textPtrNode.Encoding));
                return(pointerNode);
            }

            if (node is BitFieldNode bitFieldNode)
            {
                var underlayingNode = bitFieldNode.GetUnderlayingNode();
                underlayingNode.CopyFromNode(node);
                return(underlayingNode);
            }

            if (node is BaseHexNode hexNode)
            {
                var arrayNode = new ArrayNode {
                    Count = hexNode.MemorySize
                };
                arrayNode.CopyFromNode(node);
                arrayNode.ChangeInnerNode(new Utf8CharacterNode());
                return(arrayNode);
            }

            return(node);
        }
Exemple #2
0
            static BaseNode CreatePaddingMember(int offset, int count)
            {
                var node = new ArrayNode
                {
                    Offset = offset,
                    Count  = count,
                    Name   = $"pad_{offset:X04}"
                };

                node.ChangeInnerNode(new Utf8CharacterNode());

                return(node);
            }
        /// <summary>
        /// Outputs the C++ code for the given nodes to the <see cref="TextWriter"/> instance.
        /// </summary>
        /// <param name="writer">The writer to output to.</param>
        /// <param name="nodes">The nodes to output.</param>
        /// <param name="logger">The logger.</param>
        private void WriteNodes(IndentedTextWriter writer, IEnumerable <BaseNode> nodes, ILogger logger)
        {
            Contract.Requires(writer != null);
            Contract.Requires(nodes != null);

            var fill      = 0;
            var fillStart = 0;

            BaseNode CreatePaddingMember(int offset, int count)
            {
                var node = new ArrayNode
                {
                    Offset = offset,
                    Count  = count,
                    Name   = $"pad_{offset:X04}"
                };

                node.ChangeInnerNode(new Utf8CharacterNode());

                return(node);
            }

            foreach (var member in nodes.WhereNot(m => m is VirtualMethodTableNode))
            {
                if (member is BaseHexNode)
                {
                    if (fill == 0)
                    {
                        fillStart = member.Offset;
                    }
                    fill += member.MemorySize;

                    continue;
                }

                if (fill != 0)
                {
                    WriteNode(writer, CreatePaddingMember(fillStart, fill), logger);

                    fill = 0;
                }

                WriteNode(writer, member, logger);
            }

            if (fill != 0)
            {
                WriteNode(writer, CreatePaddingMember(fillStart, fill), logger);
            }
        }
        public override BaseNode GetEquivalentNode(int count, ClassNode classNode)
        {
            var classInstanceNode = new ClassInstanceNode();

            classInstanceNode.ChangeInnerNode(classNode);

            var arrayNode = new ArrayNode {
                Count = count
            };

            arrayNode.ChangeInnerNode(classInstanceNode);
            arrayNode.CopyFromNode(this);

            return(arrayNode);
        }
        private static IEnumerable <string> GetTypeDeclerationsForNodes(IEnumerable <BaseNode> members, ILogger logger)
        {
            Contract.Requires(members != null);
            Contract.Requires(Contract.ForAll(members, m => m != null));
            Contract.Requires(logger != null);
            Contract.Ensures(Contract.Result <IEnumerable <string> >() != null);
            Contract.Ensures(Contract.ForAll(Contract.Result <IEnumerable <string> >(), d => d != null));

            int fill      = 0;
            int fillStart = 0;

            BaseNode CreatePaddingMember(int offset, int count)
            {
                var node = new ArrayNode
                {
                    Offset = (IntPtr)offset,
                    Count  = count,
                    Name   = $"pad_{offset:X04}"
                };

                node.ChangeInnerNode(new Utf8CharacterNode());

                return(node);
            }

            foreach (var member in members.WhereNot(m => m is VirtualMethodTableNode))
            {
                if (member is BaseHexNode)
                {
                    if (fill == 0)
                    {
                        fillStart = member.Offset.ToInt32();
                    }
                    fill += member.MemorySize;

                    continue;
                }

                if (fill != 0)
                {
                    yield return(GetTypeDeclerationForNode(CreatePaddingMember(fillStart, fill), logger));

                    fill = 0;
                }

                var definition = GetTypeDeclerationForNode(member, logger);
                if (definition != null)
                {
                    yield return(definition);
                }
                else
                {
                    logger.Log(LogLevel.Error, $"Skipping node with unhandled type: {member.GetType()}");
                }
            }

            if (fill != 0)
            {
                yield return(GetTypeDeclerationForNode(CreatePaddingMember(fillStart, fill), logger));
            }
        }