Mercurial > repos > IBBoard.ArmyBuilder.API
diff Loaders/ArmyBuilderABFileLoader.cs @ 3:1a54f6afafe7
Re #84 and #85: Support Army Builder v2/v3 files
* Separate out the two versions of file
* Restructure file loader to load v2 files correctly
* Tidy up file extractor (still not working)
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sun, 17 May 2009 18:40:36 +0000 |
parents | d5ba733cd289 |
children | ec77b60e5369 |
line wrap: on
line diff
--- a/Loaders/ArmyBuilderABFileLoader.cs Mon Apr 20 19:28:01 2009 +0000 +++ b/Loaders/ArmyBuilderABFileLoader.cs Sun May 17 18:40:36 2009 +0000 @@ -11,21 +11,99 @@ public class ArmyBuilderABFileLoader { private static byte HEADER_DELIMITER = 0x09; + private static byte HEADER_TYPE_DELIMITER = 0x3A; + private static byte TABLE_HEADER_OFFSET_FROM = 4; + private static byte FILE_TABLE_OFFSET_LENGTH = 2; public static ABFile LoadFile(FileInfo file) { - ABFile abFile = new ABFile(file); - LoadData(abFile); + ABFile abFile = ReadFileInfo(file); + ReadFileTable(abFile); + return abFile; + } + + private static ABFile ReadFileInfo(FileInfo file) + { + BinaryReaderBigEndian reader = new BinaryReaderBigEndian(file.OpenRead()); + ABFile abFile = null; + + try + { + abFile = ReadFileInfo(file, reader); + } + finally + { + reader.Close(); + } + + return abFile; + } + + private static ABFile ReadFileInfo(FileInfo file, BinaryReaderBigEndian reader) + { + int tableOffset = reader.ReadInt(); + reader.Move(tableOffset); + ushort fileTableOffset = reader.ReadUShort(); + string header = reader.ReadDelimitedString(HEADER_TYPE_DELIMITER); + + ABFile abFile = CreateFile(file, header); + ReadExtraHeaders(abFile, reader); + int fileTablePosition = TABLE_HEADER_OFFSET_FROM + tableOffset + FILE_TABLE_OFFSET_LENGTH + fileTableOffset; + abFile.FileTablePosition = fileTablePosition; + int readerPosition = (int)reader.Position; + + if (fileTablePosition > readerPosition) + { + abFile.Comment = reader.ReadString(fileTablePosition - readerPosition); + } + return abFile; } - - private static void LoadData(ABFile abFile) + + private static ABFile CreateFile(FileInfo file, string header) { + ABFile abFile = null; + header = header.Trim(); + + if ("LWDExport".Equals(header)) + { + abFile = new ABv3File(file); + } + else if ("ArmyBuilder".Equals(header)) + { + abFile = new ABv2File(file); + } + else + { + throw new InvalidDataException("Unsupported file table header: "+header); + } + + abFile.Header = header; + return abFile; + } + + private static void ReadExtraHeaders(ABFile abFile, BinaryReaderBigEndian reader) + { + if (abFile is ABv3File) + { + ABv3File ab3File = (ABv3File)abFile; + ab3File.GameName = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.FolderName = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.ReleaseMajor = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.ReleaseMinor = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.RequiredMajorVersion = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.RequiredMinorVersion = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.UniqueID = reader.ReadDelimitedString(HEADER_DELIMITER); + ab3File.Exporter = reader.ReadDelimitedString(HEADER_DELIMITER); + } + } + + private static void ReadFileTable(ABFile abFile) + { BinaryReaderBigEndian reader = new BinaryReaderBigEndian(abFile.File.OpenRead()); try { - ReadFileInfo(abFile, reader); ReadFileTable(abFile, reader); } finally @@ -34,37 +112,10 @@ } } - private static void ReadFileInfo(ABFile abFile, BinaryReaderBigEndian reader) - { - int tableOffset = reader.ReadInt(); - reader.Move(tableOffset); - ushort fileTableOffset = reader.ReadUShort(); - abFile.Header = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.GameName = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.FolderName = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.ReleaseMajor = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.ReleaseMinor = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.RequiredMajorVersion = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.RequiredMinorVersion = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.UniqueID = reader.ReadDelimitedString(HEADER_DELIMITER); - abFile.Exporter = reader.ReadDelimitedString(HEADER_DELIMITER); - int bytesRead = CalculateFileInfoSize(abFile); - - if (fileTableOffset > bytesRead) - { - abFile.Comment = reader.ReadString(fileTableOffset - bytesRead); - } - } - - private static int CalculateFileInfoSize(ABFile file) - { - return file.Header.Length + file.GameName.Length + file.FolderName.Length + file.ReleaseMajor.Length + file.ReleaseMinor.Length + - file.RequiredMajorVersion.Length + file.RequiredMinorVersion.Length + file.UniqueID.Length + file.Exporter.Length + 9; - } - private static void ReadFileTable(ABFile abFile, BinaryReaderBigEndian reader) - { + { FileTableEntry entry = null; + reader.Seek(abFile.FileTablePosition); do {