using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.Serialization; using JetBrains.Annotations; using NetSerializer; namespace Robust.Shared.Serialization; /// /// Custom serializer implementation for . /// /// /// /// This type is necessary as, since .NET 10, the internal layout of was changed. /// The type now (internally) implements for backwards compatibility with existing /// BinaryFormatter code, but NetSerializer does not support . /// /// /// This code is designed to be backportable & network compatible with the previous behavior on .NET 9. /// /// internal sealed class NetBitArraySerializer : IStaticTypeSerializer { // For reference, the layout of BitArray before .NET 10 was: // private int[] m_array; // private int m_length; // private int _version; // NetSerializer serialized these in the following order (sorted by name): // _version, m_array, m_length public bool Handles(Type type) { return type == typeof(BitArray); } public IEnumerable GetSubtypes(Type type) { return [typeof(int[]), typeof(int)]; } public MethodInfo GetStaticWriter(Type type) { return typeof(NetBitArraySerializer).GetMethod("Write", BindingFlags.Static | BindingFlags.NonPublic)!; } public MethodInfo GetStaticReader(Type type) { return typeof(NetBitArraySerializer).GetMethod("Read", BindingFlags.Static | BindingFlags.NonPublic)!; } [UsedImplicitly] private static void Write(Serializer serializer, Stream stream, BitArray value) { var intCount = (31 + value.Length) >> 5; var ints = new int[intCount]; value.CopyTo(ints, 0); serializer.SerializeDirect(stream, 0); // _version serializer.SerializeDirect(stream, ints); // m_array serializer.SerializeDirect(stream, value.Length); // m_length } [UsedImplicitly] private static void Read(Serializer serializer, Stream stream, out BitArray value) { serializer.DeserializeDirect(stream, out _); // _version serializer.DeserializeDirect(stream, out var array); // m_array serializer.DeserializeDirect(stream, out var length); // m_length value = new BitArray(array) { Length = length }; } }