コード例 #1
0
        internal static int ReadArrayLength(MemorySection[] heap, UInt64 address, TypeDescription arrayType, VirtualMachineInformation virtualMachineInformation)
        {
            BytesAndOffset bo = heap.Find(address, virtualMachineInformation);

            UInt64 bounds = bo.Add(virtualMachineInformation.arrayBoundsOffsetInHeader).ReadPointer();

            if (bounds == 0)
#if UNITY_2017_2_OR_NEWER
            { return((int)bo.Add(virtualMachineInformation.arraySizeOffsetInHeader).ReadPointer()); }
#else
            { return(bo.Add(virtualMachineInformation.arraySizeOffsetInHeader).ReadInt32()); }
#endif

            BytesAndOffset cursor = heap.Find(bounds, virtualMachineInformation);
            int            length = 1;
            for (int i = 0; i != arrayType.arrayRank; i++)
            {
#if UNITY_2017_2_OR_NEWER
                length *= (int)cursor.ReadPointer();
                cursor  = cursor.Add(virtualMachineInformation.pointerSize == 4 ? 8 : 16);
#else
                length *= cursor.ReadInt32();
                cursor  = cursor.Add(8);
#endif
            }
            return(length);
        }
コード例 #2
0
        public static int ReadStringObjectSizeInBytes(BytesAndOffset bo, VirtualMachineInformation virtualMachineInformation)
        {
            var lengthPointer = bo.Add(virtualMachineInformation.objectHeaderSize);
            var length        = lengthPointer.ReadInt32();

            return(virtualMachineInformation.objectHeaderSize + /*lengthfield*/ 1 + (length * /*utf16=2bytes per char*/ 2) + /*2 zero terminators*/ 2);
        }
コード例 #3
0
ファイル: Crawler.cs プロジェクト: swordlegend/MemoryProfiler
        private void ParseObjectHeader(StartIndices startIndices, MemorySection[] heap, ulong originalHeapAddress, out ulong typeInfoAddress, out int indexOfObject, out bool wasAlreadyCrawled, List <PackedManagedObject> outManagedObjects)
        {
            BytesAndOffset bo = heap.Find(originalHeapAddress, _virtualMachineInformation);

            UInt64         pointer1 = bo.ReadPointer();
            BytesAndOffset pointer2 = bo.NextPointer();

            if (HasMarkBit(pointer1) == 0)
            {
                TypeDescription typeDescription = GetTypeDescription(heap, pointer1);

                wasAlreadyCrawled = false;
                indexOfObject     = outManagedObjects.Count + startIndices.OfFirstManagedObject;
                typeInfoAddress   = typeDescription.typeInfoAddress;

                int size = SizeOfObjectInBytes(typeDescription, bo, heap, originalHeapAddress);

                outManagedObjects.Add(new PackedManagedObject()
                {
                    address = originalHeapAddress, size = size, typeIndex = typeDescription.typeIndex
                });

                //okay, we gathered all information, now lets set the mark bit, and store the index for this object in the 2nd pointer of the header, which is rarely used.
                bo.WritePointer(pointer1 | 1);
                pointer2.WritePointer((ulong)indexOfObject);
                return;
            }

            //give typeinfo address back without the markbit
            typeInfoAddress   = ClearMarkBit(pointer1);
            wasAlreadyCrawled = true;
            //read the index for this object that we stored in the 2ndpointer field of the header
            indexOfObject = (int)pointer2.ReadPointer();
        }
