File: System\Runtime\Serialization\Formatters\Binary\ObjectMap.cs
Web Access
Project: src\src\libraries\System.Runtime.Serialization.Formatters\src\System.Runtime.Serialization.Formatters.csproj (System.Runtime.Serialization.Formatters)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Diagnostics.CodeAnalysis;
 
namespace System.Runtime.Serialization.Formatters.Binary
{
    // When an ObjectWithMap or an ObjectWithMapTyped is read off the stream, an ObjectMap class is created
    // to remember the type information.
    internal sealed class ObjectMap
    {
        internal string _objectName;
        internal Type? _objectType;
 
        internal BinaryTypeEnum[] _binaryTypeEnumA;
        internal object?[] _typeInformationA;
        internal Type?[] _memberTypes;
        internal string[] _memberNames;
        internal ReadObjectInfo _objectInfo;
        internal bool _isInitObjectInfo = true;
        internal ObjectReader? _objectReader;
        internal int _objectId;
        internal BinaryAssemblyInfo _assemblyInfo;
 
        internal ObjectMap(
            string objectName,
            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type objectType,
            string[] memberNames,
            ObjectReader objectReader,
            int objectId,
            BinaryAssemblyInfo assemblyInfo)
        {
            _objectName = objectName;
            _objectType = objectType;
            _memberNames = memberNames;
            _objectReader = objectReader;
            _objectId = objectId;
            _assemblyInfo = assemblyInfo;
 
            _objectInfo = objectReader.CreateReadObjectInfo(objectType);
            _memberTypes = _objectInfo.GetMemberTypes(memberNames, objectType)!;
 
            _binaryTypeEnumA = new BinaryTypeEnum[_memberTypes.Length];
            _typeInformationA = new object[_memberTypes.Length];
 
            for (int i = 0; i < _memberTypes.Length; i++)
            {
                BinaryTypeEnum binaryTypeEnum = BinaryTypeConverter.GetParserBinaryTypeInfo(_memberTypes[i]!, out object? typeInformation);
                _binaryTypeEnumA[i] = binaryTypeEnum;
                _typeInformationA[i] = typeInformation;
            }
        }
 
        [RequiresUnreferencedCode("Types might be removed")]
        internal ObjectMap(string objectName, string[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, object?[] typeInformationA, int[] memberAssemIds, ObjectReader objectReader, int objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
        {
            _objectName = objectName;
            _memberNames = memberNames;
            _binaryTypeEnumA = binaryTypeEnumA;
            _typeInformationA = typeInformationA;
            _objectReader = objectReader;
            _objectId = objectId;
            _assemblyInfo = assemblyInfo;
 
            if (assemblyInfo == null)
            {
                throw new SerializationException(SR.Format(SR.Serialization_Assembly, objectName));
            }
 
            _objectType = objectReader.GetType(assemblyInfo, objectName);
            _memberTypes = new Type[memberNames.Length];
 
            for (int i = 0; i < memberNames.Length; i++)
            {
                BinaryTypeConverter.TypeFromInfo(
                    binaryTypeEnumA[i], typeInformationA[i], objectReader, (BinaryAssemblyInfo?)assemIdToAssemblyTable[memberAssemIds[i]],
                    out _, out _, out Type? type, out _);
                _memberTypes[i] = type;
            }
 
            _objectInfo = objectReader.CreateReadObjectInfo(_objectType, memberNames, null);
            if (!_objectInfo._isSi)
            {
                _objectInfo.GetMemberTypes(memberNames, _objectInfo._objectType);  // Check version match
            }
        }
 
        internal ReadObjectInfo CreateObjectInfo(ref SerializationInfo? si, ref object?[]? memberData)
        {
            if (_isInitObjectInfo)
            {
                _isInitObjectInfo = false;
                _objectInfo.InitDataStore(ref si, ref memberData);
                return _objectInfo;
            }
            else
            {
                _objectInfo.PrepareForReuse();
                _objectInfo.InitDataStore(ref si, ref memberData);
                return _objectInfo;
            }
        }
 
        // No member type information
        internal static ObjectMap Create(
            string name,
            [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type objectType,
            string[] memberNames,
            ObjectReader objectReader,
            int objectId,
            BinaryAssemblyInfo assemblyInfo) =>
            new ObjectMap(name, objectType, memberNames, objectReader, objectId, assemblyInfo);
 
        // Member type information
        [RequiresUnreferencedCode("Types might be removed")]
        internal static ObjectMap Create(
            string name, string[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, object?[] typeInformationA,
            int[] memberAssemIds, ObjectReader objectReader, int objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable) =>
            new ObjectMap(name, memberNames, binaryTypeEnumA, typeInformationA, memberAssemIds, objectReader, objectId, assemblyInfo, assemIdToAssemblyTable);
    }
}