FormatterServicesNoSerializableCheck.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / AuthoringOM / Serializer / FormatterServicesNoSerializableCheck.cs / 1305376 / FormatterServicesNoSerializableCheck.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*============================================================
** 
** Class: SerializationFieldInfo 
**
** 
** Purpose: Provides a methods of representing imaginary fields
** which are unique to serialization.  In this case, what we're
** representing is the private members of parent classes.  We
** aggregate the FieldInfo associated with this member 
** and return a managled form of the name.  The name that we
** return is .parentname.fieldname 
** 
**
============================================================*/ 
using System;
using System.Reflection;
using System.Threading;
using System.Globalization; 
using System.Security.Permissions;
using System.Collections; 
using System.Collections.Generic; 
using System.Workflow.ComponentModel;
 

namespace System.Runtime.Serialization
{
 	internal static class FormatterServicesNoSerializableCheck 
	{
        private struct MemberInfoName 
        { 
            public MemberInfo[] MemberInfo;
            public string[] Names; 
        }
        private static Dictionary m_MemberInfoTable = new Dictionary(32);
		internal static readonly String FakeNameSeparatorString = "+";
 
		private static Object s_FormatterServicesSyncObject = null;
 
 		private static Object formatterServicesSyncObject 
		{
 			get 
 			{
				if (s_FormatterServicesSyncObject == null)
 				{
					Object o = new Object(); 
					Interlocked.CompareExchange(ref s_FormatterServicesSyncObject, o, null);
				} 
 				return s_FormatterServicesSyncObject; 
			}
 		} 

 		private static MemberInfo[] GetSerializableMembers2(Type type)
		{
 			// get the list of all fields 
			FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
			int countProper = 0; 
			for (int i = 0; i < fields.Length; i++) 
 			{
				if ((fields[i].Attributes & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized) 
 					continue;
 				countProper++;
			}
 			if (countProper != fields.Length) 
			{
				FieldInfo[] properFields = new FieldInfo[countProper]; 
				countProper = 0; 
 				for (int i = 0; i < fields.Length; i++)
				{ 
 					if ((fields[i].Attributes & FieldAttributes.NotSerialized) == FieldAttributes.NotSerialized)
 						continue;
					properFields[countProper] = fields[i];
 					countProper++; 
				}
				return properFields; 
			} 
 			else
				return fields; 
 		}
 		private static bool CheckSerializable(Type type)
		{
 			return true; 
			/*
			if (type.IsSerializable) 
			{ 
 				return true;
			} 
 			return false;
 			*/
		}
 		private static MemberInfo[] InternalGetSerializableMembers(Type type, out string[] typeNames) 
		{
			typeNames = null; 
 
			ArrayList allMembers = null;
 			ArrayList allNames = null; 
			MemberInfo[] typeMembers;
 			FieldInfo[] typeFields;
 			Type parentType;
 
			//<
  
			if (type.IsInterface) 
			{
				return new MemberInfo[0]; 
 			}

			//Get all of the serializable members in the class to be serialized.
 			typeMembers = GetSerializableMembers2(type); 
 			if(typeMembers != null)
			{ 
 				typeNames = new string[typeMembers.Length]; 
				for(int index = 0; index < typeMembers.Length; index++)
					typeNames[index] = typeMembers[index].Name; 
			}

 			//If this class doesn't extend directly from object, walk its hierarchy and
			//get all of the private and assembly-access fields (e.g. all fields that aren't 
 			//virtual) and include them in the list of things to be serialized.
 			parentType = (Type)(type.BaseType); 
			if (parentType != null && parentType != typeof(Object)) 
 			{
				Type[] parentTypes = null; 
				int parentTypeCount = 0;
				bool classNamesUnique = GetParentTypes(parentType, out parentTypes, out parentTypeCount);
 				if (parentTypeCount > 0)
				{ 
 					allMembers = new ArrayList();
 					allNames = new ArrayList(); 
					for (int i = 0; i < parentTypeCount; i++) 
 					{
						parentType = (Type)parentTypes[i]; 
						if (!CheckSerializable(parentType))
						{
 							throw new SerializationException();//String.Format(Environment.GetResourceString("Serialization_NonSerType"), parentType.FullName, parentType.Module.Assembly.FullName));
						} 

 						typeFields = parentType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance); 
 						String typeName = classNamesUnique ? parentType.Name : parentType.FullName; 
						foreach (FieldInfo field in typeFields)
 						{ 
							// Family and Assembly fields will be gathered by the type itself.
							if (field.IsPrivate && !field.IsNotSerialized)
							{
 								allMembers.Add(field); 
								allNames.Add(String.Concat(typeName, FakeNameSeparatorString, field.Name));
 								//allMembers.Add(new SerializationFieldInfo(field, typeName)); 
 							} 
						}
 					} 
					//If we actually found any new MemberInfo's, we need to create a new MemberInfo array and
					//copy all of the members which we've found so far into that.
					if (allMembers != null && allMembers.Count > 0)
 					{ 
						MemberInfo[] membersTemp = new MemberInfo[allMembers.Count + typeMembers.Length];
 						Array.Copy(typeMembers, membersTemp, typeMembers.Length); 
 						allMembers.CopyTo(membersTemp, typeMembers.Length); 
						typeMembers = membersTemp;
 
 						string[] namesTemp = new string[allNames.Count + typeNames.Length];
						Array.Copy(typeNames, namesTemp, typeNames.Length);
						allNames.CopyTo(namesTemp, typeNames.Length);
						typeNames = namesTemp; 
 					}
				} 
 			} 
 			return typeMembers;
		} 

