/// <summary> /// Creates a Structure filled with data. /// </summary> /// <param name="data">Bytestream representing the data to be filled.</param> /// <param name="template">Structure prototype that matches the bytestream.</param> /// <param name="file">Source file object.</param> protected Structure(byte[] data, StructureDefinition template, BlenderFile file) { // since this is a root structure, set its name to the type name (as an identification) and // Value to the type name (as expected by IField) Name = Value = TypeName = template.StructureTypeName; // roots have no parents Parent = null; Size = template.StructureTypeSize; List <IField> fields = new List <IField>(); int pos = 0; this.ContainingFile = file; parseStructureFields(this, template, data, ref fields, ref pos); // begin recursive parsing Fields = fields.ToArray(); }
/// <summary> /// Parses a file block. If the file block is SDNA or another block with block.count == 0, it will return null. /// </summary> /// <param name="block">The block to parse.</param> /// <param name="blocksParsed">Number of blocks parsed so far.</param> /// <param name="file">Source file for the structures.</param> /// <returns>An array of PopulatedStructures, or { null } if no structures are defined.</returns> public static Structure[] ParseFileBlock(FileBlock block, int blocksParsed, BlenderFile file) { if (block.Count == 0 || block.Code == "DNA1") { return(null); } StructureDNA sdna = file.StructureDNA; if (block.Data.Length != sdna.StructureList[block.SDNAIndex].StructureTypeSize * block.Count) { // generally, these are things like raw data; packed files, preview images, and arrays of pointers that are themselves pointed to. // I have no idea what TEST and REND do. file.RawBlockMessages.Add(blocksParsed + " " + block.OldMemoryAddress.ToString("X" + (file.PointerSize * 2)) + " " + block.Code + " " + block.SDNAIndex + " " + sdna.StructureList[block.SDNAIndex].StructureTypeSize * block.Count + " " + block.Data.Length); return(null); } Structure[] output = new Structure[block.Count]; if (block.Count > 1) { for (int i = 0; i < block.Count; i++) { byte[] data = new byte[block.Size / block.Count]; for (int j = 0; j < block.Size / block.Count; j++) { data[j] = block.Data[i * (block.Size / block.Count) + j]; } output[i] = new Structure(data, sdna.StructureList[block.SDNAIndex], file); output[i].Size = sdna.StructureList[block.SDNAIndex].StructureTypeSize; output[i].TypeName = sdna.StructureList[block.SDNAIndex].StructureTypeName; output[i].ContainingBlock = block; } } else { output[0] = new Structure(block.Data, sdna.StructureList[block.SDNAIndex], file); output[0].Size = sdna.StructureList[block.SDNAIndex].StructureTypeSize; output[0].TypeName = sdna.StructureList[block.SDNAIndex].StructureTypeName; output[0].ContainingBlock = block; } return(output); }