File: FrameworkFork\System.Runtime.Serialization\System\Runtime\Serialization\DataMember.cs
Web Access
Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using Microsoft.Xml;
using System.Security;
 
 
namespace System.Runtime.Serialization
{
#if NET_NATIVE
    public class DataMember
#else
    internal class DataMember
#endif
    {
        [SecurityCritical]
        /// <SecurityNote>
        /// Critical - holds instance of CriticalHelper which keeps state that is cached statically for serialization. 
        ///            Static fields are marked SecurityCritical or readonly to prevent
        ///            data from being modified or leaked to other components in appdomain.
        /// </SecurityNote>
        private CriticalHelper _helper;
 
        /// <SecurityNote>
        /// Critical - initializes SecurityCritical field 'helper'
        /// Safe - doesn't leak anything
        /// </SecurityNote>
        [SecuritySafeCritical]
        public DataMember()
        {
            _helper = new CriticalHelper();
        }
 
        /// <SecurityNote>
        /// Critical - initializes SecurityCritical field 'helper'
        /// Safe - doesn't leak anything
        /// </SecurityNote>
        [SecuritySafeCritical]
        internal DataMember(MemberInfo memberInfo)
        {
            _helper = new CriticalHelper(memberInfo);
        }
 
        /// <SecurityNote>
        /// Critical - initializes SecurityCritical field 'helper'
        /// Safe - doesn't leak anything
        /// </SecurityNote>
        [SecuritySafeCritical]
        internal DataMember(string name)
        {
            _helper = new CriticalHelper(name);
        }
 
 
        /// <SecurityNote>
        /// Critical - initializes SecurityCritical field 'helper'
        /// Safe - doesn't leak anything
        /// </SecurityNote>
        [SecuritySafeCritical]
        internal DataMember(DataContract memberTypeContract, string name, bool isNullable, bool isRequired, bool emitDefaultValue, int order)
        {
            _helper = new CriticalHelper(memberTypeContract, name, isNullable, isRequired, emitDefaultValue, order);
        }
 
        internal MemberInfo MemberInfo
        {
            [SecuritySafeCritical]
            get
            { return _helper.MemberInfo; }
        }
 
        public string Name
        {
            [SecuritySafeCritical]
            get
            { return _helper.Name; }
            [SecurityCritical]
            set
            { _helper.Name = value; }
        }
 
        public int Order
        {
            [SecuritySafeCritical]
            get
            { return _helper.Order; }
            [SecurityCritical]
            set
            { _helper.Order = value; }
        }
 
        public bool IsRequired
        {
            [SecuritySafeCritical]
            get
            { return _helper.IsRequired; }
            [SecurityCritical]
            set
            { _helper.IsRequired = value; }
        }
 
        public bool EmitDefaultValue
        {
            [SecuritySafeCritical]
            get
            { return _helper.EmitDefaultValue; }
            [SecurityCritical]
            set
            { _helper.EmitDefaultValue = value; }
        }
 
        public bool IsNullable
        {
            [SecuritySafeCritical]
            get
            { return _helper.IsNullable; }
            [SecurityCritical]
            set
            { _helper.IsNullable = value; }
        }
 
        public bool IsGetOnlyCollection
        {
            [SecuritySafeCritical]
            get
            { return _helper.IsGetOnlyCollection; }
            [SecurityCritical]
            set
            { _helper.IsGetOnlyCollection = value; }
        }
 
        internal Type MemberType
        {
            [SecuritySafeCritical]
            get
            { return _helper.MemberType; }
        }
 
        internal DataContract MemberTypeContract
        {
            [SecuritySafeCritical]
            get
            { return _helper.MemberTypeContract; }
        }
 
        public bool HasConflictingNameAndType
        {
            [SecuritySafeCritical]
            get
            { return _helper.HasConflictingNameAndType; }
            [SecurityCritical]
            set
            { _helper.HasConflictingNameAndType = value; }
        }
 
        internal DataMember ConflictingMember
        {
            [SecuritySafeCritical]
            get
            { return _helper.ConflictingMember; }
            [SecurityCritical]
            set
            { _helper.ConflictingMember = value; }
        }
        [SecurityCritical]
 
        /// <SecurityNote>
        /// Critical
        /// </SecurityNote>
        private class CriticalHelper
        {
            private DataContract _memberTypeContract;
            private string _name;
            private int _order;
            private bool _isRequired;
            private bool _emitDefaultValue;
            private bool _isNullable;
            private bool _isGetOnlyCollection = false;
            private MemberInfo _memberInfo;
            private bool _hasConflictingNameAndType;
            private DataMember _conflictingMember;
 
            internal CriticalHelper()
            {
                _emitDefaultValue = Globals.DefaultEmitDefaultValue;
            }
 
            internal CriticalHelper(MemberInfo memberInfo)
            {
                _emitDefaultValue = Globals.DefaultEmitDefaultValue;
                _memberInfo = memberInfo;
            }
 
            internal CriticalHelper(string name)
            {
                this.Name = name;
            }
 
            internal CriticalHelper(DataContract memberTypeContract, string name, bool isNullable, bool isRequired, bool emitDefaultValue, int order)
            {
                this.MemberTypeContract = memberTypeContract;
                this.Name = name;
                this.IsNullable = isNullable;
                this.IsRequired = isRequired;
                this.EmitDefaultValue = emitDefaultValue;
                this.Order = order;
            }
 
            internal MemberInfo MemberInfo
            {
                get { return _memberInfo; }
            }
 
            internal string Name
            {
                get { return _name; }
                set { _name = value; }
            }
 
            internal int Order
            {
                get { return _order; }
                set { _order = value; }
            }
 
            internal bool IsRequired
            {
                get { return _isRequired; }
                set { _isRequired = value; }
            }
 
            internal bool EmitDefaultValue
            {
                get { return _emitDefaultValue; }
                set { _emitDefaultValue = value; }
            }
 
            internal bool IsNullable
            {
                get { return _isNullable; }
                set { _isNullable = value; }
            }
 
            internal bool IsGetOnlyCollection
            {
                get { return _isGetOnlyCollection; }
                set { _isGetOnlyCollection = value; }
            }
 
            internal Type MemberType
            {
                get
                {
                    FieldInfo field = MemberInfo as FieldInfo;
                    if (field != null)
                        return field.FieldType;
                    return ((PropertyInfo)MemberInfo).PropertyType;
                }
            }
 
            internal DataContract MemberTypeContract
            {
                get
                {
                    if (_memberTypeContract == null)
                    {
                        if (MemberInfo != null)
                        {
                            if (this.IsGetOnlyCollection)
                            {
                                _memberTypeContract = DataContract.GetGetOnlyCollectionDataContract(DataContract.GetId(MemberType.TypeHandle), MemberType.TypeHandle, MemberType, SerializationMode.SharedContract);
                            }
                            else
                            {
                                _memberTypeContract = DataContract.GetDataContract(MemberType);
                            }
                        }
                    }
                    return _memberTypeContract;
                }
                set
                {
                    _memberTypeContract = value;
                }
            }
 
            internal bool HasConflictingNameAndType
            {
                get { return _hasConflictingNameAndType; }
                set { _hasConflictingNameAndType = value; }
            }
 
            internal DataMember ConflictingMember
            {
                get { return _conflictingMember; }
                set { _conflictingMember = value; }
            }
        }
 
        /// <SecurityNote>
        /// Review - checks member visibility to calculate if access to it requires MemberAccessPermission for serialization.
        ///          since this information is used to determine whether to give the generated code access
        ///          permissions to private members, any changes to the logic should be reviewed.
        /// </SecurityNote>
        internal bool RequiresMemberAccessForGet()
        {
            MemberInfo memberInfo = MemberInfo;
            FieldInfo field = memberInfo as FieldInfo;
            if (field != null)
            {
                return DataContract.FieldRequiresMemberAccess(field);
            }
            else
            {
                PropertyInfo property = (PropertyInfo)memberInfo;
                MethodInfo getMethod = property.GetMethod;
                if (getMethod != null)
                {
                    return DataContract.MethodRequiresMemberAccess(getMethod) || !DataContract.IsTypeVisible(property.PropertyType);
                }
            }
            return false;
        }
 
        /// <SecurityNote>
        /// Review - checks member visibility to calculate if access to it requires MemberAccessPermission for deserialization.
        ///          since this information is used to determine whether to give the generated code access
        ///          permissions to private members, any changes to the logic should be reviewed.
        /// </SecurityNote>
        internal bool RequiresMemberAccessForSet()
        {
            MemberInfo memberInfo = MemberInfo;
            FieldInfo field = memberInfo as FieldInfo;
            if (field != null)
            {
                return DataContract.FieldRequiresMemberAccess(field);
            }
            else
            {
                PropertyInfo property = (PropertyInfo)memberInfo;
                MethodInfo setMethod = property.SetMethod;
                if (setMethod != null)
                {
                    return DataContract.MethodRequiresMemberAccess(setMethod) || !DataContract.IsTypeVisible(property.PropertyType);
                }
            }
            return false;
        }
    }
}