Esempio n. 1
0
        /// <summary>
        /// Gets the type definition for the given node. If the node is not expressible <c>null</c> as typename is returned.
        /// </summary>
        /// <param name="node">The target node.</param>
        /// <returns>The type definition for the node or null as typename if the node is not expressible.</returns>
        private static (string typeName, string attribute) GetTypeDefinition(BaseNode node)
        {
            Contract.Requires(node != null);

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

            if (nodeTypeToTypeDefinationMap.TryGetValue(node.GetType(), out var type))
            {
                return(type, null);
            }

            return(node switch
            {
                EnumNode enumNode => (enumNode.Enum.Name, null),
                Utf8TextNode utf8TextNode => ("string", $"[MarshalAs(UnmanagedType.ByValTStr, SizeConst = {utf8TextNode.Length})]"),
                Utf16TextNode utf16TextNode => (GetUnicodeStringClassName(utf16TextNode.Length), "[MarshalAs(UnmanagedType.Struct)]"),
                _ => (null, null)
            });
Esempio n. 2
0
        public static bool GuessNode(BaseHexNode node, IProcessReader reader, MemoryBuffer memory, out BaseNode guessedNode)
        {
            Contract.Requires(node != null);
            Contract.Requires(memory != null);

            guessedNode = null;

            var offset         = node.Offset;
            var is4ByteAligned = offset % 4 == 0;
            var is8ByteAligned = offset % 8 == 0;

            // The node is not aligned, skip it.
            if (!is4ByteAligned)
            {
                return(false);
            }

            var data64 = new UInt64FloatDoubleData
            {
                Raw1 = memory.ReadInt32(offset),
                Raw2 = memory.ReadInt32(offset + sizeof(int))
            };;
            var data32 = new UInt32FloatData
            {
                Raw = memory.ReadInt32(offset)
            };

            var raw = memory.ReadBytes(offset, node.MemorySize);

            if (raw.InterpretAsSingleByteCharacter().IsLikelyPrintableData())
            {
                guessedNode = new Utf8TextNode();

                return(true);
            }
            if (raw.InterpretAsDoubleByteCharacter().IsLikelyPrintableData())
            {
                guessedNode = new Utf16TextNode();

                return(true);
            }

#if RECLASSNET64
            if (is8ByteAligned)
            {
                if (GuessPointerNode(data64.IntPtr, reader, out guessedNode))
                {
                    return(true);
                }
            }
#else
            if (GuessPointerNode(data32.IntPtr, reader, out guessedNode))
            {
                return(true);
            }
#endif

            // 0 could be anything.
            if (data32.IntValue != 0)
            {
                // If the data represents a reasonable range, it could be a float.
                if (-999999.0f <= data32.FloatValue && data32.FloatValue <= 999999.0f && !data32.FloatValue.IsNearlyEqual(0.0f, 0.001f))
                {
                    guessedNode = new FloatNode();

                    return(true);
                }

                if (-999999 <= data32.IntValue && data32.IntValue <= 999999)
                {
                    guessedNode = new Int32Node();

                    return(true);
                }
            }

            if (is8ByteAligned)
            {
                if (data64.LongValue != 0)
                {
                    // If the data represents a reasonable range, it could be a double.
                    if (-999999.0 <= data64.DoubleValue && data64.DoubleValue <= 999999.0 && !data64.DoubleValue.IsNearlyEqual(0.0, 0.001))
                    {
                        guessedNode = new DoubleNode();

                        return(true);
                    }
                }
            }

            return(false);
        }