PageRenderTime 33ms CodeModel.GetById 1ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 1ms

/WCFWebApi/src/Microsoft.Runtime.Serialization.Internal/Microsoft/Runtime/Serialization/DataMember.cs

#
C# | 330 lines | 289 code | 37 blank | 4 comment | 28 complexity | 2f38e36e1f315fd3f06885b4c246711a MD5 | raw file
  1//-----------------------------------------------------------------------------
  2// Copyright (c) Microsoft Corporation.  All rights reserved.
  3//-----------------------------------------------------------------------------
  4namespace Microsoft.Runtime.Serialization
  5{
  6    using System;
  7    using System.Collections.Generic;
  8    using System.Diagnostics.CodeAnalysis;
  9    using System.Reflection;
 10    using System.Security;
 11    using Microsoft.Server.Common;
 12
 13    class DataMember
 14    {
 15        [Fx.Tag.SecurityNote(Critical = "Holds instance of CriticalHelper which keeps state that is cached statically for serialization."
 16            + " Static fields are marked SecurityCritical or readonly to prevent data from being modified or leaked to other components in appdomain.")]
 17        [SecurityCritical]
 18        CriticalHelper helper;
 19
 20        [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.",
 21            Safe = "Doesn't leak anything.")]
 22        [SecuritySafeCritical]
 23        internal DataMember()
 24        {
 25            helper = new CriticalHelper();
 26        }
 27
 28        [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.",
 29            Safe = "Doesn't leak anything.")]
 30        [SecuritySafeCritical]
 31        internal DataMember(MemberInfo memberInfo)
 32        {
 33            helper = new CriticalHelper(memberInfo);
 34        }
 35
 36        [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.",
 37            Safe = "Doesn't leak anything.")]
 38        [SecuritySafeCritical]
 39        internal DataMember(string name)
 40        {
 41            helper = new CriticalHelper(name);
 42        }
 43
 44        [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.",
 45            Safe = "Doesn't leak anything.")]
 46        [SecuritySafeCritical]
 47        internal DataMember(DataContract memberTypeContract, string name, bool isNullable, bool isRequired, bool emitDefaultValue, int order)
 48        {
 49            helper = new CriticalHelper(memberTypeContract, name, isNullable, isRequired, emitDefaultValue, order);
 50        }
 51
 52        internal MemberInfo MemberInfo
 53        {
 54            [SecuritySafeCritical]
 55            get { return helper.MemberInfo; }
 56        }
 57
 58        internal string Name
 59        {
 60            [SecuritySafeCritical]
 61            get { return helper.Name; }
 62            [SecurityCritical]
 63            set { helper.Name = value; }
 64        }
 65
 66        internal int Order
 67        {
 68            [SecuritySafeCritical]
 69            get { return helper.Order; }
 70            [SecurityCritical]
 71            set { helper.Order = value; }
 72        }
 73
 74        internal bool IsRequired
 75        {
 76            [SecuritySafeCritical]
 77            get { return helper.IsRequired; }
 78            [SecurityCritical]
 79            set { helper.IsRequired = value; }
 80        }
 81
 82        internal bool EmitDefaultValue
 83        {
 84            [SecuritySafeCritical]
 85            get { return helper.EmitDefaultValue; }
 86            [SecurityCritical]
 87            set { helper.EmitDefaultValue = value; }
 88        }
 89
 90        internal bool IsNullable
 91        {
 92            [SecuritySafeCritical]
 93            get { return helper.IsNullable; }
 94            [SecurityCritical]
 95            set { helper.IsNullable = value; }
 96        }
 97
 98        internal bool IsGetOnlyCollection
 99        {
100            [SecuritySafeCritical]
101            get { return helper.IsGetOnlyCollection; }
102            [SecurityCritical]
103            set { helper.IsGetOnlyCollection = value; }
104        }
105
106        internal Type MemberType
107        {
108            [SecuritySafeCritical]
109            get { return helper.MemberType; }
110        }
111
112        internal DataContract MemberTypeContract
113        {
114            [SecuritySafeCritical]
115            get { return helper.MemberTypeContract; }
116            [SecurityCritical]
117            set { helper.MemberTypeContract = value; }
118        }
119
120        internal bool HasConflictingNameAndType
121        {
122            [SecuritySafeCritical]
123            get { return helper.HasConflictingNameAndType; }
124            [SecurityCritical]
125            set { helper.HasConflictingNameAndType = value; }
126        }
127
128        internal DataMember ConflictingMember
129        {
130            [SecuritySafeCritical]
131            get { return helper.ConflictingMember; }
132            [SecurityCritical]
133            set { helper.ConflictingMember = value; }
134        }
135
136        [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - checks member visibility to calculate if access to it requires MemberAccessPermission for serialization."
137            + " Since this information is used to determine whether to give the generated code access"
138            + " permissions to private members, any changes to the logic should be reviewed.")]
139        internal bool RequiresMemberAccessForGet()
140        {
141            MemberInfo memberInfo = MemberInfo;
142            FieldInfo field = memberInfo as FieldInfo;
143            if (field != null)
144            {
145                return DataContract.FieldRequiresMemberAccess(field);
146            }
147            else
148            {
149                PropertyInfo property = (PropertyInfo)memberInfo;
150                MethodInfo getMethod = property.GetGetMethod(true /*nonPublic*/);
151                if (getMethod != null)
152                    return DataContract.MethodRequiresMemberAccess(getMethod) || !DataContract.IsTypeVisible(property.PropertyType);
153            }
154            return false;
155        }
156
157        [Fx.Tag.SecurityNote(Critical = "Critical.")]
158        [SecurityCritical]
159        class CriticalHelper
160        {
161            DataContract memberTypeContract;
162            string name;
163            int order;
164            bool isRequired;
165            bool emitDefaultValue;
166            bool isNullable;
167            bool isGetOnlyCollection = false;
168            MemberInfo memberInfo;
169            bool hasConflictingNameAndType;
170            DataMember conflictingMember;
171
172            [SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Justification = "This is cloned code.")]
173            internal CriticalHelper()
174            {
175                this.emitDefaultValue = Globals.DefaultEmitDefaultValue;
176            }
177
178            [SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Justification = "This is cloned code.")]
179            internal CriticalHelper(MemberInfo memberInfo)
180            {
181                this.emitDefaultValue = Globals.DefaultEmitDefaultValue;
182                this.memberInfo = memberInfo;
183            }
184
185            [SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Justification = "This is cloned code.")]
186            internal CriticalHelper(string name)
187            {
188                this.Name = name;
189            }
190
191            [SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Justification = "This is cloned code.")]
192            internal CriticalHelper(DataContract memberTypeContract, string name, bool isNullable, bool isRequired, bool emitDefaultValue, int order)
193            {
194                this.MemberTypeContract = memberTypeContract;
195                this.Name = name;
196                this.IsNullable = isNullable;
197                this.IsRequired = isRequired;
198                this.EmitDefaultValue = emitDefaultValue;
199                this.Order = order;
200            }
201
202            internal MemberInfo MemberInfo
203            {
204                get { return memberInfo; }
205            }
206
207            internal string Name
208            {
209                get { return name; }
210                set { name = value; }
211            }
212
213            internal int Order
214            {
215                get { return order; }
216                set { order = value; }
217            }
218
219            internal bool IsRequired
220            {
221                get { return isRequired; }
222                set { isRequired = value; }
223            }
224
225            internal bool EmitDefaultValue
226            {
227                get { return emitDefaultValue; }
228                set { emitDefaultValue = value; }
229            }
230
231            internal bool IsNullable
232            {
233                get { return isNullable; }
234                set { isNullable = value; }
235            }
236
237            internal bool IsGetOnlyCollection
238            {
239                get { return isGetOnlyCollection; }
240                set { isGetOnlyCollection = value; }
241            }
242
243            internal Type MemberType
244            {
245                get
246                {
247                    FieldInfo field = MemberInfo as FieldInfo;
248                    if (field != null)
249                        return field.FieldType;
250                    return ((PropertyInfo)MemberInfo).PropertyType;
251                }
252            }
253
254            internal DataContract MemberTypeContract
255            {
256                get
257                {
258                    if (memberTypeContract == null)
259                    {
260                        if (MemberInfo != null)
261                        {
262                            if (this.IsGetOnlyCollection)
263                            {
264                                memberTypeContract = DataContract.GetGetOnlyCollectionDataContract(DataContract.GetId(MemberType.TypeHandle), MemberType.TypeHandle, MemberType, SerializationMode.SharedContract);
265                            }
266                            else
267                            {
268                                memberTypeContract = DataContract.GetDataContract(MemberType);
269                            }
270                        }
271                    }
272                    return memberTypeContract;
273                }
274                set
275                {
276                    memberTypeContract = value;
277                }
278            }
279
280            internal bool HasConflictingNameAndType
281            {
282                get { return this.hasConflictingNameAndType; }
283                set { this.hasConflictingNameAndType = value; }
284            }
285
286            internal DataMember ConflictingMember
287            {
288                get { return this.conflictingMember; }
289                set { this.conflictingMember = value; }
290            }
291        }
292
293        internal DataMember BindGenericParameters(DataContract[] paramContracts, Dictionary<DataContract, DataContract> boundContracts)
294        {
295            DataContract memberTypeContract = this.MemberTypeContract.BindGenericParameters(paramContracts, boundContracts);
296            DataMember boundDataMember = new DataMember(memberTypeContract,
297                this.Name,
298                !memberTypeContract.IsValueType,
299                this.IsRequired,
300                this.EmitDefaultValue,
301                this.Order);
302            return boundDataMember;
303        }
304
305        internal bool Equals(object other, Dictionary<DataContractPairKey, object> checkedContracts)
306        {
307            if ((object)this == other)
308                return true;
309
310            DataMember dataMember = other as DataMember;
311            if (dataMember != null)
312            {
313                // Note: comparison does not use Order hint since it influences element order but does not specify exact order
314                bool thisIsNullable = (MemberTypeContract == null) ? false : !MemberTypeContract.IsValueType;
315                bool dataMemberIsNullable = (dataMember.MemberTypeContract == null) ? false : !dataMember.MemberTypeContract.IsValueType;
316                return (Name == dataMember.Name
317                        && (IsNullable || thisIsNullable) == (dataMember.IsNullable || dataMemberIsNullable)
318                        && IsRequired == dataMember.IsRequired
319                        && EmitDefaultValue == dataMember.EmitDefaultValue
320                        && MemberTypeContract.Equals(dataMember.MemberTypeContract, checkedContracts));
321            }
322            return false;
323        }
324
325        public override int GetHashCode()
326        {
327            return base.GetHashCode();
328        }
329    }
330}