protected object ParseProperty(CR2WBinaryReader br, Type proptype) { //Basic / Value Types switch (proptype.Name) { case "Byte": return(br.ReadByte()); case "UInt16": return(br.ReadUInt16()); case "UInt32": return(br.ReadUInt32()); case "UInt64": return(br.ReadUInt64()); case "SByte": return(br.ReadSByte()); case "Int16": return(br.ReadInt16()); case "Int32": return(br.ReadInt32()); case "Int64": return(br.ReadInt64()); case "Boolean": return(br.ReadBoolean()); case "Single": return(br.ReadSingle()); case "Double": return(br.ReadDouble()); case "CName": return(br.ReadCName()); case "CGUID": return(br.ReadCGUID()); case "IdTag": return(br.ReadIdTag()); case "TagList": return(br.ReadTagList()); case "EngineTransform": return(br.ReadEngineTransform()); case "EngineQsTransform": return(br.ReadEngineQsTransform()); case "CDateTime": return(br.ReadCDateTime()); case "String": return(br.ReadStringDefaultSingle()); } //Parse Enumarators if (proptype.IsEnum) { return(br.ReadEnumarator(proptype)); } //Parse Generic Types (Array, Soft, Ptr, Handle) if (proptype.IsGenericType) { var instance = Activator.CreateInstance(proptype); var genprop = proptype.GetTypeInfo().GenericTypeArguments[0]; if (proptype.GetGenericTypeDefinition() == typeof(Array <>)) { var length = br.ReadUInt32(); for (int i = 0; i < length; i++) { var value = ParseProperty(br, genprop); proptype.GetMethod("Add").Invoke(instance, new[] { value }); } return(instance); } else if (proptype.GetGenericTypeDefinition() == typeof(Soft <>)) { var id = br.ReadUInt16() - 1; if (br.resources[id].type != genprop.Name) { throw new InvalidOperationException($"Soft type mistatch. Expected Type: {genprop.Name}. Type Read: {br.resources[id].type}."); } proptype.GetProperty("DepotPath").SetValue(instance, br.resources[id].path); proptype.GetProperty("Flags").SetValue(instance, br.resources[id].flags); return(instance); } } //Parse classes if (proptype.IsClass) { var instance = Activator.CreateInstance(proptype); ParseClass(br, instance); return(instance); } //Any Unknown Type //Should be impossible to reach if all types get covered above. return(null); }