<PackageReference Include="System.Runtime.Serialization.Formatters" Version="9.0.6" />

ReadObjectInfo

sealed class ReadObjectInfo
using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Threading; namespace System.Runtime.Serialization.Formatters.Binary { internal sealed class ReadObjectInfo { internal int _objectInfoId; internal static int _readObjectInfoCounter; [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] internal Type _objectType; internal ObjectManager _objectManager; internal int _count; internal bool _isSi; internal bool _isTyped; internal bool _isSimpleAssembly; internal SerObjectInfoCache _cache; internal string[] _wireMemberNames; internal Type[] _wireMemberTypes; private int _lastPosition; internal ISerializationSurrogate _serializationSurrogate; internal StreamingContext _context; internal List<Type> _memberTypesList; internal SerObjectInfoInit _serObjectInfoInit; internal IFormatterConverter _formatterConverter; internal ReadObjectInfo() { } internal void ObjectEnd() { } internal void PrepareForReuse() { _lastPosition = 0; } internal static ReadObjectInfo Create([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, bool bSimpleAssembly) { ReadObjectInfo objectInfo = GetObjectInfo(serObjectInfoInit); objectInfo.Init(objectType, surrogateSelector, context, objectManager, serObjectInfoInit, converter, bSimpleAssembly); return objectInfo; } internal void Init([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, bool bSimpleAssembly) { _objectType = objectType; _objectManager = objectManager; _context = context; _serObjectInfoInit = serObjectInfoInit; _formatterConverter = converter; _isSimpleAssembly = bSimpleAssembly; InitReadConstructor(objectType, surrogateSelector, context); } internal static ReadObjectInfo Create([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type objectType, string[] memberNames, Type[] memberTypes, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, bool bSimpleAssembly) { ReadObjectInfo objectInfo = GetObjectInfo(serObjectInfoInit); objectInfo.Init(objectType, memberNames, memberTypes, surrogateSelector, context, objectManager, serObjectInfoInit, converter, bSimpleAssembly); return objectInfo; } internal void Init([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type objectType, string[] memberNames, Type[] memberTypes, ISurrogateSelector surrogateSelector, StreamingContext context, ObjectManager objectManager, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, bool bSimpleAssembly) { _objectType = objectType; _objectManager = objectManager; _wireMemberNames = memberNames; _wireMemberTypes = memberTypes; _context = context; _serObjectInfoInit = serObjectInfoInit; _formatterConverter = converter; _isSimpleAssembly = bSimpleAssembly; if (memberTypes != null) _isTyped = true; if (objectType != (Type)null) InitReadConstructor(objectType, surrogateSelector, context); } private void InitReadConstructor(Type objectType, ISurrogateSelector surrogateSelector, StreamingContext context) { BinaryFormatterEventSource.Log.DeserializingObject(objectType); if (objectType.IsArray) InitNoMembers(); else { if (surrogateSelector != null) _serializationSurrogate = surrogateSelector.GetSurrogate(objectType, context, out ISurrogateSelector _); if (_serializationSurrogate != null) _isSi = true; else if ((object)objectType != Converter.s_typeofObject && Converter.s_typeofISerializable.IsAssignableFrom(objectType)) { _isSi = true; } if (_isSi) InitSiRead(); else InitMemberInfo(); } } private void InitSiRead() { if (_memberTypesList != null) _memberTypesList = new List<Type>(20); } private void InitNoMembers() { _cache = new SerObjectInfoCache(_objectType); } private void InitMemberInfo() { _cache = new SerObjectInfoCache(_objectType); _cache._memberInfos = FormatterServices.GetSerializableMembers(_objectType, _context); _count = _cache._memberInfos.Length; _cache._memberNames = new string[_count]; _cache._memberTypes = new Type[_count]; for (int i = 0; i < _count; i++) { _cache._memberNames[i] = _cache._memberInfos[i].Name; _cache._memberTypes[i] = GetMemberType(_cache._memberInfos[i]); } _isTyped = true; } internal MemberInfo GetMemberInfo(string name) { if (_cache == null) return null; if (_isSi) throw new SerializationException(System.SR.Format(System.SR.Serialization_MemberInfo, _objectType?.ToString() + " " + name)); if (_cache._memberInfos == null) throw new SerializationException(System.SR.Format(System.SR.Serialization_NoMemberInfo, _objectType?.ToString() + " " + name)); int num = Position(name); if (num == -1) return null; return _cache._memberInfos[num]; } internal Type GetType(string name) { int num = Position(name); if (num == -1) return null; Type obj = _isTyped ? _cache._memberTypes[num] : _memberTypesList[num]; if (obj == (Type)null) throw new SerializationException(System.SR.Format(System.SR.Serialization_ISerializableTypes, _objectType?.ToString() + " " + name)); return obj; } internal void AddValue(string name, object value, ref SerializationInfo si, ref object[] memberData) { if (_isSi) si.AddValue(name, value); else { int num = Position(name); if (num != -1) memberData[num] = value; } } internal void InitDataStore(ref SerializationInfo si, ref object[] memberData) { if (_isSi) { if (si == null) si = new SerializationInfo(_objectType, _formatterConverter); } else if (memberData == null && _cache != null) { memberData = new object[_cache._memberNames.Length]; } } internal void RecordFixup(long objectId, string name, long idRef) { if (_isSi) { if (_objectManager == null) throw new SerializationException(System.SR.Serialization_CorruptedStream); _objectManager.RecordDelayedFixup(objectId, name, idRef); } else { int num = Position(name); if (num != -1) { if (_objectManager == null) throw new SerializationException(System.SR.Serialization_CorruptedStream); _objectManager.RecordFixup(objectId, _cache._memberInfos[num], idRef); } } } internal void PopulateObjectMembers(object obj, object[] memberData) { if (!_isSi && memberData != null) FormatterServices.PopulateObjectMembers(obj, _cache._memberInfos, memberData); } private int Position(string name) { if (_cache == null) return -1; if (_cache._memberNames.Length != 0 && _cache._memberNames[_lastPosition].Equals(name)) return _lastPosition; if (++_lastPosition < _cache._memberNames.Length && _cache._memberNames[_lastPosition].Equals(name)) return _lastPosition; for (int i = 0; i < _cache._memberNames.Length; i++) { if (_cache._memberNames[i].Equals(name)) { _lastPosition = i; return _lastPosition; } } _lastPosition = 0; return -1; } internal Type[] GetMemberTypes(string[] inMemberNames, Type objectType) { if (_isSi) throw new SerializationException(System.SR.Format(System.SR.Serialization_ISerializableTypes, objectType)); if (_cache == null) return null; if (_cache._memberTypes == null) { _cache._memberTypes = new Type[_count]; for (int i = 0; i < _count; i++) { _cache._memberTypes[i] = GetMemberType(_cache._memberInfos[i]); } } bool flag = false; if (inMemberNames.Length < _cache._memberInfos.Length) flag = true; Type[] array = new Type[_cache._memberInfos.Length]; for (int j = 0; j < _cache._memberInfos.Length; j++) { if (!flag && inMemberNames[j].Equals(_cache._memberInfos[j].Name)) array[j] = _cache._memberTypes[j]; else { bool flag2 = false; for (int k = 0; k < inMemberNames.Length; k++) { if (_cache._memberInfos[j].Name.Equals(inMemberNames[k])) { array[j] = _cache._memberTypes[j]; flag2 = true; break; } } if (!flag2 && !_isSimpleAssembly && _cache._memberInfos[j].GetCustomAttribute<OptionalFieldAttribute>(false) == null) throw new SerializationException(System.SR.Format(System.SR.Serialization_MissingMember, _cache._memberNames[j], objectType, typeof(OptionalFieldAttribute).FullName)); } } return array; } internal Type GetMemberType(MemberInfo objMember) { if (objMember is FieldInfo) return ((FieldInfo)objMember).FieldType; throw new SerializationException(System.SR.Format(System.SR.Serialization_SerMemberInfo, objMember.GetType())); } private static ReadObjectInfo GetObjectInfo(SerObjectInfoInit serObjectInfoInit) { return new ReadObjectInfo { _objectInfoId = Interlocked.Increment(ref _readObjectInfoCounter) }; } } }