コード例 #4
0
ファイル: Crawler.cs プロジェクト: swordlegend/MemoryProfiler
        private void CrawlPointerNonRecursive(PackedMemorySnapshot packedMemorySnapshot, StartIndices startIndices, ulong pointer, int indexOfFrom, List <Connection> out_connections, List <PackedManagedObject> out_managedObjects, Stack <ThingToProfile> out_thingsToProfile)
        {
            BytesAndOffset bo = packedMemorySnapshot.managedHeapSections.Find(pointer, _virtualMachineInformation);

            if (!bo.IsValid)
            {
                return;
            }

            UInt64 typeInfoAddress;
            int    indexOfObject;
            bool   wasAlreadyCrawled;

            try
            {
                ParseObjectHeader(startIndices, packedMemorySnapshot.managedHeapSections, pointer, out typeInfoAddress, out indexOfObject, out wasAlreadyCrawled, out_managedObjects);
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogWarningFormat("Exception parsing object header. Skipping. {0}", e);
                return;
            }

            out_connections.Add(new Connection()
            {
                from = indexOfFrom, to = indexOfObject
            });

            if (wasAlreadyCrawled)
            {
                return;
            }

            TypeDescription typeDescription = _typeInfoToTypeDescription[typeInfoAddress];

            if (!typeDescription.isArray)
            {
                out_thingsToProfile.Push(new ThingToProfile(typeDescription, bo.Add(_virtualMachineInformation.objectHeaderSize), false, indexOfObject));
                return;
            }

            int             arrayLength = ArrayTools.ReadArrayLength(packedMemorySnapshot.managedHeapSections, pointer, typeDescription, _virtualMachineInformation);
            TypeDescription elementType = packedMemorySnapshot.typeDescriptions[typeDescription.baseOrElementTypeIndex];
            BytesAndOffset  cursor      = bo.Add(_virtualMachineInformation.arrayHeaderSize);

            for (int i = 0; i != arrayLength; i++)
            {
                if (elementType.isValueType)
                {
                    out_thingsToProfile.Push(new ThingToProfile(elementType, cursor, false, indexOfObject));
                    cursor = cursor.Add(elementType.size);
                }
                else
                {
                    out_thingsToProfile.Push(new ThingToProfile(cursor.ReadPointer(), indexOfObject));
                    cursor = cursor.NextPointer();
                }
            }
        }
コード例 #5
0
        public static string ReadString(BytesAndOffset bo, VirtualMachineInformation virtualMachineInformation)
        {
            var lengthPointer = bo.Add(virtualMachineInformation.objectHeaderSize);
            var length        = lengthPointer.ReadInt32();
            var firstChar     = lengthPointer.Add(4);

            return(System.Text.Encoding.Unicode.GetString(firstChar.bytes, firstChar.offset, length * 2));
        }
コード例 #6
0
ファイル: Crawler.cs プロジェクト: swordlegend/MemoryProfiler
 internal ThingToProfile(TypeDescription typeDesc, BytesAndOffset inBytesAndOffset, bool inUseStaticFields, int inIndexOfFrom)
 {
     type            = PointerType.RawPointer;
     typeDescription = typeDesc;
     bytesAndOffset  = inBytesAndOffset;
     useStaticFields = inUseStaticFields;
     indexOfFrom     = inIndexOfFrom;
     objectPointer   = 0;
 }
コード例 #7
0
ファイル: Crawler.cs プロジェクト: iuvei/17mj
 public ThingToProfile(TypeDescription typeDesc, BytesAndOffset inBytesAndOffset, bool inUseStaticFields, int inIndexOfFrom)
 {
     type            = PointerType.Reference;
     typeDescription = typeDesc;
     bytesAndOffset  = inBytesAndOffset;
     useStaticFields = inUseStaticFields;
     indexOfFrom     = inIndexOfFrom;
     object_offset   = 0;
 }
コード例 #8
0
ファイル: Crawler.cs プロジェクト: swordlegend/MemoryProfiler
        internal ThingToProfile(ulong objectPtr, int refIndexOfFrom)
        {
            type          = PointerType.Reference;
            objectPointer = objectPtr;
            indexOfFrom   = refIndexOfFrom;

            useStaticFields = true;
            typeDescription = new TypeDescription();
            bytesAndOffset  = new BytesAndOffset();
        }
コード例 #9
0
ファイル: Crawler.cs プロジェクト: iuvei/17mj
        public ThingToProfile(ulong refOffset, int refIndexOfFrom)
        {
            type          = PointerType.Reference;
            object_offset = refOffset;
            indexOfFrom   = refIndexOfFrom;

            useStaticFields = true;
            typeDescription = new TypeDescription();
            bytesAndOffset  = new BytesAndOffset();
        }
コード例 #10
0
 public UInt64 ReadPointer(BytesAndOffset bo)
 {
     if (_virtualMachineInformation.pointerSize == 4)
     {
         return(ReadUInt32(bo));
     }
     else
     {
         return(ReadUInt64(bo));
     }
 }
コード例 #11
0
ファイル: TreeMapView.cs プロジェクト: vinhphu3000/mg01
        private string DumpFields(TypeDescription typeDescription, BytesAndOffset bytesAndOffset, bool useStatics = false)
        {
            var str = new StringBuilder();

            foreach (var field in TypeTools.AllFieldsOf(typeDescription, _unpackedCrawl.typeDescriptions, useStatics ? TypeTools.FieldFindOptions.OnlyStatic : TypeTools.FieldFindOptions.OnlyInstance))
            {
                str.AppendFormat("\t\t\t{0}\n", field.name);
                // str.Append(DumpValueFor(field, bytesAndOffset.Add(field.offset)));
            }
            return(str.ToString());
        }
