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
 			{