view Loaders/ArmyBuilderABFileLoader.cs @ 0:1a5205612b72

Add initial work on ArmyBuilder API project\nno-open-ticket
author IBBoard <dev@ibboard.co.uk>
date Sun, 19 Apr 2009 11:24:10 +0000
parents
children d5ba733cd289
line wrap: on
line source

//  This file (ArmyBuilderFileLoader.cs) is a part of the IBBoard.ArmyBuilder.API project and is copyright 2009 IBBoard
// 
//  The file and the library/program it is in are licensed under the GNU LGPL license, either version 3 of the License or (at your option) any later version. Please see COPYING.LGPL for more information and the full license.
// 

using System;
using System.IO;

namespace IBBoard.ArmyBuilder.API.Loaders
{
	public class ArmyBuilderABFileLoader
	{
		private static byte HEADER_DELIMITER = 0x09;

		public static ABFile LoadFile(FileInfo file)
		{
			ABFile abFile = new ABFile(file);
			LoadData(abFile);
			return abFile;
		}
		
		private static void LoadData(ABFile abFile)
		{
			BinaryReaderBigEndian reader = new BinaryReaderBigEndian(abFile.File.OpenRead());

			try
			{
				ReadFileInfo(abFile, reader);
				ReadFileTable(abFile, reader);
			}
			finally
			{
				reader.Close();
			}
		}

		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.UnknownNumber = 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.UnknownNumber.Length + file.Exporter.Length + 9;
		}

		private static void ReadFileTable(ABFile abFile, BinaryReaderBigEndian reader)
		{
			FileTableEntry entry = null;
			
			do
			{
				entry = ReadFileTableEntry(reader);
				abFile.AddFileTableEntry(entry);
			}
			while (entry!=null);
		}

		private static FileTableEntry ReadFileTableEntry(BinaryReaderBigEndian reader)
		{
			FileTableEntry entry = null;
			string name = reader.ReadUShortLengthString();

			if (name!="" && name!=null)
			{
				entry = new FileTableEntry(name);
				entry.FirstBytes = reader.ReadBytes(8);
				entry.FileSize = reader.ReadInt();
				entry.CompressedSize = reader.ReadInt();
				entry.MidBytes = reader.ReadBytes(4);
				entry.Location = reader.ReadInt();
				entry.EndBytes = reader.ReadBytes(8);
			}

			return entry;
		}
	}
}