Added pointers and list handling in reader

This commit is contained in:
mm00
2025-03-10 19:09:11 +01:00
parent b6760ab27a
commit 37ebc71cf3
3 changed files with 85 additions and 7 deletions

View File

@@ -14,6 +14,9 @@
<Compile Include="..\CodeGenerator\BlendFile.cs">
<Link>BlendFile.cs</Link>
</Compile>
<Compile Include="..\CodeGenerator\StrExt.cs">
<Link>StrExt.cs</Link>
</Compile>
</ItemGroup>
</Project>

View File

@@ -1,6 +1,7 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using CodeGenerator;
using Kaitai;
using static Kaitai.BlendFile;
@@ -102,19 +103,42 @@ public class Reader {
blockOffset += t.GetCustomAttribute<DNAClassAttribute>()!.Size;
}
}
foreach (var obj in objects) {
foreach (var obj in objects) { // for each converted object
// get the fields of the object
FieldInfo[] fieldInfo = obj.Value.GetType().GetFields();
// get all fields that are pointers
var list = fieldInfo.Where(fldInfo => fldInfo.GetCustomAttribute<DNAFieldAttribute>()!.IsPointer).ToList();
// for each pointer field
foreach (var f in list) {
// get the pointer value
var addr = GetBlockFieldDataOffset(obj.Key.Item1, f.GetCustomAttribute<DNAFieldAttribute>()!.OriginalIndex,
fieldInfo);
// get the object that the pointer is pointing to if we've already converted it
var newobj = objects.GetValueOrDefault((addr, f.FieldType));
if (newobj != null) f.SetValue(obj.Value, newobj);
if (newobj != null)
f.SetValue(obj.Value, newobj);
else // if we haven't converted the object yet, we need to convert it now
{
newobj = ActivateInstance(f.FieldType);
if (newobj != null)
{
FillObject(addr, ref newobj, f.FieldType.GetFields());
f.SetValue(obj.Value, newobj);
Objects.Add((addr, f.FieldType), newobj);
} // should never happen
else throw new NotSupportedException($"Type \"{f.FieldType}\" is unknown");
}
}
}
foreach(var ptr in pointers) {
var obj = objects.GetValueOrDefault((ptr.Key, typeof(object)));
if (obj == null) continue;
InstantiatedObjects.Add(ptr.Key, obj);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private long GetBlockFieldDataOffset(long blockAddress, int fieldIndex, FieldInfo[] fieldMetadata) =>
blockAddress + GetFieldDataOffset(fieldIndex, fieldMetadata);
@@ -179,6 +203,15 @@ public class Reader {
objects.Add((block.MemAddr.ToPointer() + startOffset, obj!.GetType()), obj!);
}
private void FillObject(IntPtr ptr, ref object? obj, FieldInfo[] fieldMetadata)
{
var block = GetBlock(ptr.ToInt64());
if (block == null) throw new($"Block for pointer {ptr.ToInt64():X} not found");
var blockOffset = ptr.ToInt64() - block.MemAddr.ToPointer();
FillObject(block, ref obj, fieldMetadata, new IntPtr(blockOffset));
}
private object? ConvertNormalField(FileBlock block, DNAFieldAttribute attrib, IntPtr startOffset) {
//Calculate the offset from where the data of the field starts.
//Because the order of the fields is not guaranteed we need to compute it each time
@@ -219,11 +252,50 @@ public class Reader {
throw new NotSupportedException($"Unknown type \"{attrib.OriginalType}\"");
}
private object? ConvertListField(FileBlock block, FieldInfo field, DNAListAttribute attrib, IntPtr startOffset) {/*
IntPtr offset = attrib.MemoryOffset + startOffset;
int size = Array.Copy((byte[])block.Body, startOffset+attrib.)
var data = new byte[]*/
return null;
private object? ConvertListField(FileBlock block, FieldInfo field, DNAListAttribute attrib, IntPtr startOffset) {
IntPtr countOffset = attrib.CountMemoryOffset + startOffset;
IntPtr ptrOffset = attrib.PtrMemoryOffset + startOffset;
var countLen = attrib.CountFieldName.ParseFSize();
var countData = new byte[countLen];
Array.Copy((byte[])block.Body, countOffset, countData, 0, countLen);
var tmpCount = ConvertFieldData(countData, attrib.CountFieldName);
int count;
switch (tmpCount)
{
case int i:
count = i;
break;
case short s:
count = s;
break;
default:
throw new NotSupportedException($"Unknown type \"{attrib.CountFieldName}\"");
}
List<Object?> objList = new();
for(IntPtr ptr = ptrOffset; ptr < ptrOffset + count * sizeof(Int64); ptr += sizeof(Int64)) {
var data = new byte[sizeof(Int64)];
Array.Copy((byte[])block.Body, ptr, data, 0, sizeof(Int64));
IntPtr memAddr = new IntPtr(BitConverter.ToInt64(data, 0));
if (memAddr == IntPtr.Zero) {
objList.Add(null);
continue;
}
var obj = ActivateInstance(attrib.UnderlyingType);
if (obj == null) throw new NotSupportedException($"Type \"{attrib.UnderlyingType}\" is unknown");
var fieldMetadata = obj.GetType().GetFields();
FillObject(memAddr, ref obj, fieldMetadata);
objList.Add(obj);
}
return objList;
}
private object? ConvertFieldData(byte[] data, string type) {

View File

@@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AActivator_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F9a64357ccf6e3349d098262337b4a821dfc37ed653d94ada0a8859c6dde_003FActivator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArgumentException_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0beb96d31db641cf82014cb1a758a330b2dc00_003Fea_003F056794d0_003FArgumentException_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArgumentOutOfRangeException_002Ecs_002Fl_003AC_0021_003FUsers_003Fairon_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F72e5853ed6f2c1967eff9d6f0cf6ba12744c8978c516cbc5e74d992944ab_003FArgumentOutOfRangeException_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArray_002ECoreCLR_002Ecs_002Fl_003AC_0021_003FUsers_003Fairon_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fee3c9d264411441f56a12bac52a58ad25b495ef52e59b4a86f8478158f7d_003FArray_002ECoreCLR_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@@ -10,8 +11,10 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACSharpCodeGenerator_002Ecs_002Fl_003AC_0021_003FUsers_003Fairon_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F4aa9136c27fa69d6c91e9d8679c1a1d4b7aabee06e20d4405ee3d91ee05048f0_003FCSharpCodeGenerator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACSharpCodeGenerator_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F4aa9136c27fa69d6c91e9d8679c1a1d4b7aabee06e20d4405ee3d91ee05048f0_003FCSharpCodeGenerator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADefaultInterpolatedStringHandler_002Ecs_002Fl_003AC_0021_003FUsers_003Fairon_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fc1c946eaa6d8ddaaea1b63e936ca8ed2791d9316c5b025a41d445891e8a59ecd_003FDefaultInterpolatedStringHandler_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIntPtr_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F82ab53226b38d0ff1abfabfc5e951361c82d37b012cc2966b6358b4d6b5e7_003FIntPtr_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_002Ecs_002Fl_003AC_0021_003FUsers_003Fairon_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fb7208b3f72528d22781d25fde9a55271bdf2b5aade4f03b1324579a25493cd8_003FList_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARuntimeType_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F0beb96d31db641cf82014cb1a758a330b2dc00_003F5b_003F039af867_003FRuntimeType_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARuntimeType_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F7139fe40e31cec9ddaf3bf550e2d74b6564e2b3838816bf103f9f8063aa1fe8_003FRuntimeType_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASortedDictionary_002Ecs_002Fl_003AC_0021_003FUsers_003Fairon_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Febdb3cec3b3875204585daa9fc42159a24cae33b2087ff4dc114d0e6a5a3e9_003FSortedDictionary_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AStringBuilder_002Ecs_002Fl_003AC_0021_003FUsers_003Fairon_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fc6a25ea096494870a1dd94f188bc2634db58c9faa8b319e415cadf49b913d1a_003FStringBuilder_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003AC_0021_003FUsers_003Fairon_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F2c8e7ca976f350cba9836d5565dac56b11e0b56656fa786460eb1395857a6fa_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>