Mercurial > repos > IBBoard.ArmyBuilder.API
comparison 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 |
comparison
equal
deleted
inserted
replaced
2:d5ba733cd289 | 3:1a54f6afafe7 |
---|---|
9 namespace IBBoard.ArmyBuilder.API.Loaders | 9 namespace IBBoard.ArmyBuilder.API.Loaders |
10 { | 10 { |
11 public class ArmyBuilderABFileLoader | 11 public class ArmyBuilderABFileLoader |
12 { | 12 { |
13 private static byte HEADER_DELIMITER = 0x09; | 13 private static byte HEADER_DELIMITER = 0x09; |
14 private static byte HEADER_TYPE_DELIMITER = 0x3A; | |
15 private static byte TABLE_HEADER_OFFSET_FROM = 4; | |
16 private static byte FILE_TABLE_OFFSET_LENGTH = 2; | |
14 | 17 |
15 public static ABFile LoadFile(FileInfo file) | 18 public static ABFile LoadFile(FileInfo file) |
16 { | 19 { |
17 ABFile abFile = new ABFile(file); | 20 ABFile abFile = ReadFileInfo(file); |
18 LoadData(abFile); | 21 ReadFileTable(abFile); |
19 return abFile; | 22 return abFile; |
20 } | 23 } |
21 | 24 |
22 private static void LoadData(ABFile abFile) | 25 private static ABFile ReadFileInfo(FileInfo file) |
26 { | |
27 BinaryReaderBigEndian reader = new BinaryReaderBigEndian(file.OpenRead()); | |
28 ABFile abFile = null; | |
29 | |
30 try | |
31 { | |
32 abFile = ReadFileInfo(file, reader); | |
33 } | |
34 finally | |
35 { | |
36 reader.Close(); | |
37 } | |
38 | |
39 return abFile; | |
40 } | |
41 | |
42 private static ABFile ReadFileInfo(FileInfo file, BinaryReaderBigEndian reader) | |
23 { | 43 { |
44 int tableOffset = reader.ReadInt(); | |
45 reader.Move(tableOffset); | |
46 ushort fileTableOffset = reader.ReadUShort(); | |
47 string header = reader.ReadDelimitedString(HEADER_TYPE_DELIMITER); | |
48 | |
49 ABFile abFile = CreateFile(file, header); | |
50 ReadExtraHeaders(abFile, reader); | |
51 int fileTablePosition = TABLE_HEADER_OFFSET_FROM + tableOffset + FILE_TABLE_OFFSET_LENGTH + fileTableOffset; | |
52 abFile.FileTablePosition = fileTablePosition; | |
53 int readerPosition = (int)reader.Position; | |
54 | |
55 if (fileTablePosition > readerPosition) | |
56 { | |
57 abFile.Comment = reader.ReadString(fileTablePosition - readerPosition); | |
58 } | |
59 | |
60 return abFile; | |
61 } | |
62 | |
63 private static ABFile CreateFile(FileInfo file, string header) | |
64 { | |
65 ABFile abFile = null; | |
66 header = header.Trim(); | |
67 | |
68 if ("LWDExport".Equals(header)) | |
69 { | |
70 abFile = new ABv3File(file); | |
71 } | |
72 else if ("ArmyBuilder".Equals(header)) | |
73 { | |
74 abFile = new ABv2File(file); | |
75 } | |
76 else | |
77 { | |
78 throw new InvalidDataException("Unsupported file table header: "+header); | |
79 } | |
80 | |
81 abFile.Header = header; | |
82 return abFile; | |
83 } | |
84 | |
85 private static void ReadExtraHeaders(ABFile abFile, BinaryReaderBigEndian reader) | |
86 { | |
87 if (abFile is ABv3File) | |
88 { | |
89 ABv3File ab3File = (ABv3File)abFile; | |
90 ab3File.GameName = reader.ReadDelimitedString(HEADER_DELIMITER); | |
91 ab3File.FolderName = reader.ReadDelimitedString(HEADER_DELIMITER); | |
92 ab3File.ReleaseMajor = reader.ReadDelimitedString(HEADER_DELIMITER); | |
93 ab3File.ReleaseMinor = reader.ReadDelimitedString(HEADER_DELIMITER); | |
94 ab3File.RequiredMajorVersion = reader.ReadDelimitedString(HEADER_DELIMITER); | |
95 ab3File.RequiredMinorVersion = reader.ReadDelimitedString(HEADER_DELIMITER); | |
96 ab3File.UniqueID = reader.ReadDelimitedString(HEADER_DELIMITER); | |
97 ab3File.Exporter = reader.ReadDelimitedString(HEADER_DELIMITER); | |
98 } | |
99 } | |
100 | |
101 private static void ReadFileTable(ABFile abFile) | |
102 { | |
24 BinaryReaderBigEndian reader = new BinaryReaderBigEndian(abFile.File.OpenRead()); | 103 BinaryReaderBigEndian reader = new BinaryReaderBigEndian(abFile.File.OpenRead()); |
25 | 104 |
26 try | 105 try |
27 { | 106 { |
28 ReadFileInfo(abFile, reader); | |
29 ReadFileTable(abFile, reader); | 107 ReadFileTable(abFile, reader); |
30 } | 108 } |
31 finally | 109 finally |
32 { | 110 { |
33 reader.Close(); | 111 reader.Close(); |
34 } | 112 } |
35 } | 113 } |
36 | 114 |
37 private static void ReadFileInfo(ABFile abFile, BinaryReaderBigEndian reader) | |
38 { | |
39 int tableOffset = reader.ReadInt(); | |
40 reader.Move(tableOffset); | |
41 ushort fileTableOffset = reader.ReadUShort(); | |
42 abFile.Header = reader.ReadDelimitedString(HEADER_DELIMITER); | |
43 abFile.GameName = reader.ReadDelimitedString(HEADER_DELIMITER); | |
44 abFile.FolderName = reader.ReadDelimitedString(HEADER_DELIMITER); | |
45 abFile.ReleaseMajor = reader.ReadDelimitedString(HEADER_DELIMITER); | |
46 abFile.ReleaseMinor = reader.ReadDelimitedString(HEADER_DELIMITER); | |
47 abFile.RequiredMajorVersion = reader.ReadDelimitedString(HEADER_DELIMITER); | |
48 abFile.RequiredMinorVersion = reader.ReadDelimitedString(HEADER_DELIMITER); | |
49 abFile.UniqueID = reader.ReadDelimitedString(HEADER_DELIMITER); | |
50 abFile.Exporter = reader.ReadDelimitedString(HEADER_DELIMITER); | |
51 int bytesRead = CalculateFileInfoSize(abFile); | |
52 | |
53 if (fileTableOffset > bytesRead) | |
54 { | |
55 abFile.Comment = reader.ReadString(fileTableOffset - bytesRead); | |
56 } | |
57 } | |
58 | |
59 private static int CalculateFileInfoSize(ABFile file) | |
60 { | |
61 return file.Header.Length + file.GameName.Length + file.FolderName.Length + file.ReleaseMajor.Length + file.ReleaseMinor.Length + | |
62 file.RequiredMajorVersion.Length + file.RequiredMinorVersion.Length + file.UniqueID.Length + file.Exporter.Length + 9; | |
63 } | |
64 | |
65 private static void ReadFileTable(ABFile abFile, BinaryReaderBigEndian reader) | 115 private static void ReadFileTable(ABFile abFile, BinaryReaderBigEndian reader) |
66 { | 116 { |
67 FileTableEntry entry = null; | 117 FileTableEntry entry = null; |
118 reader.Seek(abFile.FileTablePosition); | |
68 | 119 |
69 do | 120 do |
70 { | 121 { |
71 entry = ReadFileTableEntry(reader); | 122 entry = ReadFileTableEntry(reader); |
72 abFile.AddFileTableEntry(entry); | 123 abFile.AddFileTableEntry(entry); |