private byte[] CreateChunk(ZObject obj, bool bigEndian, ref long offset) { using (AwesomeWriter aw = new AwesomeWriter(new MemoryStream(), bigEndian)) { obj.WriteData(aw); // Ensures chunk size is always divisible by 4 if (aw.BaseStream.Position % 4 != 0) { aw.Write(new byte[4 - (aw.BaseStream.Position % 4)]); } offset += aw.BaseStream.Position + 8; // 8 = Chunk Magic + Size return(((MemoryStream)aw.BaseStream).ToArray()); } }
private static RiffFile FromStream(Stream stream) { RiffFile riff = new RiffFile(); AwesomeReader ar = new AwesomeReader(stream); // Checks for "RIFF" magic. switch (ar.ReadInt32()) { case MAGIC_RIFF: ar.BigEndian = false; break; case MAGIC_RIFF_R: ar.BigEndian = true; break; default: throw new Exception("Invalid magic. Expected \"RIFF\""); } riff.BigEndian = ar.BigEndian; // Sets endianess ar.BaseStream.Position += 4; // Skips total size int chunkType = GetChunkType(ar); if (chunkType != MAGIC_INDX) { throw new Exception("First chunk was not an Index!"); } Index index = new Index(ar); foreach (IndexEntry entry in index.Entries) { ar.BaseStream.Position = entry.Offset; // Jumps to offset chunkType = GetChunkType(ar); if (chunkType != MAGIC_STBL && chunkType != MAGIC_ZOBJ) { continue; } // Reads header info HKey filePath = new HKey(ar.ReadUInt64()); HKey directoryPath = new HKey(ar.ReadUInt64()); HKey type = new HKey(ar.ReadUInt64()); ar.BaseStream.Position += 8; if (chunkType == MAGIC_STBL) { // Gets localization if (!StringTable.IsValidLocalization(type)) { continue; } // Loads string table StringTable table = new StringTable(filePath, directoryPath, StringTable.GetLocalization(type)); table.ReadData(ar); riff._objects.Add(table); } else if (chunkType == MAGIC_ZOBJ) { if (!Global.ZObjectTypes.ContainsKey(type)) { continue; // Unsupported type } // Loads zobject ZObject obj = Activator.CreateInstance(Global.ZObjectTypes[type], new object[] { filePath, directoryPath }) as ZObject; obj.ReadData(ar); riff._objects.Add(obj); } else { // Unknown chunk continue; } } return(riff); }
public void AddZObjectAsPending(ZObject obj) => _pendingChanges.Add(obj);