diff --git a/BlendFile/Reader.cs b/BlendFile/Reader.cs index 3dc2e79..f4f50a6 100644 --- a/BlendFile/Reader.cs +++ b/BlendFile/Reader.cs @@ -28,57 +28,51 @@ public class Reader { foreach (var block in blend.Blocks) { + //We need to read all blocks of data regardeless of the type //if (block.Code != "DATA") continue; + //Checks if the block has a known SDNA type, meaning that we know how it is structured if(!dnaTypes.ContainsKey((int)block.SdnaIndex)) continue; - Type t = dnaTypes.Values.First(x => - x.GetCustomAttribute()!.OriginalName == block.SdnaStruct.Type); - + Type t = dnaTypes.Values.First( + x => x.GetCustomAttribute()!.OriginalName == block.SdnaStruct.Type); + // How many objects are in the block var count = block.Count; + //offset for the next object in the block var blockOffset = 0; + //for each expected object in the block for(var i=0; i(); - if (attrib == null) continue; + if(obj == null) continue; //should never happen + objects.Add(obj); //add the object to the list of objects - var offset = fields.Where(f => f.GetCustomAttribute()!.OriginalIndex < attrib.OriginalIndex) - .Sum(f => f.GetCustomAttribute()!.Size) + blockOffset; - var size = attrib.Size; - - byte[] data = new byte[size]; - Array.Copy((byte[])block.Body, offset, data, 0, size); - - var value = ConvertFieldData(data, attrib.OriginalType); - if(value == null) continue; - - field.SetValue(obj, value); - } - + //fill the object with the data from the block + FillObject(block, ref obj, t.GetFields(), blockOffset); + //move the offset to the next object in the block blockOffset += t.GetCustomAttribute()!.Size; } } } + + private void FillObject(Kaitai.BlendFile.FileBlock block, ref object obj, FieldInfo[] fieldMetadata, int startOffset = 0) { + foreach (var field in fieldMetadata) { + var attrib = field.GetCustomAttribute(); + if (attrib == null) continue; + + int offset = fieldMetadata.Where(f => f.GetCustomAttribute()!.OriginalIndex < attrib.OriginalIndex) + .Sum(f => f.GetCustomAttribute()!.Size) + startOffset; + int size = attrib.Size; + + var data = new byte[size]; + Array.Copy((byte[])block.Body, offset, data, 0, size); + + object? value = ConvertFieldData(data, attrib.OriginalType); + if(value == null) continue; + + field.SetValue(obj, value); + } + } - /* - * "char" => typeof(char).AssemblyQualifiedName, - "short" => typeof(short).AssemblyQualifiedName, - "int" => typeof(int).AssemblyQualifiedName, - "float" => typeof(float).AssemblyQualifiedName, - "double" => typeof(double).AssemblyQualifiedName, - "string" => typeof(string).AssemblyQualifiedName, - "void" => typeof(object).AssemblyQualifiedName, - "ushort" => typeof(ushort).AssemblyQualifiedName, - "uchar" => typeof(byte).AssemblyQualifiedName, - "int64_t" => typeof(long).AssemblyQualifiedName, - "int8_t" => typeof(sbyte).AssemblyQualifiedName, - "uint64_t" => typeof(ulong).AssemblyQualifiedName, - */ private object? ConvertFieldData(byte[] data, string type) { return type switch