/// <summary> /// Returns a deep copy of the resource table /// </summary> public ResourceTableEntry[] GetResourceTableCopy() { if (Table == null) { return(null); } ResourceTableEntry[] result = new ResourceTableEntry[Table.Length]; for (int i = 0; i < Table.Length; i++) { result[i] = new ResourceTableEntry(); result[i].ID = Table[i].ID; result[i].Flags = Table[i].Flags; result[i].Offset = Table[i].Offset; result[i].Size = Table[i].Size; result[i].Type = Table[i].Type; result[i].Name = Table[i].Name; } return(result); }
/// <summary> /// Returns Resource entry as indexed by its ID (not the index in the file). /// /// Returns a cached version if one exists. /// </summary> /// <param name="ID">Resource ID</param> /// <returns></returns> public ResourceEntry this[int ID] { get { if (CachedResources.ContainsKey(ID)) { return(CachedResources[ID]); } if (TableIDLookup.ContainsKey(ID) == false) { return(null); } using (BinaryReader reader = new BinaryReader(File.OpenRead(Filename))) { ResourceTableEntry tableEntry = Table[TableIDLookup[ID]]; ResourceEntry entry = new ResourceEntry(); entry.ID = tableEntry.ID; entry.Type = tableEntry.Type; reader.BaseStream.Seek(tableEntry.Offset, SeekOrigin.Begin); entry.Data = reader.ReadBytes(tableEntry.Size); entry.Name = tableEntry.Name; if (ShouldCache) { CachedResources.Add(tableEntry.ID, entry); } return(entry); } } }
/// <summary> /// Opens a biff file and reads the header and resource table information /// </summary> /// <param name="filename"></param> /// <param name="keyfile">Can be null</param> public BiffFile(string filename, string keyfilename) { Filename = filename; TableIDLookup = new Dictionary <int, int>(); CachedResources = new Dictionary <int, ResourceEntry>(); Header = new BiffFileHeader(); Header.Signature = "UNKW"; Header.Version = ""; Header.ResCount = 0; Header.ResTableOffset = 0; Table = null; KeyFile keyFile = new KeyFile(keyfilename); biffEntry = keyFile.GetBiffFileEntry(Path.GetFileName(filename)); using (BinaryReader reader = new BinaryReader(File.OpenRead(filename))) { if (reader.BaseStream.Length < 8) { throw new Exception("File is not a BIFF V1.1 file (file is too short)"); } // Read Header Header.Signature = new string(reader.ReadChars(4)); Header.Version = new string(reader.ReadChars(4)); if (Header.Signature != "BIFF" && Header.Version != "V1.1") { throw new Exception("File is not a BIFF V1.1 file (according to header)"); } Header.ResCount = reader.ReadInt32(); reader.ReadInt32(); // NULL Header.ResTableOffset = reader.ReadInt32(); // Read Resource Table Table = new ResourceTableEntry[Header.ResCount]; reader.BaseStream.Seek(Header.ResTableOffset, SeekOrigin.Begin); for (int i = 0; i < Header.ResCount; i++) { Table[i] = new ResourceTableEntry(); Table[i].ID = reader.ReadInt32(); Table[i].Flags = reader.ReadInt32(); Table[i].Offset = reader.ReadInt32(); Table[i].Size = reader.ReadInt32(); Table[i].Type = (ResourceType)reader.ReadInt16(); Table[i].Name = Table[i].ID.ToString(); if (biffEntry != null && biffEntry.ResourceNames.ContainsKey(Table[i].ID)) { Table[i].Name = biffEntry.ResourceNames[Table[i].ID]; } Table[i].Name += "." + Table[i].Type; reader.ReadInt16(); // NULL TableIDLookup.Add(Table[i].ID, i); } } }