コード例 #12
0
ファイル: Crawler.cs プロジェクト: xingwen93/Xlua_UGUI_Demo
        int SizeOfObjectInBytes(TypeDescription typeDescription, BytesAndOffset bo, MemorySection[] heap, ulong address)
        {
            if (typeDescription.isArray)
            {
                return(ArrayTools.ReadArrayObjectSizeInBytes(heap, address, typeDescription, _typeDescriptions, _virtualMachineInformation));
            }

            if (typeDescription.name == "System.String")
            {
                return(StringTools.ReadStringObjectSizeInBytes(bo, _virtualMachineInformation));
            }

            //array and string are the only types that are special, all other types just have one size, which is stored in the typedescription
            return(typeDescription.size);
        }
コード例 #13
0
ファイル: Crawler.cs プロジェクト: swordlegend/MemoryProfiler
        private TypeDescription GetTypeDescription(MemorySection[] heap, ulong objectAddress)
        {
            TypeDescription typeDescription;

            // IL2CPP has the class pointer as the first member of the object.
            if (!_typeInfoToTypeDescription.TryGetValue(objectAddress, out typeDescription))
            {
                // Mono has a vtable pointer as the first member of the object.
                // The first member of the vtable is the class pointer.
                BytesAndOffset vtable             = heap.Find(objectAddress, _virtualMachineInformation);
                UInt64         vtableClassPointer = vtable.ReadPointer();
                typeDescription = _typeInfoToTypeDescription[vtableClassPointer];
            }

            return(typeDescription);
        }
コード例 #14
0
ファイル: Crawler.cs プロジェクト: swordlegend/MemoryProfiler
        private TypeDescription RestoreObjectHeader(MemorySection[] heaps, ulong address, int managedObjectIndex)
        {
            BytesAndOffset bo              = heaps.Find(address, _virtualMachineInformation);
            UInt64         mask            = this._virtualMachineInformation.pointerSize == 8 ? System.UInt64.MaxValue - 1 : System.UInt32.MaxValue - 1;
            UInt64         pointer         = bo.ReadPointer();
            UInt64         typeInfoAddress = pointer & mask;

            bo.WritePointer(typeInfoAddress);

            UInt64 restoreValue = 0;

            _pointer2Backups.TryGetValue(managedObjectIndex, out restoreValue);
            bo.NextPointer().WritePointer(restoreValue);

            return(GetTypeDescription(heaps, typeInfoAddress));
        }
コード例 #15
0
ファイル: Crawler.cs プロジェクト: swordlegend/MemoryProfiler
        private void CrawlRawObjectDataNonRecursive(PackedMemorySnapshot packedMemorySnapshot, StartIndices startIndices, BytesAndOffset bytesAndOffset, TypeDescription typeDescription, bool useStaticFields, int indexOfFrom,
                                                    List <Connection> out_connections, List <PackedManagedObject> out_managedObjects, Stack <ThingToProfile> out_thingsToProfile)
        {
            // Do not crawl MemoryProfilerWindow objects
            if (typeDescription.name.StartsWith("MemoryProfilerWindow."))
            {
                return;
            }

            FieldDescription[] fields = useStaticFields ? _staticFields[typeDescription.typeIndex] : _instanceFields[typeDescription.typeIndex];

            for (int i = 0; i < fields.Length; ++i)
            {
                FieldDescription field         = fields[i];
                TypeDescription  fieldType     = packedMemorySnapshot.typeDescriptions[field.typeIndex];
                BytesAndOffset   fieldLocation = bytesAndOffset.Add(field.offset - (useStaticFields ? 0 : _virtualMachineInformation.objectHeaderSize));

                if (fieldType.isValueType)
                {
                    out_thingsToProfile.Push(new ThingToProfile(fieldType, fieldLocation, false, indexOfFrom));

                    continue;
                }
                else
                {
                    //temporary workaround for a bug in 5.3b4 and earlier where we would get literals returned as fields with offset 0. soon we'll be able to remove this code.
                    bool gotException = false;
                    try
                    {
                        fieldLocation.ReadPointer();
                    }
                    catch (ArgumentException)
                    {
                        UnityEngine.Debug.LogWarningFormat("Skipping field {0} on type {1}", field.name, typeDescription.name);
                        UnityEngine.Debug.LogWarningFormat("FieldType.name: {0}", fieldType.name);
                        gotException = true;
                    }

                    if (!gotException)
                    {
                        out_thingsToProfile.Push(new ThingToProfile(fieldLocation.ReadPointer(), indexOfFrom));
                    }
                }
            }
        }
