public void Deserialize(Stream input, Endian endian, IStringTable stringTable) { var nameIndex = input.ReadValueU32(endian); this.Name = stringTable.Get(nameIndex); uint fileCount = input.ReadValueU32(endian); uint directoryCount = input.ReadValueU32(endian); uint unknown = input.ReadValueU32(endian); if (unknown != 0) { throw new InvalidOperationException(); } this.Directories.Clear(); for (uint i = 0; i < directoryCount; i++) { var dir = new DirectoryEntry(this); dir.Deserialize(input, endian, stringTable); this.Directories.Add(dir); } this.Files.Clear(); for (uint i = 0; i < fileCount; i++) { var file = new FileEntry(this); file.Deserialize(input, endian, stringTable); this.Files.Add(file); } }
private void Deserialize(Stream input, Endian endian) { var version = input.ReadValueU16(endian); if (IsValidVersion(version) == false) { throw new FormatException("invalid or unsupported wad version"); } this.Version = version; if (version == 0x101 || version >= 0x200) { this.Flags = input.ReadValueEnum <Wad.ArchiveFlags>(endian); } else { this.Flags = Wad.ArchiveFlags.None; } if (version >= 0x202) { var headerXmlLength = input.ReadValueU32(endian); this.HeaderXml = input.ReadBytes(headerXmlLength); } var stringTableSize = input.ReadValueU32(endian); using (var stringTableData = new MemoryStream()) { if (version >= 0x200) { stringTableData.WriteFromStream(input, stringTableSize); stringTableData.Position = 0; } this.DataTypes.Clear(); if ((this.Flags & Wad.ArchiveFlags.HasDataTypes) == Wad.ArchiveFlags.HasDataTypes) { uint count = input.ReadValueU32(endian); for (uint i = 0; i < count; i++) { var item = new Wad.DataType(); item.Index = input.ReadValueU32(endian); item.Unknown2 = input.ReadValueU32(endian); this.DataTypes.Add(item); } } var totalFileCount = input.ReadValueU32(endian); var totalDirectoryCount = input.ReadValueU32(endian); this.DataOffsets.Clear(); if (version >= 0x200) { uint count = input.ReadValueU32(endian); for (uint i = 0; i < count; i++) { this.DataOffsets.Add(input.ReadValueU32(endian)); } } else { // don't know how to handle this situation throw new InvalidOperationException(); } if (version == 0x100) { stringTableData.WriteFromStream(input, stringTableSize); stringTableData.Position = 0; } var stringTableReader = new StringTableReader(stringTableData); using (var fileTableData = input.ReadToMemoryStream((totalDirectoryCount + totalFileCount) * 16)) { while (fileTableData.Position < fileTableData.Length) { var dir = new Wad.DirectoryEntry(null); dir.Deserialize(fileTableData, endian, stringTableReader); this.Directories.Add(dir); } if (this.TotalFileCount != totalFileCount || this.TotalDirectoryCount != totalDirectoryCount) { throw new InvalidOperationException(); } if (fileTableData.Position != fileTableData.Length) { throw new InvalidOperationException(); } } } }