internal static T ParseChunk <T>( BinaryReader reader, W3dParseContext context, Func <W3dChunkHeader, T> parseCallback) where T : W3dChunk { var chunkHeader = W3dChunkHeader.Parse(reader); var startPosition = reader.BaseStream.Position; var endPosition = startPosition + chunkHeader.ChunkSize; context.PushChunk(typeof(T).Name, endPosition); var result = parseCallback(chunkHeader); result.StartPosition = startPosition; result.EndPosition = endPosition; context.PopAsset(); if (reader.BaseStream.Position != endPosition) { throw new InvalidDataException($"Error while parsing asset '{typeof(T).Name}'. Expected reader to be at position {endPosition}, but was at {reader.BaseStream.Position}."); } return(result); }
internal static W3dChunkHeader Parse(BinaryReader reader) { var result = new W3dChunkHeader(); var chunkSize = reader.ReadUInt32(); result.ChunkSize = chunkSize & 0x7FFFFFFF; result.HasSubChunks = (chunkSize >> 31) == 1; return(result); }
internal void WriteTo(BinaryWriter writer) { writer.Write((uint)ChunkType); var headerPosition = writer.BaseStream.Position; // We'll back up and overwrite this later. writer.Seek(W3dChunkHeader.SizeInBytes, SeekOrigin.Current); var startPosition = writer.BaseStream.Position; WriteToOverride(writer); var endPosition = writer.BaseStream.Position; var dataSize = endPosition - startPosition; // Back up and write header. var header = new W3dChunkHeader((uint)dataSize, HasSubChunks); writer.BaseStream.Position = headerPosition; header.WriteTo(writer); writer.BaseStream.Position = endPosition; }