コード例 #16
0
        private void DrawFields(TypeDescription typeDescription, BytesAndOffset bytesAndOffset, bool useStatics = false)
        {
            int counter = 0;

            foreach (var field in TypeTools.AllFieldsOf(typeDescription, _unpackedCrawl.typeDescriptions, useStatics ? TypeTools.FieldFindOptions.OnlyStatic : TypeTools.FieldFindOptions.OnlyInstance))
            {
                counter++;
                var gUIStyle = counter % 2 == 0 ? Styles.entryEven : Styles.entryOdd;
                gUIStyle.margin   = new RectOffset(0, 0, 0, 0);
                gUIStyle.overflow = new RectOffset(0, 0, 0, 0);
                gUIStyle.padding  = EditorStyles.label.padding;
                GUILayout.BeginHorizontal(gUIStyle);
                GUILayout.Label(field.name, labelWidth);
                GUILayout.BeginVertical();
                DrawValueFor(field, bytesAndOffset.Add(field.offset));
                GUILayout.EndVertical();
                GUILayout.EndHorizontal();
            }
        }
コード例 #17
0
ファイル: Crawler.cs プロジェクト: xingwen93/Xlua_UGUI_Demo
        private void CrawlRawObjectData(PackedMemorySnapshot packedMemorySnapshot, StartIndices startIndices, BytesAndOffset bytesAndOffset, TypeDescription typeDescription, bool useStaticFields, int indexOfFrom, List <Connection> out_connections, List <PackedManagedObject> out_managedObjects)
        {
            var fields = useStaticFields ? _staticFields[typeDescription.typeIndex] : _instanceFields[typeDescription.typeIndex];

            foreach (var field in fields)
            {
                var fieldType     = packedMemorySnapshot.typeDescriptions[field.typeIndex];
                var fieldLocation = bytesAndOffset.Add(field.offset - (useStaticFields ? 0 : _virtualMachineInformation.objectHeaderSize));

                if (fieldType.isValueType)
                {
                    CrawlRawObjectData(packedMemorySnapshot, startIndices, fieldLocation, fieldType, false, indexOfFrom, out_connections, out_managedObjects);

                    continue;
                }

                //temporary workaround for a bug in 5.3b4 and earlier where we would get literals returned as fields with offset 0. soon we'll be able to remove this code.
                bool gotException = false;
                try
                {
                    fieldLocation.ReadPointer();
                }
                catch (ArgumentException)
                {
                    UnityEngine.Debug.LogWarningFormat("Skipping field {0} on type {1}", field.name, typeDescription.name);
                    UnityEngine.Debug.LogWarningFormat("FieldType.name: {0}", fieldType.name);
                    gotException = true;
                }

                if (!gotException)
                {
                    CrawlPointer(packedMemorySnapshot, startIndices, fieldLocation.ReadPointer(), indexOfFrom, out_connections, out_managedObjects);
                }
            }
        }
コード例 #18
0
 public System.Int64 ReadInt64(BytesAndOffset bo)
 {
     return(BitConverter.ToInt64(bo.bytes, bo.offset));
 }
コード例 #19
0
 public System.UInt16 ReadUInt16(BytesAndOffset bo)
 {
     return(BitConverter.ToUInt16(bo.bytes, bo.offset));
 }
