summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Runtime/Serialization
diff options
context:
space:
mode:
authorJiyoung Yun <jy910.yun@samsung.com>2016-11-23 19:09:09 +0900
committerJiyoung Yun <jy910.yun@samsung.com>2016-11-23 19:09:09 +0900
commit4b4aad7217d3292650e77eec2cf4c198ea9c3b4b (patch)
tree98110734c91668dfdbb126fcc0e15ddbd93738ca /src/mscorlib/src/System/Runtime/Serialization
parentfa45f57ed55137c75ac870356a1b8f76c84b229c (diff)
downloadcoreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.gz
coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.bz2
coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.zip
Imported Upstream version 1.1.0upstream/1.1.0
Diffstat (limited to 'src/mscorlib/src/System/Runtime/Serialization')
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs167
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs590
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/IDeserializationCallback.cs23
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/IFormatter.cs41
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/IFormatterConverter.cs40
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs30
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs33
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs36
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs37
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/MemberHolder.cs51
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationAttributes.cs64
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationBinder.cs29
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationException.cs45
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs166
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs798
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs146
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/StreamingContext.cs74
17 files changed, 2370 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs b/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs
new file mode 100644
index 0000000000..7df221c9cd
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs
@@ -0,0 +1,167 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: A base implementation of the IFormatterConverter
+** interface that uses the Convert class and the
+** IConvertible interface.
+**
+**
+============================================================*/
+namespace System.Runtime.Serialization {
+ using System;
+ using System.Globalization;
+ using System.Diagnostics.Contracts;
+
+[System.Runtime.InteropServices.ComVisible(true)]
+ public class FormatterConverter : IFormatterConverter {
+
+ public FormatterConverter() {
+ }
+
+ public Object Convert(Object value, Type type) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
+ }
+
+ public Object Convert(Object value, TypeCode typeCode) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ChangeType(value, typeCode, CultureInfo.InvariantCulture);
+ }
+
+ public bool ToBoolean(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToBoolean(value, CultureInfo.InvariantCulture);
+ }
+
+ public char ToChar(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToChar(value, CultureInfo.InvariantCulture);
+ }
+
+ [CLSCompliant(false)]
+ public sbyte ToSByte(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToSByte(value, CultureInfo.InvariantCulture);
+ }
+
+ public byte ToByte(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToByte(value, CultureInfo.InvariantCulture);
+ }
+
+ public short ToInt16(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToInt16(value, CultureInfo.InvariantCulture);
+ }
+
+ [CLSCompliant(false)]
+ public ushort ToUInt16(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToUInt16(value, CultureInfo.InvariantCulture);
+ }
+
+ public int ToInt32(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToInt32(value, CultureInfo.InvariantCulture);
+ }
+
+ [CLSCompliant(false)]
+ public uint ToUInt32(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToUInt32(value, CultureInfo.InvariantCulture);
+ }
+
+ public long ToInt64(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToInt64(value, CultureInfo.InvariantCulture);
+ }
+
+ [CLSCompliant(false)]
+ public ulong ToUInt64(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToUInt64(value, CultureInfo.InvariantCulture);
+ }
+
+ public float ToSingle(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToSingle(value, CultureInfo.InvariantCulture);
+ }
+
+ public double ToDouble(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToDouble(value, CultureInfo.InvariantCulture);
+ }
+
+ public Decimal ToDecimal(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToDecimal(value, CultureInfo.InvariantCulture);
+ }
+
+ public DateTime ToDateTime(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToDateTime(value, CultureInfo.InvariantCulture);
+ }
+
+ public String ToString(Object value) {
+ if (value==null) {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ return System.Convert.ToString(value, CultureInfo.InvariantCulture);
+ }
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs b/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
new file mode 100644
index 0000000000..c6f27b5b2a
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
@@ -0,0 +1,590 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: Provides some static methods to aid with the implementation
+** of a Formatter for Serialization.
+**
+**
+============================================================*/
+namespace System.Runtime.Serialization {
+
+ using System;
+ using System.Reflection;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Security;
+ using System.Security.Permissions;
+#if FEATURE_SERIALIZATION
+ using System.Runtime.Serialization.Formatters;
+#endif
+ using System.Runtime.Remoting;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.Versioning;
+ using System.Threading;
+ using System.IO;
+ using System.Text;
+ using System.Globalization;
+ using System.Diagnostics.Contracts;
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public static class FormatterServices {
+#if FEATURE_SERIALIZATION
+ internal static Dictionary<MemberHolder, MemberInfo[]> m_MemberInfoTable = new Dictionary<MemberHolder, MemberInfo[]>(32);
+ [System.Security.SecurityCritical]
+ private static bool unsafeTypeForwardersIsEnabled = false;
+
+ [System.Security.SecurityCritical]
+ private static volatile bool unsafeTypeForwardersIsEnabledInitialized = false;
+
+ private static Object s_FormatterServicesSyncObject = null;
+
+ private static Object formatterServicesSyncObject
+ {
+ get
+ {
+ if (s_FormatterServicesSyncObject == null)
+ {
+ Object o = new Object();
+ Interlocked.CompareExchange<Object>(ref s_FormatterServicesSyncObject, o, null);
+ }
+ return s_FormatterServicesSyncObject;
+ }
+ }
+
+ [SecuritySafeCritical]
+ static FormatterServices()
+ {
+ // Static initialization touches security critical types, so we need an
+ // explicit static constructor to allow us to mark it safe critical.
+ }
+
+ private static MemberInfo[] GetSerializableMembers(RuntimeType 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(RuntimeType type) {
+ if (type.IsSerializable) {
+ return true;
+ }
+ return false;
+ }
+
+ private static MemberInfo[] InternalGetSerializableMembers(RuntimeType type) {
+ List<SerializationFieldInfo> allMembers = null;
+ MemberInfo[] typeMembers;
+ FieldInfo [] typeFields;
+ RuntimeType parentType;
+
+ Contract.Assert((object)type != null, "[GetAllSerializableMembers]type!=null");
+
+ if (type.IsInterface) {
+ return new MemberInfo[0];
+ }
+
+ if (!(CheckSerializable(type))) {
+ throw new SerializationException(Environment.GetResourceString("Serialization_NonSerType", type.FullName, type.Module.Assembly.FullName));
+ }
+
+ //Get all of the serializable members in the class to be serialized.
+ typeMembers = GetSerializableMembers(type);
+
+ //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 = (RuntimeType)(type.BaseType);
+ if (parentType != null && parentType != (RuntimeType)typeof(Object)) {
+ RuntimeType[] parentTypes = null;
+ int parentTypeCount = 0;
+ bool classNamesUnique = GetParentTypes(parentType, out parentTypes, out parentTypeCount);
+ if (parentTypeCount > 0){
+ allMembers = new List<SerializationFieldInfo>();
+ for (int i = 0; i < parentTypeCount;i++){
+ parentType = parentTypes[i];
+ if (!CheckSerializable(parentType)) {
+ throw new SerializationException(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.IsNotSerialized) {
+ allMembers.Add(new SerializationFieldInfo((RuntimeFieldInfo)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);
+ ((ICollection)allMembers).CopyTo(membersTemp, typeMembers.Length);
+ typeMembers = membersTemp;
+ }
+ }
+ }
+ return typeMembers;
+ }
+
+ private static bool GetParentTypes(RuntimeType parentType, out RuntimeType[] 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;
+ RuntimeType objectType = (RuntimeType)typeof(object);
+ for (RuntimeType t1 = parentType; t1 != objectType; t1 = (RuntimeType)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){
+ RuntimeType[] tempParentTypes = new RuntimeType[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).
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static MemberInfo[] GetSerializableMembers(Type type) {
+ return GetSerializableMembers(type, new StreamingContext(StreamingContextStates.All));
+ }
+
+ // Get all of the Serializable Members for a particular class. If we're not cloning, this is all
+ // non-transient, non-static fields. If we are cloning, include the transient fields as well since
+ // we know that we're going to live inside of the same context.
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static MemberInfo[] GetSerializableMembers(Type type, StreamingContext context) {
+ MemberInfo[] members;
+
+ if ((object)type==null) {
+ throw new ArgumentNullException("type");
+ }
+ Contract.EndContractBlock();
+
+ if (!(type is RuntimeType)) {
+ throw new SerializationException(Environment.GetResourceString("Serialization_InvalidType", type.ToString()));
+ }
+
+ MemberHolder mh = new MemberHolder(type, context);
+
+ //If we've already gathered the members for this type, just return them.
+ if (m_MemberInfoTable.ContainsKey(mh)) {
+ return m_MemberInfoTable[mh];
+ }
+
+ lock (formatterServicesSyncObject) {
+ //If we've already gathered the members for this type, just return them.
+ if (m_MemberInfoTable.ContainsKey(mh)) {
+ return m_MemberInfoTable[mh];
+ }
+
+ members = InternalGetSerializableMembers((RuntimeType)type);
+
+ m_MemberInfoTable[mh] = members;
+ }
+
+ return members;
+ }
+
+ static readonly Type[] advancedTypes = new Type[]{
+ typeof(System.DelegateSerializationHolder),
+#if FEATURE_REMOTING
+ typeof(System.Runtime.Remoting.ObjRef),
+ typeof(System.Runtime.Remoting.IEnvoyInfo),
+ typeof(System.Runtime.Remoting.Lifetime.ISponsor),
+#endif
+ };
+
+ public static void CheckTypeSecurity(Type t, TypeFilterLevel securityLevel) {
+ if (securityLevel == TypeFilterLevel.Low){
+ for(int i=0;i<advancedTypes.Length;i++){
+ if (advancedTypes[i].IsAssignableFrom(t))
+ throw new SecurityException(Environment.GetResourceString("Serialization_TypeSecurity", advancedTypes[i].FullName, t.FullName));
+ }
+ }
+ }
+#endif // FEATURE_SERIALIZATION
+
+ // Gets a new instance of the object. The entire object is initalized to 0 and no
+ // constructors have been run. **THIS MEANS THAT THE OBJECT MAY NOT BE IN A STATE
+ // CONSISTENT WITH ITS INTERNAL REQUIREMENTS** This method should only be used for
+ // deserialization when the user intends to immediately populate all fields. This method
+ // will not create an unitialized string because it is non-sensical to create an empty
+ // instance of an immutable type.
+ //
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Object GetUninitializedObject(Type type) {
+ if ((object)type == null) {
+ throw new ArgumentNullException("type");
+ }
+ Contract.EndContractBlock();
+
+ if (!(type is RuntimeType)) {
+ throw new SerializationException(Environment.GetResourceString("Serialization_InvalidType", type.ToString()));
+ }
+
+ return nativeGetUninitializedObject((RuntimeType)type);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Object GetSafeUninitializedObject(Type type) {
+ if ((object)type == null) {
+ throw new ArgumentNullException("type");
+ }
+ Contract.EndContractBlock();
+
+ if (!(type is RuntimeType)) {
+ throw new SerializationException(Environment.GetResourceString("Serialization_InvalidType", type.ToString()));
+ }
+#if FEATURE_REMOTING
+ if (Object.ReferenceEquals(type, typeof(System.Runtime.Remoting.Messaging.ConstructionCall)) ||
+ Object.ReferenceEquals(type, typeof(System.Runtime.Remoting.Messaging.LogicalCallContext)) ||
+ Object.ReferenceEquals(type, typeof(System.Runtime.Remoting.Contexts.SynchronizationAttribute)))
+ return nativeGetUninitializedObject((RuntimeType)type);
+#endif
+
+ try {
+ return nativeGetSafeUninitializedObject((RuntimeType)type);
+ }
+ catch(SecurityException e) {
+ throw new SerializationException(Environment.GetResourceString("Serialization_Security", type.FullName), e);
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern Object nativeGetSafeUninitializedObject(RuntimeType type);
+
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern Object nativeGetUninitializedObject(RuntimeType type);
+#if FEATURE_SERIALIZATION
+ [System.Security.SecurityCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern bool GetEnableUnsafeTypeForwarders();
+
+ [SecuritySafeCritical]
+ internal static bool UnsafeTypeForwardersIsEnabled()
+ {
+ if (!unsafeTypeForwardersIsEnabledInitialized)
+ {
+ unsafeTypeForwardersIsEnabled = GetEnableUnsafeTypeForwarders();
+ unsafeTypeForwardersIsEnabledInitialized = true;
+ }
+
+ return unsafeTypeForwardersIsEnabled;
+ }
+#endif
+ private static Binder s_binder = Type.DefaultBinder;
+ [System.Security.SecurityCritical]
+ internal static void SerializationSetValue(MemberInfo fi, Object target, Object value)
+ {
+ Contract.Requires(fi != null);
+
+ RtFieldInfo rtField = fi as RtFieldInfo;
+
+ if (rtField != null)
+ {
+ rtField.CheckConsistency(target);
+ rtField.UnsafeSetValue(target, value, BindingFlags.Default, s_binder, null);
+ return;
+ }
+
+ SerializationFieldInfo serField = fi as SerializationFieldInfo;
+ if (serField != null)
+ {
+ serField.InternalSetValue(target, value, BindingFlags.Default, s_binder, null);
+ return;
+ }
+
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFieldInfo"));
+ }
+
+ // Fill in the members of obj with the data contained in data.
+ // Returns the number of members populated.
+ //
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Object PopulateObjectMembers(Object obj, MemberInfo[] members, Object[] data) {
+ if (obj==null) {
+ throw new ArgumentNullException("obj");
+ }
+
+ if (members==null) {
+ throw new ArgumentNullException("members");
+ }
+
+ if (data==null) {
+ throw new ArgumentNullException("data");
+ }
+
+ if (members.Length!=data.Length) {
+ throw new ArgumentException(Environment.GetResourceString("Argument_DataLengthDifferent"));
+ }
+ Contract.EndContractBlock();
+
+ MemberInfo mi;
+
+ BCLDebug.Trace("SER", "[PopulateObjectMembers]Enter.");
+
+ for (int i=0; i<members.Length; i++) {
+ mi = members[i];
+
+ if (mi==null) {
+ throw new ArgumentNullException("members", Environment.GetResourceString("ArgumentNull_NullMember", i));
+ }
+
+ //If we find an empty, it means that the value was never set during deserialization.
+ //This is either a forward reference or a null. In either case, this may break some of the
+ //invariants mantained by the setter, so we'll do nothing with it for right now.
+ if (data[i]!=null) {
+ if (mi.MemberType==MemberTypes.Field) {
+ SerializationSetValue(mi, obj, data[i]);
+ } else {
+ throw new SerializationException(Environment.GetResourceString("Serialization_UnknownMemberInfo"));
+ }
+
+ BCLDebug.Trace("SER", "[PopulateObjectMembers]\tType:", obj.GetType(), "\tMember:",
+ members[i].Name, " with member type: ", ((FieldInfo)members[i]).FieldType);
+ }
+ //Console.WriteLine("X");
+ }
+
+ BCLDebug.Trace("SER", "[PopulateObjectMembers]Leave.");
+
+ return obj;
+ }
+
+ // Extracts the data from obj. members is the array of members which we wish to
+ // extract (must be FieldInfos or PropertyInfos). For each supplied member, extract the matching value and
+ // return it in a Object[] of the same size.
+ //
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Object[] GetObjectData(Object obj, MemberInfo[] members) {
+
+ if (obj==null) {
+ throw new ArgumentNullException("obj");
+ }
+
+ if (members==null) {
+ throw new ArgumentNullException("members");
+ }
+ Contract.EndContractBlock();
+
+ int numberOfMembers = members.Length;
+
+ Object[] data = new Object[numberOfMembers];
+ MemberInfo mi;
+
+ for (int i=0; i<numberOfMembers; i++) {
+ mi=members[i];
+
+ if (mi==null) {
+ throw new ArgumentNullException("members", Environment.GetResourceString("ArgumentNull_NullMember", i));
+ }
+
+ if (mi.MemberType==MemberTypes.Field) {
+ Contract.Assert(mi is RuntimeFieldInfo || mi is SerializationFieldInfo,
+ "[FormatterServices.GetObjectData]mi is RuntimeFieldInfo || mi is SerializationFieldInfo.");
+
+ RtFieldInfo rfi = mi as RtFieldInfo;
+ if (rfi != null) {
+ rfi.CheckConsistency(obj);
+ data[i] = rfi.UnsafeGetValue(obj);
+ } else {
+ data[i] = ((SerializationFieldInfo)mi).InternalGetValue(obj);
+ }
+ } else {
+ throw new SerializationException(Environment.GetResourceString("Serialization_UnknownMemberInfo"));
+ }
+ }
+
+ return data;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public static ISerializationSurrogate GetSurrogateForCyclicalReference(ISerializationSurrogate innerSurrogate)
+ {
+ if (innerSurrogate == null)
+ throw new ArgumentNullException("innerSurrogate");
+ Contract.EndContractBlock();
+ return new SurrogateForCyclicalReference(innerSurrogate);
+ }
+
+ /*=============================GetTypeFromAssembly==============================
+ **Action:
+ **Returns:
+ **Arguments:
+ **Exceptions:
+ ==============================================================================*/
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static Type GetTypeFromAssembly(Assembly assem, String name) {
+ if (assem==null)
+ throw new ArgumentNullException("assem");
+ Contract.EndContractBlock();
+ return assem.GetType(name, false, false);
+ }
+
+ /*============================LoadAssemblyFromString============================
+ **Action: Loads an assembly from a given string. The current assembly loading story
+ ** is quite confusing. If the assembly is in the fusion cache, we can load it
+ ** using the stringized-name which we transmitted over the wire. If that fails,
+ ** we try for a lookup of the assembly using the simple name which is the first
+ ** part of the assembly name. If we can't find it that way, we'll return null
+ ** as our failure result.
+ **Returns: The loaded assembly or null if it can't be found.
+ **Arguments: assemblyName -- The stringized assembly name.
+ **Exceptions: None
+ ==============================================================================*/
+ internal static Assembly LoadAssemblyFromString(String assemblyName) {
+ //
+ // Try using the stringized assembly name to load from the fusion cache.
+ //
+ BCLDebug.Trace("SER", "[LoadAssemblyFromString]Looking for assembly: ", assemblyName);
+ Assembly found = Assembly.Load(assemblyName);
+ return found;
+ }
+
+ internal static Assembly LoadAssemblyFromStringNoThrow(String assemblyName) {
+ try {
+ return LoadAssemblyFromString(assemblyName);
+ }
+ catch (Exception e){
+ BCLDebug.Trace("SER", "[LoadAssemblyFromString]", e.ToString());
+ }
+ return null;
+ }
+
+ internal static string GetClrAssemblyName(Type type, out bool hasTypeForwardedFrom) {
+ if ((object)type == null) {
+ throw new ArgumentNullException("type");
+ }
+
+ object[] typeAttributes = type.GetCustomAttributes(typeof(TypeForwardedFromAttribute), false);
+ if (typeAttributes != null && typeAttributes.Length > 0) {
+ hasTypeForwardedFrom = true;
+ TypeForwardedFromAttribute typeForwardedFromAttribute = (TypeForwardedFromAttribute)typeAttributes[0];
+ return typeForwardedFromAttribute.AssemblyFullName;
+ }
+ else {
+ hasTypeForwardedFrom = false;
+ return type.Assembly.FullName;
+ }
+ }
+
+ internal static string GetClrTypeFullName(Type type) {
+ if (type.IsArray) {
+ return GetClrTypeFullNameForArray(type);
+ }
+ else {
+ return GetClrTypeFullNameForNonArrayTypes(type);
+ }
+ }
+
+ static string GetClrTypeFullNameForArray(Type type) {
+ int rank = type.GetArrayRank();
+ if (rank == 1)
+ {
+ return String.Format(CultureInfo.InvariantCulture, "{0}{1}", GetClrTypeFullName(type.GetElementType()), "[]");
+ }
+ else
+ {
+ StringBuilder builder = new StringBuilder(GetClrTypeFullName(type.GetElementType())).Append("[");
+ for (int commaIndex = 1; commaIndex < rank; commaIndex++)
+ {
+ builder.Append(",");
+ }
+ builder.Append("]");
+ return builder.ToString();
+ }
+ }
+
+ static string GetClrTypeFullNameForNonArrayTypes(Type type) {
+ if (!type.IsGenericType) {
+ return type.FullName;
+ }
+
+ Type[] genericArguments = type.GetGenericArguments();
+ StringBuilder builder = new StringBuilder(type.GetGenericTypeDefinition().FullName).Append("[");
+ bool hasTypeForwardedFrom;
+
+ foreach (Type genericArgument in genericArguments) {
+ builder.Append("[").Append(GetClrTypeFullName(genericArgument)).Append(", ");
+ builder.Append(GetClrAssemblyName(genericArgument, out hasTypeForwardedFrom)).Append("],");
+ }
+
+ //remove the last comma and close typename for generic with a close bracket
+ return builder.Remove(builder.Length - 1, 1).Append("]").ToString();
+ }
+ }
+
+ internal sealed class SurrogateForCyclicalReference : ISerializationSurrogate
+ {
+ ISerializationSurrogate innerSurrogate;
+ internal SurrogateForCyclicalReference(ISerializationSurrogate innerSurrogate)
+ {
+ if (innerSurrogate == null)
+ throw new ArgumentNullException("innerSurrogate");
+ this.innerSurrogate = innerSurrogate;
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ public void GetObjectData(Object obj, SerializationInfo info, StreamingContext context)
+ {
+ innerSurrogate.GetObjectData(obj, info, context);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ public Object SetObjectData(Object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
+ {
+ return innerSurrogate.SetObjectData(obj, info, context, selector);
+ }
+ }
+}
+
+
+
+
+
diff --git a/src/mscorlib/src/System/Runtime/Serialization/IDeserializationCallback.cs b/src/mscorlib/src/System/Runtime/Serialization/IDeserializationCallback.cs
new file mode 100644
index 0000000000..e2497e5d34
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/IDeserializationCallback.cs
@@ -0,0 +1,23 @@
+// 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.
+
+/*============================================================
+**
+** Interface: IDeserializationEventListener
+**
+**
+** Purpose: Implemented by any class that wants to indicate that
+** it wishes to receive deserialization events.
+**
+**
+===========================================================*/
+namespace System.Runtime.Serialization {
+ using System;
+
+ // Interface does not need to be marked with the serializable attribute
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public interface IDeserializationCallback {
+ void OnDeserialization(Object sender);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/IFormatter.cs b/src/mscorlib/src/System/Runtime/Serialization/IFormatter.cs
new file mode 100644
index 0000000000..8d91d95acf
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/IFormatter.cs
@@ -0,0 +1,41 @@
+// 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.
+
+/*============================================================
+**
+** Interface: IFormatter;
+**
+**
+** Purpose: The interface for all formatters.
+**
+**
+===========================================================*/
+namespace System.Runtime.Serialization {
+ using System.Runtime.Remoting;
+ using System;
+ using System.IO;
+
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface IFormatter {
+ Object Deserialize(Stream serializationStream);
+
+ void Serialize(Stream serializationStream, Object graph);
+
+
+ ISurrogateSelector SurrogateSelector {
+ get;
+ set;
+ }
+
+ SerializationBinder Binder {
+ get;
+ set;
+ }
+
+ StreamingContext Context {
+ get;
+ set;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/IFormatterConverter.cs b/src/mscorlib/src/System/Runtime/Serialization/IFormatterConverter.cs
new file mode 100644
index 0000000000..182cc93412
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/IFormatterConverter.cs
@@ -0,0 +1,40 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: The interface provides the connection between an
+** instance of SerializationInfo and the formatter-provided
+** class which knows how to parse the data inside the
+** SerializationInfo.
+**
+**
+============================================================*/
+namespace System.Runtime.Serialization {
+ using System;
+
+ [CLSCompliant(false)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface IFormatterConverter {
+ Object Convert(Object value, Type type);
+ Object Convert(Object value, TypeCode typeCode);
+ bool ToBoolean(Object value);
+ char ToChar(Object value);
+ sbyte ToSByte(Object value);
+ byte ToByte(Object value);
+ short ToInt16(Object value);
+ ushort ToUInt16(Object value);
+ int ToInt32(Object value);
+ uint ToUInt32(Object value);
+ long ToInt64(Object value);
+ ulong ToUInt64(Object value);
+ float ToSingle(Object value);
+ double ToDouble(Object value);
+ Decimal ToDecimal(Object value);
+ DateTime ToDateTime(Object value);
+ String ToString(Object value);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs b/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs
new file mode 100644
index 0000000000..f1a1bc0590
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs
@@ -0,0 +1,30 @@
+// 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.
+
+/*============================================================
+**
+** Interface: IObjectReference
+**
+**
+** Purpose: Implemented by objects that are actually references
+** to a different object which can't be discovered until
+** this one is completely restored. During the fixup stage,
+** any object implementing IObjectReference is asked for it's
+** "real" object and that object is inserted into the graph.
+**
+**
+===========================================================*/
+namespace System.Runtime.Serialization {
+
+ using System;
+ using System.Security.Permissions;
+ // Interface does not need to be marked with the serializable attribute
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface IObjectReference {
+ [System.Security.SecurityCritical] // auto-generated_required
+ Object GetRealObject(StreamingContext context);
+ }
+}
+
+
diff --git a/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs b/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs
new file mode 100644
index 0000000000..e59fa65043
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs
@@ -0,0 +1,33 @@
+// 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.
+
+/*============================================================
+**
+** Interface: ISerializable
+**
+**
+** Purpose: Implemented by any object that needs to control its
+** own serialization.
+**
+**
+===========================================================*/
+
+namespace System.Runtime.Serialization {
+ using System.Runtime.Remoting;
+ using System.Runtime.Serialization;
+ using System.Security.Permissions;
+ using System;
+ using System.Reflection;
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public interface ISerializable {
+ [System.Security.SecurityCritical] // auto-generated_required
+ void GetObjectData(SerializationInfo info, StreamingContext context);
+ }
+
+}
+
+
+
+
diff --git a/src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs b/src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs
new file mode 100644
index 0000000000..9bb30d99e0
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs
@@ -0,0 +1,36 @@
+// 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.
+
+/*============================================================
+**
+** Interface: ISurrogate
+**
+**
+** Purpose: The interface implemented by an object which
+** supports surrogates.
+**
+**
+===========================================================*/
+namespace System.Runtime.Serialization {
+ using System.Runtime.Remoting;
+ using System.Runtime.Serialization;
+ using System.Security.Permissions;
+ using System;
+ using System.Reflection;
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface ISerializationSurrogate {
+ // Interface does not need to be marked with the serializable attribute
+ // Returns a SerializationInfo completely populated with all of the data needed to reinstantiate the
+ // the object at the other end of serialization.
+ //
+ [System.Security.SecurityCritical] // auto-generated_required
+ void GetObjectData(Object obj, SerializationInfo info, StreamingContext context);
+
+ // Reinflate the object using all of the information in data. The information in
+ // members is used to find the particular field or property which needs to be set.
+ //
+ [System.Security.SecurityCritical] // auto-generated_required
+ Object SetObjectData(Object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs b/src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs
new file mode 100644
index 0000000000..01b960f86b
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs
@@ -0,0 +1,37 @@
+// 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.
+
+/*============================================================
+**
+** Interface: ISurrogateSelector
+**
+**
+** Purpose: A user-supplied class for doing the type to surrogate
+** mapping.
+**
+**
+===========================================================*/
+namespace System.Runtime.Serialization {
+
+ using System.Runtime.Remoting;
+ using System.Security.Permissions;
+ using System;
+[System.Runtime.InteropServices.ComVisible(true)]
+ public interface ISurrogateSelector {
+ // Interface does not need to be marked with the serializable attribute
+ // Specifies the next ISurrogateSelector to be examined for surrogates if the current
+ // instance doesn't have a surrogate for the given type and assembly in the given context.
+ [System.Security.SecurityCritical] // auto-generated_required
+ void ChainSelector(ISurrogateSelector selector);
+
+ // Returns the appropriate surrogate for the given type in the given context.
+ [System.Security.SecurityCritical] // auto-generated_required
+ ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector);
+
+
+ // Return the next surrogate in the chain. Returns null if no more exist.
+ [System.Security.SecurityCritical] // auto-generated_required
+ ISurrogateSelector GetNextSelector();
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/MemberHolder.cs b/src/mscorlib/src/System/Runtime/Serialization/MemberHolder.cs
new file mode 100644
index 0000000000..1303e40c27
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/MemberHolder.cs
@@ -0,0 +1,51 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: This is a lightweight class designed to hold the members
+** and StreamingContext for a particular class.
+**
+**
+============================================================*/
+namespace System.Runtime.Serialization {
+
+ using System.Runtime.Remoting;
+ using System;
+ using System.Reflection;
+ [Serializable]
+ internal class MemberHolder {
+// disable csharp compiler warning #0414: field assigned unused value
+#pragma warning disable 0414
+ internal MemberInfo[] members = null;
+#pragma warning restore 0414
+ internal Type memberType;
+ internal StreamingContext context;
+
+ internal MemberHolder(Type type, StreamingContext ctx) {
+ memberType = type;
+ context = ctx;
+ }
+
+ public override int GetHashCode() {
+ return memberType.GetHashCode();
+ }
+
+ public override bool Equals(Object obj) {
+ if (!(obj is MemberHolder)) {
+ return false;
+ }
+
+ MemberHolder temp = (MemberHolder)obj;
+
+ if (Object.ReferenceEquals(temp.memberType, memberType) && temp.context.State == context.State) {
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationAttributes.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationAttributes.cs
new file mode 100644
index 0000000000..27c5751cc6
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationAttributes.cs
@@ -0,0 +1,64 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: Various Attributes for Serialization
+**
+**
+============================================================*/
+namespace System.Runtime.Serialization
+{
+ using System;
+ using System.Diagnostics.Contracts;
+ using System.Reflection;
+
+ [AttributeUsage(AttributeTargets.Field, Inherited=false)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class OptionalFieldAttribute : Attribute
+ {
+ int versionAdded = 1;
+ public OptionalFieldAttribute() { }
+
+ public int VersionAdded
+ {
+ get {
+ return this.versionAdded;
+ }
+ set {
+ if (value < 1)
+ throw new ArgumentException(Environment.GetResourceString("Serialization_OptionalFieldVersionValue"));
+ Contract.EndContractBlock();
+ this.versionAdded = value;
+ }
+ }
+ }
+
+ [AttributeUsage(AttributeTargets.Method, Inherited=false)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class OnSerializingAttribute : Attribute
+ {
+ }
+
+ [AttributeUsage(AttributeTargets.Method, Inherited=false)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class OnSerializedAttribute : Attribute
+ {
+ }
+
+ [AttributeUsage(AttributeTargets.Method, Inherited=false)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class OnDeserializingAttribute : Attribute
+ {
+ }
+
+ [AttributeUsage(AttributeTargets.Method, Inherited=false)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class OnDeserializedAttribute : Attribute
+ {
+ }
+
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationBinder.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationBinder.cs
new file mode 100644
index 0000000000..7457991008
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationBinder.cs
@@ -0,0 +1,29 @@
+// 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.
+
+/*============================================================
+**
+** Interface: SerializationBinder
+**
+**
+** Purpose: The base class of serialization binders.
+**
+**
+===========================================================*/
+namespace System.Runtime.Serialization {
+ using System;
+
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public abstract class SerializationBinder {
+
+ public virtual void BindToName(Type serializedType, out String assemblyName, out String typeName)
+ {
+ assemblyName = null;
+ typeName = null;
+ }
+
+ public abstract Type BindToType(String assemblyName, String typeName);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationException.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationException.cs
new file mode 100644
index 0000000000..b88ccfd706
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationException.cs
@@ -0,0 +1,45 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Thrown when something goes wrong during serialization or
+** deserialization.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.Serialization {
+
+ using System;
+ using System.Runtime.Serialization;
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ [Serializable]
+ public class SerializationException : SystemException {
+
+ private static String _nullMessage = Environment.GetResourceString("Arg_SerializationException");
+
+ // Creates a new SerializationException with its message
+ // string set to a default message.
+ public SerializationException()
+ : base(_nullMessage) {
+ SetErrorCode(__HResults.COR_E_SERIALIZATION);
+ }
+
+ public SerializationException(String message)
+ : base(message) {
+ SetErrorCode(__HResults.COR_E_SERIALIZATION);
+ }
+
+ public SerializationException(String message, Exception innerException) : base (message, innerException) {
+ SetErrorCode(__HResults.COR_E_SERIALIZATION);
+ }
+
+ protected SerializationException(SerializationInfo info, StreamingContext context) : base (info, context) {
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs
new file mode 100644
index 0000000000..5e7851bc57
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs
@@ -0,0 +1,166 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** 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 RuntimeFieldInfo associated with this member
+** and return a managled form of the name. The name that we
+** return is .parentname.fieldname
+**
+**
+============================================================*/
+
+namespace System.Runtime.Serialization {
+
+ using System;
+ using System.Reflection;
+ using System.Globalization;
+ using System.Diagnostics.Contracts;
+ using System.Threading;
+#if FEATURE_REMOTING
+ using System.Runtime.Remoting.Metadata;
+#endif //FEATURE_REMOTING
+
+ internal sealed class SerializationFieldInfo : FieldInfo {
+
+ internal const String FakeNameSeparatorString = "+";
+
+ private RuntimeFieldInfo m_field;
+ private String m_serializationName;
+
+ public override Module Module { get { return m_field.Module; } }
+ public override int MetadataToken { get { return m_field.MetadataToken; } }
+
+ internal SerializationFieldInfo(RuntimeFieldInfo field, String namePrefix) {
+ Contract.Assert(field!=null, "[SerializationFieldInfo.ctor]field!=null");
+ Contract.Assert(namePrefix!=null, "[SerializationFieldInfo.ctor]namePrefix!=null");
+
+ m_field = field;
+ m_serializationName = String.Concat(namePrefix, FakeNameSeparatorString, m_field.Name);
+ }
+
+ //
+ // MemberInfo methods
+ //
+ public override String Name {
+ get {
+ return m_serializationName;
+ }
+ }
+
+ public override Type DeclaringType {
+ get {
+ return m_field.DeclaringType;
+ }
+ }
+
+ public override Type ReflectedType {
+ get {
+ return m_field.ReflectedType;
+ }
+ }
+
+ public override Object[] GetCustomAttributes(bool inherit) {
+ return m_field.GetCustomAttributes(inherit);
+ }
+
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit) {
+ return m_field.GetCustomAttributes(attributeType, inherit);
+ }
+
+ public override bool IsDefined(Type attributeType, bool inherit) {
+ return m_field.IsDefined(attributeType, inherit);
+ }
+
+ //
+ // FieldInfo methods
+ //
+ public override Type FieldType {
+ get {
+ return m_field.FieldType;
+ }
+ }
+
+ public override Object GetValue(Object obj) {
+ return m_field.GetValue(obj);
+ }
+
+ [System.Security.SecurityCritical]
+ internal Object InternalGetValue(Object obj) {
+ RtFieldInfo field = m_field as RtFieldInfo;
+ if (field != null)
+ {
+ field.CheckConsistency(obj);
+ return field.UnsafeGetValue(obj);
+ }
+ else
+ return m_field.GetValue(obj);
+ }
+
+ public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) {
+ m_field.SetValue(obj, value, invokeAttr, binder, culture);
+ }
+
+ [System.Security.SecurityCritical]
+ internal void InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) {
+ RtFieldInfo field = m_field as RtFieldInfo;
+ if (field != null)
+ {
+ field.CheckConsistency(obj);
+ field.UnsafeSetValue(obj, value, invokeAttr, binder, culture);
+ }
+ else
+ m_field.SetValue(obj, value, invokeAttr, binder, culture);
+ }
+
+ internal RuntimeFieldInfo FieldInfo {
+ get {
+ return m_field;
+ }
+ }
+
+ public override RuntimeFieldHandle FieldHandle {
+ get {
+ return m_field.FieldHandle;
+ }
+ }
+
+ public override FieldAttributes Attributes {
+ get {
+ return m_field.Attributes;
+ }
+ }
+
+#if FEATURE_REMOTING
+ #region Legacy Remoting Cache
+ private RemotingFieldCachedData m_cachedData;
+
+ internal RemotingFieldCachedData RemotingCache
+ {
+ get
+ {
+ // This grabs an internal copy of m_cachedData and uses
+ // that instead of looking at m_cachedData directly because
+ // the cache may get cleared asynchronously. This prevents
+ // us from having to take a lock.
+ RemotingFieldCachedData cache = m_cachedData;
+ if (cache == null)
+ {
+ cache = new RemotingFieldCachedData(this);
+ RemotingFieldCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
+ if (ret != null)
+ cache = ret;
+ }
+ return cache;
+ }
+ }
+ #endregion
+#endif //FEATURE_REMOTING
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs
new file mode 100644
index 0000000000..94e6825b51
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs
@@ -0,0 +1,798 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: The structure for holding all of the data needed
+** for object serialization and deserialization.
+**
+**
+===========================================================*/
+namespace System.Runtime.Serialization
+{
+
+ using System;
+ using System.Collections.Generic;
+ using System.Reflection;
+ using System.Runtime.Remoting;
+#if FEATURE_REMOTING
+ using System.Runtime.Remoting.Proxies;
+#endif
+ using System.Globalization;
+ using System.Diagnostics.Contracts;
+ using System.Security;
+#if FEATURE_CORECLR
+ using System.Runtime.CompilerServices;
+#endif
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class SerializationInfo
+ {
+ private const int defaultSize = 4;
+ private const string s_mscorlibAssemblySimpleName = System.CoreLib.Name;
+ private const string s_mscorlibFileName = s_mscorlibAssemblySimpleName + ".dll";
+
+ // Even though we have a dictionary, we're still keeping all the arrays around for back-compat.
+ // Otherwise we may run into potentially breaking behaviors like GetEnumerator() not returning entries in the same order they were added.
+ internal String[] m_members;
+ internal Object[] m_data;
+ internal Type[] m_types;
+ private Dictionary<string, int> m_nameToIndex;
+ internal int m_currMember;
+ internal IFormatterConverter m_converter;
+ private String m_fullTypeName;
+ private String m_assemName;
+ private Type objectType;
+ private bool isFullTypeNameSetExplicit;
+ private bool isAssemblyNameSetExplicit;
+ private bool requireSameTokenInPartialTrust;
+
+ [CLSCompliant(false)]
+ public SerializationInfo(Type type, IFormatterConverter converter)
+ : this(type, converter, false)
+ {
+ }
+
+ [CLSCompliant(false)]
+ public SerializationInfo(Type type, IFormatterConverter converter, bool requireSameTokenInPartialTrust)
+ {
+ if ((object)type == null)
+ {
+ throw new ArgumentNullException("type");
+ }
+
+ if (converter == null)
+ {
+ throw new ArgumentNullException("converter");
+ }
+
+ Contract.EndContractBlock();
+
+ objectType = type;
+ m_fullTypeName = type.FullName;
+ m_assemName = type.Module.Assembly.FullName;
+
+ m_members = new String[defaultSize];
+ m_data = new Object[defaultSize];
+ m_types = new Type[defaultSize];
+
+ m_nameToIndex = new Dictionary<string, int>();
+
+ m_converter = converter;
+
+ this.requireSameTokenInPartialTrust = requireSameTokenInPartialTrust;
+ }
+
+ public String FullTypeName
+ {
+ get
+ {
+ return m_fullTypeName;
+ }
+ set
+ {
+ if (null == value)
+ {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+
+ m_fullTypeName = value;
+ isFullTypeNameSetExplicit = true;
+ }
+ }
+
+ public String AssemblyName
+ {
+ get
+ {
+ return m_assemName;
+ }
+ [SecuritySafeCritical]
+ set
+ {
+ if (null == value)
+ {
+ throw new ArgumentNullException("value");
+ }
+ Contract.EndContractBlock();
+ if (this.requireSameTokenInPartialTrust)
+ {
+ DemandForUnsafeAssemblyNameAssignments(this.m_assemName, value);
+ }
+ m_assemName = value;
+ isAssemblyNameSetExplicit = true;
+ }
+ }
+
+ [SecuritySafeCritical]
+ public void SetType(Type type)
+ {
+ if ((object)type == null)
+ {
+ throw new ArgumentNullException("type");
+ }
+ Contract.EndContractBlock();
+
+ if (this.requireSameTokenInPartialTrust)
+ {
+ DemandForUnsafeAssemblyNameAssignments(this.ObjectType.Assembly.FullName, type.Assembly.FullName);
+ }
+
+ if (!Object.ReferenceEquals(objectType, type))
+ {
+ objectType = type;
+ m_fullTypeName = type.FullName;
+ m_assemName = type.Module.Assembly.FullName;
+ isFullTypeNameSetExplicit = false;
+ isAssemblyNameSetExplicit = false;
+ }
+ }
+
+ private static bool Compare(byte[] a, byte[] b)
+ {
+ // if either or both assemblies do not have public key token, we should demand, hence, returning false will force a demand
+ if (a == null || b == null || a.Length == 0 || b.Length == 0 || a.Length != b.Length)
+ {
+ return false;
+ }
+ else
+ {
+ for (int i = 0; i < a.Length; i++)
+ {
+ if (a[i] != b[i]) return false;
+ }
+
+ return true;
+ }
+ }
+
+ [SecuritySafeCritical]
+ internal static void DemandForUnsafeAssemblyNameAssignments(string originalAssemblyName, string newAssemblyName)
+ {
+#if !FEATURE_CORECLR
+ if (!IsAssemblyNameAssignmentSafe(originalAssemblyName, newAssemblyName))
+ {
+ CodeAccessPermission.Demand(PermissionType.SecuritySerialization);
+ }
+#endif
+ }
+
+ internal static bool IsAssemblyNameAssignmentSafe(string originalAssemblyName, string newAssemblyName)
+ {
+ if (originalAssemblyName == newAssemblyName)
+ {
+ return true;
+ }
+
+ AssemblyName originalAssembly = new AssemblyName(originalAssemblyName);
+ AssemblyName newAssembly = new AssemblyName(newAssemblyName);
+
+ // mscorlib will get loaded by the runtime regardless of its string casing or its public key token,
+ // so setting the assembly name to mscorlib must always be protected by a demand
+ if (string.Equals(newAssembly.Name, s_mscorlibAssemblySimpleName, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(newAssembly.Name, s_mscorlibFileName, StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+
+ return Compare(originalAssembly.GetPublicKeyToken(), newAssembly.GetPublicKeyToken());
+ }
+
+ public int MemberCount
+ {
+ get
+ {
+ return m_currMember;
+ }
+ }
+
+ public Type ObjectType
+ {
+ get
+ {
+ return objectType;
+ }
+ }
+
+ public bool IsFullTypeNameSetExplicit
+ {
+ get
+ {
+ return isFullTypeNameSetExplicit;
+ }
+ }
+
+ public bool IsAssemblyNameSetExplicit
+ {
+ get
+ {
+ return isAssemblyNameSetExplicit;
+ }
+ }
+
+ public SerializationInfoEnumerator GetEnumerator()
+ {
+ return new SerializationInfoEnumerator(m_members, m_data, m_types, m_currMember);
+ }
+
+ private void ExpandArrays()
+ {
+ int newSize;
+ Contract.Assert(m_members.Length == m_currMember, "[SerializationInfo.ExpandArrays]m_members.Length == m_currMember");
+
+ newSize = (m_currMember * 2);
+
+ //
+ // In the pathological case, we may wrap
+ //
+ if (newSize < m_currMember)
+ {
+ if (Int32.MaxValue > m_currMember)
+ {
+ newSize = Int32.MaxValue;
+ }
+ }
+
+ //
+ // Allocate more space and copy the data
+ //
+ String[] newMembers = new String[newSize];
+ Object[] newData = new Object[newSize];
+ Type[] newTypes = new Type[newSize];
+
+ Array.Copy(m_members, newMembers, m_currMember);
+ Array.Copy(m_data, newData, m_currMember);
+ Array.Copy(m_types, newTypes, m_currMember);
+
+ //
+ // Assign the new arrys back to the member vars.
+ //
+ m_members = newMembers;
+ m_data = newData;
+ m_types = newTypes;
+ }
+
+ public void AddValue(String name, Object value, Type type)
+ {
+ if (null == name)
+ {
+ throw new ArgumentNullException("name");
+ }
+
+ if ((object)type == null)
+ {
+ throw new ArgumentNullException("type");
+ }
+ Contract.EndContractBlock();
+
+ AddValueInternal(name, value, type);
+ }
+
+ public void AddValue(String name, Object value)
+ {
+ if (null == value)
+ {
+ AddValue(name, value, typeof(Object));
+ }
+ else
+ {
+ AddValue(name, value, value.GetType());
+ }
+ }
+
+ public void AddValue(String name, bool value)
+ {
+ AddValue(name, (Object)value, typeof(bool));
+ }
+
+ public void AddValue(String name, char value)
+ {
+ AddValue(name, (Object)value, typeof(char));
+ }
+
+
+ [CLSCompliant(false)]
+ public void AddValue(String name, sbyte value)
+ {
+ AddValue(name, (Object)value, typeof(sbyte));
+ }
+
+ public void AddValue(String name, byte value)
+ {
+ AddValue(name, (Object)value, typeof(byte));
+ }
+
+ public void AddValue(String name, short value)
+ {
+ AddValue(name, (Object)value, typeof(short));
+ }
+
+ [CLSCompliant(false)]
+ public void AddValue(String name, ushort value)
+ {
+ AddValue(name, (Object)value, typeof(ushort));
+ }
+
+ public void AddValue(String name, int value)
+ {
+ AddValue(name, (Object)value, typeof(int));
+ }
+
+ [CLSCompliant(false)]
+ public void AddValue(String name, uint value)
+ {
+ AddValue(name, (Object)value, typeof(uint));
+ }
+
+ public void AddValue(String name, long value)
+ {
+ AddValue(name, (Object)value, typeof(long));
+ }
+
+ [CLSCompliant(false)]
+ public void AddValue(String name, ulong value)
+ {
+ AddValue(name, (Object)value, typeof(ulong));
+ }
+
+ public void AddValue(String name, float value)
+ {
+ AddValue(name, (Object)value, typeof(float));
+ }
+
+ public void AddValue(String name, double value)
+ {
+ AddValue(name, (Object)value, typeof(double));
+ }
+
+ public void AddValue(String name, decimal value)
+ {
+ AddValue(name, (Object)value, typeof(decimal));
+ }
+
+ public void AddValue(String name, DateTime value)
+ {
+ AddValue(name, (Object)value, typeof(DateTime));
+ }
+
+ internal void AddValueInternal(String name, Object value, Type type)
+ {
+ if (m_nameToIndex.ContainsKey(name))
+ {
+ BCLDebug.Trace("SER", "[SerializationInfo.AddValue]Tried to add ", name, " twice to the SI.");
+ throw new SerializationException(Environment.GetResourceString("Serialization_SameNameTwice"));
+ }
+ m_nameToIndex.Add(name, m_currMember);
+
+ //
+ // If we need to expand the arrays, do so.
+ //
+ if (m_currMember >= m_members.Length)
+ {
+ ExpandArrays();
+ }
+
+ //
+ // Add the data and then advance the counter.
+ //
+ m_members[m_currMember] = name;
+ m_data[m_currMember] = value;
+ m_types[m_currMember] = type;
+ m_currMember++;
+ }
+
+ /*=================================UpdateValue==================================
+ **Action: Finds the value if it exists in the current data. If it does, we replace
+ ** the values, if not, we append it to the end. This is useful to the
+ ** ObjectManager when it's performing fixups.
+ **Returns: void
+ **Arguments: name -- the name of the data to be updated.
+ ** value -- the new value.
+ ** type -- the type of the data being added.
+ **Exceptions: None. All error checking is done with asserts. Although public in coreclr,
+ ** it's not exposed in a contract and is only meant to be used by corefx.
+ ==============================================================================*/
+#if FEATURE_CORECLR
+ // This should not be used by clients: exposing out this functionality would allow children
+ // to overwrite their parent's values. It is public in order to give corefx access to it for
+ // its ObjectManager implementation, but it should not be exposed out of a contract.
+ public
+#else
+ internal
+#endif
+ void UpdateValue(String name, Object value, Type type)
+ {
+ Contract.Assert(null != name, "[SerializationInfo.UpdateValue]name!=null");
+ Contract.Assert(null != value, "[SerializationInfo.UpdateValue]value!=null");
+ Contract.Assert(null != (object)type, "[SerializationInfo.UpdateValue]type!=null");
+
+ int index = FindElement(name);
+ if (index < 0)
+ {
+ AddValueInternal(name, value, type);
+ }
+ else
+ {
+ m_data[index] = value;
+ m_types[index] = type;
+ }
+
+ }
+
+ private int FindElement(String name)
+ {
+ if (null == name)
+ {
+ throw new ArgumentNullException("name");
+ }
+ Contract.EndContractBlock();
+ BCLDebug.Trace("SER", "[SerializationInfo.FindElement]Looking for ", name, " CurrMember is: ", m_currMember);
+ int index;
+ if (m_nameToIndex.TryGetValue(name, out index))
+ {
+ return index;
+ }
+ return -1;
+ }
+
+ /*==================================GetElement==================================
+ **Action: Use FindElement to get the location of a particular member and then return
+ ** the value of the element at that location. The type of the member is
+ ** returned in the foundType field.
+ **Returns: The value of the element at the position associated with name.
+ **Arguments: name -- the name of the element to find.
+ ** foundType -- the type of the element associated with the given name.
+ **Exceptions: None. FindElement does null checking and throws for elements not
+ ** found.
+ ==============================================================================*/
+ private Object GetElement(String name, out Type foundType)
+ {
+ int index = FindElement(name);
+ if (index == -1)
+ {
+ throw new SerializationException(Environment.GetResourceString("Serialization_NotFound", name));
+ }
+
+ Contract.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
+ Contract.Assert(index < m_types.Length, "[SerializationInfo.GetElement]index<m_types.Length");
+
+ foundType = m_types[index];
+ Contract.Assert((object)foundType != null, "[SerializationInfo.GetElement]foundType!=null");
+ return m_data[index];
+ }
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ private Object GetElementNoThrow(String name, out Type foundType)
+ {
+ int index = FindElement(name);
+ if (index == -1)
+ {
+ foundType = null;
+ return null;
+ }
+
+ Contract.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
+ Contract.Assert(index < m_types.Length, "[SerializationInfo.GetElement]index<m_types.Length");
+
+ foundType = m_types[index];
+ Contract.Assert((object)foundType != null, "[SerializationInfo.GetElement]foundType!=null");
+ return m_data[index];
+ }
+
+ //
+ // The user should call one of these getters to get the data back in the
+ // form requested.
+ //
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public Object GetValue(String name, Type type)
+ {
+
+ if ((object)type == null)
+ {
+ throw new ArgumentNullException("type");
+ }
+ Contract.EndContractBlock();
+
+ RuntimeType rt = type as RuntimeType;
+ if (rt == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
+
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+#if FEATURE_REMOTING
+ if (RemotingServices.IsTransparentProxy(value))
+ {
+ RealProxy proxy = RemotingServices.GetRealProxy(value);
+ if (RemotingServices.ProxyCheckCast(proxy, rt))
+ return value;
+ }
+ else
+#endif
+ if (Object.ReferenceEquals(foundType, type) || type.IsAssignableFrom(foundType) || value == null)
+ {
+ return value;
+ }
+
+ Contract.Assert(m_converter != null, "[SerializationInfo.GetValue]m_converter!=null");
+
+ return m_converter.Convert(value, type);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [System.Runtime.InteropServices.ComVisible(true)]
+ internal Object GetValueNoThrow(String name, Type type)
+ {
+ Type foundType;
+ Object value;
+
+ Contract.Assert((object)type != null, "[SerializationInfo.GetValue]type ==null");
+ Contract.Assert(type is RuntimeType, "[SerializationInfo.GetValue]type is not a runtime type");
+
+ value = GetElementNoThrow(name, out foundType);
+ if (value == null)
+ return null;
+#if FEATURE_REMOTING
+ if (RemotingServices.IsTransparentProxy(value))
+ {
+ RealProxy proxy = RemotingServices.GetRealProxy(value);
+ if (RemotingServices.ProxyCheckCast(proxy, (RuntimeType)type))
+ return value;
+ }
+ else
+#endif
+ if (Object.ReferenceEquals(foundType, type) || type.IsAssignableFrom(foundType) || value == null)
+ {
+ return value;
+ }
+
+ Contract.Assert(m_converter != null, "[SerializationInfo.GetValue]m_converter!=null");
+
+ return m_converter.Convert(value, type);
+ }
+
+ public bool GetBoolean(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(bool)))
+ {
+ return (bool)value;
+ }
+ return m_converter.ToBoolean(value);
+ }
+
+ public char GetChar(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(char)))
+ {
+ return (char)value;
+ }
+ return m_converter.ToChar(value);
+ }
+
+ [CLSCompliant(false)]
+ public sbyte GetSByte(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(sbyte)))
+ {
+ return (sbyte)value;
+ }
+ return m_converter.ToSByte(value);
+ }
+
+ public byte GetByte(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(byte)))
+ {
+ return (byte)value;
+ }
+ return m_converter.ToByte(value);
+ }
+
+ public short GetInt16(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(short)))
+ {
+ return (short)value;
+ }
+ return m_converter.ToInt16(value);
+ }
+
+ [CLSCompliant(false)]
+ public ushort GetUInt16(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(ushort)))
+ {
+ return (ushort)value;
+ }
+ return m_converter.ToUInt16(value);
+ }
+
+ public int GetInt32(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(int)))
+ {
+ return (int)value;
+ }
+ return m_converter.ToInt32(value);
+ }
+
+ [CLSCompliant(false)]
+ public uint GetUInt32(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(uint)))
+ {
+ return (uint)value;
+ }
+ return m_converter.ToUInt32(value);
+ }
+
+ public long GetInt64(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(long)))
+ {
+ return (long)value;
+ }
+ return m_converter.ToInt64(value);
+ }
+
+ [CLSCompliant(false)]
+ public ulong GetUInt64(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(ulong)))
+ {
+ return (ulong)value;
+ }
+ return m_converter.ToUInt64(value);
+ }
+
+ public float GetSingle(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(float)))
+ {
+ return (float)value;
+ }
+ return m_converter.ToSingle(value);
+ }
+
+
+ public double GetDouble(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(double)))
+ {
+ return (double)value;
+ }
+ return m_converter.ToDouble(value);
+ }
+
+ public decimal GetDecimal(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(decimal)))
+ {
+ return (decimal)value;
+ }
+ return m_converter.ToDecimal(value);
+ }
+
+ public DateTime GetDateTime(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(DateTime)))
+ {
+ return (DateTime)value;
+ }
+ return m_converter.ToDateTime(value);
+ }
+
+ public String GetString(String name)
+ {
+ Type foundType;
+ Object value;
+
+ value = GetElement(name, out foundType);
+ if (Object.ReferenceEquals(foundType, typeof(String)) || value == null)
+ {
+ return (String)value;
+ }
+ return m_converter.ToString(value);
+ }
+
+ internal string[] MemberNames
+ {
+ get
+ {
+ return m_members;
+ }
+
+ }
+
+ internal object[] MemberValues
+ {
+ get
+ {
+ return m_data;
+ }
+ }
+
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs
new file mode 100644
index 0000000000..6b256a6e1f
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs
@@ -0,0 +1,146 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: A formatter-friendly mechanism for walking all of
+** the data in a SerializationInfo. Follows the IEnumerator
+** mechanism from Collections.
+**
+**
+============================================================*/
+namespace System.Runtime.Serialization {
+ using System;
+ using System.Collections;
+ using System.Diagnostics.Contracts;
+
+ //
+ // The tuple returned by SerializationInfoEnumerator.Current.
+ //
+[System.Runtime.InteropServices.ComVisible(true)]
+ public struct SerializationEntry {
+ private Type m_type;
+ private Object m_value;
+ private String m_name;
+
+ public Object Value {
+ get {
+ return m_value;
+ }
+ }
+
+ public String Name {
+ get {
+ return m_name;
+ }
+ }
+
+ public Type ObjectType {
+ get {
+ return m_type;
+ }
+ }
+
+ internal SerializationEntry(String entryName, Object entryValue, Type entryType) {
+ m_value = entryValue;
+ m_name = entryName;
+ m_type = entryType;
+ }
+ }
+
+ //
+ // A simple enumerator over the values stored in the SerializationInfo.
+ // This does not snapshot the values, it just keeps pointers to the
+ // member variables of the SerializationInfo that created it.
+ //
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class SerializationInfoEnumerator : IEnumerator {
+ String[] m_members;
+ Object[] m_data;
+ Type[] m_types;
+ int m_numItems;
+ int m_currItem;
+ bool m_current;
+
+ internal SerializationInfoEnumerator(String[] members, Object[] info, Type[] types, int numItems) {
+ Contract.Assert(members!=null, "[SerializationInfoEnumerator.ctor]members!=null");
+ Contract.Assert(info!=null, "[SerializationInfoEnumerator.ctor]info!=null");
+ Contract.Assert(types!=null, "[SerializationInfoEnumerator.ctor]types!=null");
+ Contract.Assert(numItems>=0, "[SerializationInfoEnumerator.ctor]numItems>=0");
+ Contract.Assert(members.Length>=numItems, "[SerializationInfoEnumerator.ctor]members.Length>=numItems");
+ Contract.Assert(info.Length>=numItems, "[SerializationInfoEnumerator.ctor]info.Length>=numItems");
+ Contract.Assert(types.Length>=numItems, "[SerializationInfoEnumerator.ctor]types.Length>=numItems");
+
+ m_members = members;
+ m_data = info;
+ m_types = types;
+ //The MoveNext semantic is much easier if we enforce that [0..m_numItems] are valid entries
+ //in the enumerator, hence we subtract 1.
+ m_numItems = numItems-1;
+ m_currItem = -1;
+ m_current = false;
+ }
+
+ public bool MoveNext() {
+ if (m_currItem<m_numItems) {
+ m_currItem++;
+ m_current = true;
+ } else {
+ m_current = false;
+ }
+ return m_current;
+ }
+
+ /// <internalonly/>
+ Object IEnumerator.Current { //Actually returns a SerializationEntry
+ get {
+ if (m_current==false) {
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ }
+ return (Object)(new SerializationEntry(m_members[m_currItem], m_data[m_currItem], m_types[m_currItem]));
+ }
+ }
+
+ public SerializationEntry Current { //Actually returns a SerializationEntry
+ get {
+ if (m_current==false) {
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ }
+ return (new SerializationEntry(m_members[m_currItem], m_data[m_currItem], m_types[m_currItem]));
+ }
+ }
+
+ public void Reset() {
+ m_currItem = -1;
+ m_current = false;
+ }
+
+ public String Name {
+ get {
+ if (m_current==false) {
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ }
+ return m_members[m_currItem];
+ }
+ }
+ public Object Value {
+ get {
+ if (m_current==false) {
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ }
+ return m_data[m_currItem];
+ }
+ }
+ public Type ObjectType {
+ get {
+ if (m_current==false) {
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ }
+ return m_types[m_currItem];
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/StreamingContext.cs b/src/mscorlib/src/System/Runtime/Serialization/StreamingContext.cs
new file mode 100644
index 0000000000..ef4a096a51
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/StreamingContext.cs
@@ -0,0 +1,74 @@
+// 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.
+
+/*============================================================
+**
+** ValueType: StreamingContext
+**
+**
+** Purpose: A value type indicating the source or destination of our streaming.
+**
+**
+===========================================================*/
+namespace System.Runtime.Serialization {
+
+ using System.Runtime.Remoting;
+ using System;
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public struct StreamingContext {
+ internal Object m_additionalContext;
+ internal StreamingContextStates m_state;
+
+ public StreamingContext(StreamingContextStates state)
+ : this (state, null) {
+ }
+
+ public StreamingContext(StreamingContextStates state, Object additional) {
+ m_state = state;
+ m_additionalContext = additional;
+ }
+
+ public Object Context {
+ get { return m_additionalContext; }
+ }
+
+ public override bool Equals(Object obj) {
+ if (!(obj is StreamingContext)) {
+ return false;
+ }
+ if (((StreamingContext)obj).m_additionalContext == m_additionalContext &&
+ ((StreamingContext)obj).m_state == m_state) {
+ return true;
+ }
+ return false;
+ }
+
+ public override int GetHashCode() {
+ return (int)m_state;
+ }
+
+ public StreamingContextStates State {
+ get { return m_state; }
+ }
+ }
+
+ // **********************************************************
+ // Keep these in sync with the version in vm\runtimehandles.h
+ // **********************************************************
+[Serializable]
+[Flags]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public enum StreamingContextStates {
+ CrossProcess=0x01,
+ CrossMachine=0x02,
+ File =0x04,
+ Persistence =0x08,
+ Remoting =0x10,
+ Other =0x20,
+ Clone =0x40,
+ CrossAppDomain =0x80,
+ All =0xFF,
+ }
+}