public static string Header(ZHeader header, int col1Width = 25) { var h = header; var pairs = new Dictionary <string, string> { { "ZMachine Version", $"{h.Version}" }, { "Flags1", Flags((byte)h.Flags1) }, { "Flags2", Flags(h.Flags2) }, { "Abbreviations Table", Word(h.AbbreviationsTable) }, { "Object Table", Word(h.ObjectTable) }, { "Globals", Word(h.Globals) }, { "Dynamic Memory Size", Word(h.DynamicMemorySize) }, { "Static Memory", Word(h.StaticMemoryBaseAddress) }, { "Dictionary", Word(h.Dictionary) }, { "High Memory", Word(h.HighMemoryBaseAddress) }, { "Program Counter:", Word(h.ProgramCounter) }, { "Unknown1 (0x01):", Byte(h.Unknown1) }, { "Unknown2 (0x12):", Word(h.Unknown2) }, { "Unknown3 (0x14):", Word(h.Unknown3) }, { "Unknown4 (0x16):", Word(h.Unknown4) } }; return(KeyValues(pairs)); }
public BlorbFile(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } this.memory = stream.ReadFully(); var reader = new MemoryReader(this.memory, 0); var dwords = reader.NextDWords(3); // First, ensure that this is a valid format if (dwords[0] != id_FORM) { throw new InvalidOperationException(); } if (dwords[2] != id_IFRS) { throw new InvalidOperationException(); } int totalLength = (int)dwords[1] + 8; // Collect all chunks this.chunks = new List <ChunkDescriptor>(); while (reader.Address < totalLength) { var chunk = new ChunkDescriptor(); chunk.Address = (uint)reader.Address; var type = reader.NextDWord(); var len = reader.NextDWord(); chunk.Type = type; if (type == id_FORM) { chunk.DataAddress = chunk.Address; chunk.Length = len + 8; } else { chunk.DataAddress = (uint)reader.Address; chunk.Length = len; } chunks.Add(chunk); reader.Skip((int)len); if ((reader.Address & 1) != 0) { reader.Skip(1); } if (reader.Address > totalLength) { throw new InvalidOperationException(); } } // Loop through chunks and collect resources this.resources = new List <ResourceDecriptor>(); foreach (var chunk in chunks) { if (chunk.Type == id_RIdx) { reader.Address = (int)chunk.DataAddress; var numResources = (int)reader.NextDWord(); if (chunk.Length < (numResources * 12) + 4) { throw new InvalidOperationException(); } for (int i = 0; i < numResources; i++) { var resource = new ResourceDecriptor(); resource.Usage = reader.NextDWord(); resource.Number = reader.NextDWord(); var resourcePos = reader.NextDWord(); var chunkIndex = chunks.FindIndex(c => c.Address == resourcePos); if (chunkIndex < 0) { throw new InvalidOperationException(); } resource.ChunkNumber = chunkIndex; resources.Add(resource); } } else if (chunk.Type == id_RelN) { reader.Address = (int)chunk.DataAddress; if (chunk.Length < 2) { throw new InvalidOperationException(); } releaseNumber = reader.NextWord(); } else if (chunk.Type == id_IFhd) { reader.Address = (int)chunk.DataAddress; if (chunk.Length < 3) { throw new InvalidOperationException(); } var header = new ZHeader(); header.ReleaseNumber = reader.NextWord(); header.SerialNumber = new char[6]; for (int i = 0; i < 6; i++) { header.SerialNumber[i] = (char)reader.NextByte(); } header.Checksum = reader.NextWord(); } else if (chunk.Type == id_Reso) { } else if (chunk.Type == id_Loop) { } else if (chunk.Type == id_Plte) { } } }