 		private static bool GetParentTypes(Type parentType, out Type[] parentTypes, out int parentTypeCount)
		{
			//Check if there are any dup class names. Then we need to include as part of 
			//typeName to prefix the Field names in SerializationFieldInfo
 			/*out*/ 
			parentTypes = null; 
 			/*out*/
 			parentTypeCount = 0; 
			bool unique = true;
 			for (Type t1 = parentType; t1 != typeof(object); t1 = t1.BaseType)
			{
				if (t1.IsInterface) continue; 
				string t1Name = t1.Name;
 				for (int i = 0; unique && i < parentTypeCount; i++) 
				{ 
 					string t2Name = parentTypes[i].Name;
 					if (t2Name.Length == t1Name.Length && t2Name[0] == t1Name[0] && t1Name == t2Name) 
					{
 						unique = false;
						break;
					} 
				}
 				//expand array if needed 
				if (parentTypes == null || parentTypeCount == parentTypes.Length) 
 				{
 					Type[] tempParentTypes = new Type[Math.Max(parentTypeCount * 2, 12)]; 
					if (parentTypes != null)
 						Array.Copy(parentTypes, 0, tempParentTypes, 0, parentTypeCount);
					parentTypes = tempParentTypes;
				} 
				parentTypes[parentTypeCount++] = t1;
 			} 
			return unique; 
 		}
 
 		// Get all of the Serializable members for a particular class.  For all practical intents and
		// purposes, this is the non-transient, non-static members (fields and properties).  In order to
 		// be included, properties must have both a getter and a setter.  N.B.: A class
		// which implements ISerializable or has a serialization surrogate may not use all of these members 
		// (or may have additional members).
		[SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] 
 		public static MemberInfo[] GetSerializableMembers(Type type, out string[] names) 
		{
 			names = null; 

 			MemberInfoName members;
			if (type == null)
 			{ 
				throw new ArgumentNullException("type");
			} 
 
            lock (formatterServicesSyncObject)
            { 
                //If we've already gathered the members for this type, just return them
                if (m_MemberInfoTable.TryGetValue(type, out members))
                {
                    names = members.Names; 
                    return members.MemberInfo;
                } 
            } 
            members.MemberInfo = InternalGetSerializableMembers(type, out members.Names);
            lock (formatterServicesSyncObject) 
			{
 				//If we've already gathered the members for this type, just return them.
                MemberInfoName insertedMembers;
                if (m_MemberInfoTable.TryGetValue(type, out insertedMembers)) 
				{
                    names = insertedMembers.Names; 
                    return insertedMembers.MemberInfo; 
 				}
                m_MemberInfoTable[type] = members; 
 			}
            names = members.Names;
			return members.MemberInfo;
 		} 
	}
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK