/// <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); }
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)); } }