public void Deserialize(Stream input) { input.Seek(0, SeekOrigin.Begin); var magic = input.ReadValueU32(Endian.Big); if (magic != 0x47464620) { throw new FormatException(); } var version = input.ReadValueU32(Endian.Big); if (version != 0x56342E30 && // 4.0 version != 0x56342E31) // 4.1 { throw new FormatException("unsupported version"); } this.FileVersion = (byte)(version - 0x56342E30); this.FilePlatform = input.ReadValueEnum <GFF.FilePlatform>(Endian.Big); this.FormatType = input.ReadValueEnum <GFF.FormatType>(Endian.Big); this.FormatVersion = input.ReadValueU32(Endian.Big); var endian = this.FilePlatform == GFF.FilePlatform.PC ? Endian.Little : Endian.Big; var structCount = input.ReadValueU32(endian); var stringCount = this.FileVersion < 1 ? 0 : input.ReadValueU32(endian); var stringOffset = this.FileVersion < 1 ? 0 : input.ReadValueU32(endian); var dataOffset = input.ReadValueU32(endian); if (this.FileVersion < 1) { stringOffset = dataOffset; } else { if (dataOffset < stringOffset) { throw new FormatException(); } } this.Structures.Clear(); for (uint i = 0; i < structCount; i++) { var structDef = new GFF.StructureDefinition(); //structDef.Id = input.ReadValueU32(endian); structDef.Id = input.ReadValueU32(Endian.Big); var fieldCount = input.ReadValueU32(endian); var fieldOffset = input.ReadValueU32(endian); structDef.DataSize = input.ReadValueU32(endian); long nextOffset = input.Position; structDef.Fields.Clear(); input.Seek(fieldOffset, SeekOrigin.Begin); for (uint j = 0; j < fieldCount; j++) { var fieldDef = new GFF.FieldDefinition(); fieldDef.Id = input.ReadValueS32(endian); var rawFlags = input.ReadValueU32(endian); fieldDef.Offset = input.ReadValueU32(endian); var type = (ushort)(rawFlags & 0xFFFF); var flags = (GFF.FieldFlags)((rawFlags >> 16) & 0xFFFF); if ((flags & GFF.FieldFlags.IsStructure) != 0) { flags &= ~GFF.FieldFlags.IsStructure; fieldDef.Type = GFF.FieldType.Structure; fieldDef.StructureId = type; } else { fieldDef.Type = (GFF.FieldType)type; } fieldDef.Flags = flags; structDef.Fields.Add(fieldDef); } this.Structures.Add(structDef); input.Seek(nextOffset, SeekOrigin.Begin); } if (this.FileVersion >= 1) { input.Seek(stringOffset, SeekOrigin.Begin); this.StringTable = new List <string>(); for (uint i = 0; i < stringCount; i++) { this.StringTable.Add(input.ReadStringZ(Encoding.UTF8)); } } input.Seek(dataOffset, SeekOrigin.Begin); this.Data = input.ReadToMemoryStream(input.Length - dataOffset); }
public void Deserialize(Stream input) { input.Seek(0, SeekOrigin.Begin); var magic = input.ReadValueU32(false); if (magic != 0x47464620) { throw new FormatException(); } var version = input.ReadValueU32(false); if (version != 0x56342E30 && // 4.0 version != 0x56342E31) // 4.1 { throw new FormatException("unsupported version"); } this.FileVersion = (byte)(version - 0x56342E30); this.FilePlatform = input.ReadValueEnum<GFF.FilePlatform>(false); this.FormatType = input.ReadValueEnum<GFF.FormatType>(false); this.FormatVersion = input.ReadValueU32(false); var littleEndian = this.FilePlatform == GFF.FilePlatform.PC; var structCount = input.ReadValueU32(littleEndian); var stringCount = this.FileVersion < 1 ? 0 : input.ReadValueU32(littleEndian); var stringOffset = this.FileVersion < 1 ? 0 : input.ReadValueU32(littleEndian); var dataOffset = input.ReadValueU32(littleEndian); if (this.FileVersion < 1) { stringOffset = dataOffset; } else { if (dataOffset < stringOffset) { throw new FormatException(); } } this.Structures.Clear(); for (uint i = 0; i < structCount; i++) { var structDef = new GFF.StructureDefinition(); //structDef.Id = input.ReadValueU32(littleEndian); structDef.Id = input.ReadValueU32(false); var fieldCount = input.ReadValueU32(littleEndian); var fieldOffset = input.ReadValueU32(littleEndian); structDef.DataSize = input.ReadValueU32(littleEndian); long nextOffset = input.Position; structDef.Fields.Clear(); input.Seek(fieldOffset, SeekOrigin.Begin); for (uint j = 0; j < fieldCount; j++) { var fieldDef = new GFF.FieldDefinition(); fieldDef.Id = input.ReadValueS32(littleEndian); var rawFlags = input.ReadValueU32(littleEndian); fieldDef.Offset = input.ReadValueU32(littleEndian); var type = (ushort)(rawFlags & 0xFFFF); var flags = (GFF.FieldFlags)((rawFlags >> 16) & 0xFFFF); if ((flags & GFF.FieldFlags.IsStructure) != 0) { flags &= ~GFF.FieldFlags.IsStructure; fieldDef.Type = GFF.FieldType.Structure; fieldDef.StructureId = type; } else { fieldDef.Type = (GFF.FieldType)type; } fieldDef.Flags = flags; structDef.Fields.Add(fieldDef); } this.Structures.Add(structDef); input.Seek(nextOffset, SeekOrigin.Begin); } if (this.FileVersion >= 1) { input.Seek(stringOffset, SeekOrigin.Begin); this.StringTable = new List<string>(); for (uint i = 0; i < stringCount; i++) { this.StringTable.Add(input.ReadStringZ(Encoding.UTF8)); } } input.Seek(dataOffset, SeekOrigin.Begin); this.Data = input.ReadToMemoryStream(input.Length - dataOffset); }