コード例 #20
0
        private void DrawValueFor(FieldDescription field, BytesAndOffset bytesAndOffset)
        {
            var typeDescription = _unpackedCrawl.typeDescriptions[field.typeIndex];

            try
            {
                switch (typeDescription.name)
                {
                case "System.Int32":
                    GUILayout.Label(_primitiveValueReader.ReadInt32(bytesAndOffset).ToString());
                    break;

                case "System.Int64":
                    GUILayout.Label(_primitiveValueReader.ReadInt64(bytesAndOffset).ToString());
                    break;

                case "System.UInt32":
                    GUILayout.Label(_primitiveValueReader.ReadUInt32(bytesAndOffset).ToString());
                    break;

                case "System.UInt64":
                    GUILayout.Label(_primitiveValueReader.ReadUInt64(bytesAndOffset).ToString());
                    break;

                case "System.Int16":
                    GUILayout.Label(_primitiveValueReader.ReadInt16(bytesAndOffset).ToString());
                    break;

                case "System.UInt16":
                    GUILayout.Label(_primitiveValueReader.ReadUInt16(bytesAndOffset).ToString());
                    break;

                case "System.Byte":
                    GUILayout.Label(_primitiveValueReader.ReadByte(bytesAndOffset).ToString());
                    break;

                case "System.SByte":
                    GUILayout.Label(_primitiveValueReader.ReadSByte(bytesAndOffset).ToString());
                    break;

                case "System.Char":
                    GUILayout.Label(_primitiveValueReader.ReadChar(bytesAndOffset).ToString());
                    break;

                case "System.Boolean":
                    GUILayout.Label(_primitiveValueReader.ReadBool(bytesAndOffset).ToString());
                    break;

                case "System.Single":
                    GUILayout.Label(_primitiveValueReader.ReadSingle(bytesAndOffset).ToString());
                    break;

                case "System.Double":
                    GUILayout.Label(_primitiveValueReader.ReadDouble(bytesAndOffset).ToString());
                    break;

                case "System.IntPtr":
                    GUILayout.Label(_primitiveValueReader.ReadPointer(bytesAndOffset).ToString("X"));
                    break;

                default:
                    if (!typeDescription.isValueType)
                    {
                        ThingInMemory item = GetThingAt(bytesAndOffset.ReadPointer());
                        if (item == null)
                        {
                            EditorGUI.BeginDisabledGroup(true);
                            GUILayout.Button("Null");
                            EditorGUI.EndDisabledGroup();
                        }
                        else
                        {
                            DrawLinks(new ThingInMemory[] { item });
                        }
                    }
                    else
                    {
                        DrawFields(typeDescription, bytesAndOffset);
                    }
                    break;
                }
            }
            catch (Exception ex)
            {
                GUILayout.Label(string.Format("<bad_entry> type: {0}, len: {1}, offset: {2}, ex: {3}", typeDescription.name, bytesAndOffset.bytes.Length, bytesAndOffset.offset, ex.GetType().Name));
                Debug.LogFormat("<bad_entry> type: {0}, len: {1}, offset: {2}, ex: {3}", typeDescription.name, bytesAndOffset.bytes.Length, bytesAndOffset.offset, ex.GetType().Name);
            }
        }
コード例 #21
0
 public System.Byte ReadByte(BytesAndOffset bo)
 {
     return(bo.bytes[bo.offset]);
 }
コード例 #22
0
ファイル: Crawler.cs プロジェクト: zhuoweip/FrameScript
        private void CrawlRawObjectData(PackedMemorySnapshot packedMemorySnapshot, StartIndices startIndices, BytesAndOffset bytesAndOffset, TypeDescription typeDescription, bool useStaticFields, int indexOfFrom, List <Connection> out_connections, List <PackedManagedObject> out_managedObjects)
        {
            foreach (var field in TypeTools.AllFieldsOf(typeDescription, _typeDescriptions, useStaticFields ? TypeTools.FieldFindOptions.OnlyStatic : TypeTools.FieldFindOptions.OnlyInstance))
            {
                if (field.typeIndex == typeDescription.typeIndex && typeDescription.isValueType)
                {
                    //this happens in System.Single, which is a weird type that has a field of its own type.
                    continue;
                }

                if (field.offset == -1)
                {
                    //this is how we encode TLS fields. todo: actually treat TLS fields as roots
                    continue;
                }

                var fieldType = packedMemorySnapshot.typeDescriptions[field.typeIndex];

                var fieldLocation = bytesAndOffset.Add(field.offset - (useStaticFields ? 0 : _virtualMachineInformation.objectHeaderSize));

                if (fieldType.isValueType)
                {
                    CrawlRawObjectData(packedMemorySnapshot, startIndices, fieldLocation, fieldType, false, indexOfFrom, out_connections, out_managedObjects);
                    continue;
                }

                //temporary workaround for a bug in 5.3b4 and earlier where we would get literals returned as fields with offset 0. soon we'll be able to remove this code.
                bool gotException = false;
                try
                {
                    fieldLocation.ReadPointer();
                }
                catch (ArgumentException)
                {
                    UnityEngine.Debug.LogWarningFormat("Skipping field {0} on type {1}", field.name, typeDescription.name);
                    UnityEngine.Debug.LogWarningFormat("FieldType.name: {0}", fieldType.name);
                    gotException = true;
                }

                if (!gotException)
                {
                    CrawlPointer(packedMemorySnapshot, startIndices, fieldLocation.ReadPointer(), indexOfFrom, out_connections, out_managedObjects);
                }
            }
        }
コード例 #23
0
 public System.SByte ReadSByte(BytesAndOffset bo)
 {
     return((System.SByte)bo.bytes[bo.offset]);
 }
コード例 #24
0
 public System.Boolean ReadBool(BytesAndOffset bo)
 {
     return(ReadByte(bo) != 0);
 }
コード例 #25
0
 public Char ReadChar(BytesAndOffset bytesAndOffset)
 {
     return(System.Text.Encoding.Unicode.GetChars(bytesAndOffset.bytes, bytesAndOffset.offset, 2)[0]);
 }
コード例 #26
0
 public System.Single ReadSingle(BytesAndOffset bytesAndOffset)
 {
     return(BitConverter.ToSingle(bytesAndOffset.bytes, bytesAndOffset.offset));
 }
コード例 #27
0
 internal System.Byte ReadByte(BytesAndOffset bo)
 {
     return(bo.bytes[bo.offset]);
 }
コード例 #28
0
 public System.Double ReadDouble(BytesAndOffset bytesAndOffset)
 {
     return(BitConverter.ToDouble(bytesAndOffset.bytes, bytesAndOffset.offset));
 }
コード例 #29
0
        private void DrawValueFor(FieldDescription field, BytesAndOffset bytesAndOffset)
        {
            var typeDescription = _unpackedCrawl.typeDescriptions[field.typeIndex];

            switch (typeDescription.name)
            {
            case "System.Int32":
                GUILayout.Label(_primitiveValueReader.ReadInt32(bytesAndOffset).ToString());
                break;

            case "System.Int64":
                GUILayout.Label(_primitiveValueReader.ReadInt64(bytesAndOffset).ToString());
                break;

            case "System.UInt32":
                GUILayout.Label(_primitiveValueReader.ReadUInt32(bytesAndOffset).ToString());
                break;

            case "System.UInt64":
                GUILayout.Label(_primitiveValueReader.ReadUInt64(bytesAndOffset).ToString());
                break;

            case "System.Int16":
                GUILayout.Label(_primitiveValueReader.ReadInt16(bytesAndOffset).ToString());
                break;

            case "System.UInt16":
                GUILayout.Label(_primitiveValueReader.ReadUInt16(bytesAndOffset).ToString());
                break;

            case "System.Byte":
                GUILayout.Label(_primitiveValueReader.ReadByte(bytesAndOffset).ToString());
                break;

            case "System.SByte":
                GUILayout.Label(_primitiveValueReader.ReadSByte(bytesAndOffset).ToString());
                break;

            case "System.Char":
                GUILayout.Label(_primitiveValueReader.ReadChar(bytesAndOffset).ToString());
                break;

            case "System.Boolean":
                GUILayout.Label(_primitiveValueReader.ReadBool(bytesAndOffset).ToString());
                break;

            case "System.Single":
                GUILayout.Label(_primitiveValueReader.ReadSingle(bytesAndOffset).ToString());
                break;

            case "System.Double":
                GUILayout.Label(_primitiveValueReader.ReadDouble(bytesAndOffset).ToString());
                break;

            case "System.IntPtr":
                GUILayout.Label(_primitiveValueReader.ReadPointer(bytesAndOffset).ToString("X"));
                break;

            default:

                if (!typeDescription.isValueType)
                {
                    ThingInMemory item = GetThingAt(bytesAndOffset.ReadPointer());
                    if (item == null)
                    {
                        EditorGUI.BeginDisabledGroup(true);
                        GUILayout.Button("Null");
                        EditorGUI.EndDisabledGroup();
                    }
                    else
                    {
                        DrawLinks(new ThingInMemory[] { item });
                    }
                }
                else
                {
                    DrawFields(typeDescription, bytesAndOffset);
                }
                break;
            }
        }
コード例 #30
0
 internal System.Int16 ReadInt16(BytesAndOffset bo)
 {
     return(BitConverter.ToInt16(bo.bytes, bo.offset));
 }