Merge pull request #347 from JamesB7/master
[mono.git] / mcs / class / corlib / System.Runtime.Serialization.Formatters.Binary / ObjectReader.cs
index ec6994490ad7cabd823638bada5bf608c8650d8b..e3962a3b7157a19bab06b7a1a89c3ddf9315fd61 100644 (file)
@@ -46,9 +46,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
                StreamingContext _context;
                SerializationBinder _binder;
                
-#if NET_1_1
                TypeFilterLevel _filterLevel;
-#endif
 
                ObjectManager _manager;
                Hashtable _registeredAssemblies = new Hashtable();
@@ -84,9 +82,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
                        _binder = formatter.Binder;
                        _manager = new ObjectManager (_surrogateSelector, _context);
                        
-#if NET_1_1
                        _filterLevel = formatter.FilterLevel;
-#endif
                }
 
                public void ReadObjectGraph (BinaryReader reader, bool readHeaders, out object result, out Header[] headers)
@@ -294,12 +290,22 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                
                        info = metadata.NeedsSerializationInfo ? new SerializationInfo(metadata.Type, new FormatterConverter()) : null;
 
-                       if (metadata.MemberNames != null)
+                       if (metadata.MemberNames != null) {
                                for (int n=0; n<metadata.FieldCount; n++)
                                        ReadValue (reader, objectInstance, objectId, info, metadata.MemberTypes[n], metadata.MemberNames[n], null, null);
-                       else
-                               for (int n=0; n<metadata.FieldCount; n++)
-                                       ReadValue (reader, objectInstance, objectId, info, metadata.MemberTypes[n], metadata.MemberInfos[n].Name, metadata.MemberInfos[n], null);
+                       } else
+                               for (int n=0; n<metadata.FieldCount; n++) {
+                                       if (metadata.MemberInfos [n] != null)
+                                               ReadValue (reader, objectInstance, objectId, info, metadata.MemberTypes[n], metadata.MemberInfos[n].Name, metadata.MemberInfos[n], null);
+                                       else if (BinaryCommon.IsPrimitive(metadata.MemberTypes[n])) {
+                                               // Since the member info is null, the type in this
+                                               // domain does not have this type. Even though we
+                                               // are not going to store the value, we will read
+                                               // it from the stream so that we can advance to the
+                                               // next block.
+                                               ReadPrimitiveTypeValue (reader, metadata.MemberTypes[n]);
+                                       }
+                               }
                }
 
                private void RegisterObject (long objectId, object objectInstance, SerializationInfo info, long parentObjectId, MemberInfo parentObjectMemeber, int[] indices)
@@ -621,8 +627,13 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                for (int n=0; n<fieldCount; n++)
                                        codes [n] = (TypeTag) reader.ReadByte ();
        
-                               for (int n=0; n<fieldCount; n++)
-                                       types [n] = ReadType (reader, codes[n]);
+                               for (int n=0; n<fieldCount; n++) {
+                                       Type t = ReadType (reader, codes[n], false);
+                                       // The field's type could not be resolved: assume it is an object.
+                                       if (t == null)
+                                               t = typeof (object);
+                                       types [n] = t;
+                               }
                        }
                        
                        // Gets the type
@@ -684,8 +695,8 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                                else
                                                        field = metadata.Type.GetField (memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                                                        
-                                               if (field == null) throw new SerializationException ("Field \"" + names[n] + "\" not found in class " + metadata.Type.FullName);
-                                               metadata.MemberInfos [n] = field;
+                                               if (field != null)
+                                                       metadata.MemberInfos [n] = field;
                                                
                                                if (!hasTypeInfo) {
                                                        types [n] = field.FieldType;
@@ -704,6 +715,22 @@ namespace System.Runtime.Serialization.Formatters.Binary
                        return metadata;
                }
 
+               // Called for primitive types
+               static bool IsGeneric (MemberInfo minfo)
+               {
+                       if (minfo == null)
+                               return false;
+
+                       Type mtype = null;
+                       switch (minfo.MemberType) {
+                       case MemberTypes.Field:
+                               mtype = ((FieldInfo) minfo).FieldType;
+                               break;
+                       default:
+                               throw new NotSupportedException ("Not supported: " + minfo.MemberType);
+                       }
+                       return (mtype != null && mtype.IsGenericType);
+               }
 
                private void ReadValue (BinaryReader reader, object parentObject, long parentObjectId, SerializationInfo info, Type valueType, string fieldName, MemberInfo memberInfo, int[] indices)
                {
@@ -711,7 +738,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
 
                        object val;
 
-                       if (BinaryCommon.IsPrimitive (valueType))
+                       if (BinaryCommon.IsPrimitive (valueType) && !IsGeneric (memberInfo))
                        {
                                val = ReadPrimitiveTypeValue (reader, valueType);
                                SetObjectValue (parentObject, fieldName, memberInfo, info, val, valueType, indices);
@@ -815,6 +842,11 @@ namespace System.Runtime.Serialization.Formatters.Binary
                }
 
                private Type GetDeserializationType (long assemblyId, string className)
+               {
+                       return GetDeserializationType (assemblyId, className, true);
+               }
+               
+               private Type GetDeserializationType (long assemblyId, string className, bool throwOnError)
                {
                        Type t;
                        string assemblyName = (string)_registeredAssemblies[assemblyId];
@@ -824,15 +856,32 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                if (t != null)
                                        return t;
                        }
-                               
-                       Assembly assembly = Assembly.Load (assemblyName);
-                       t = assembly.GetType (className, true);
+
+                       Assembly assembly;
+                       try {
+                               assembly = Assembly.Load (assemblyName);
+                       } catch (Exception ex) {
+                               if (!throwOnError)
+                                       return null;
+                               throw new SerializationException (String.Format ("Couldn't find assembly '{0}'", assemblyName), ex);
+                       }
+
+                       t = assembly.GetType (className);
                        if (t != null)
                                return t;
-                       throw new SerializationException ("Couldn't find type '" + className + "'.");
+
+                       if (!throwOnError)
+                               return null;
+
+                       throw new SerializationException (String.Format ("Couldn't find type '{0}' in assembly '{1}'", className, assemblyName));
                }
 
                public Type ReadType (BinaryReader reader, TypeTag code)
+               {
+                       return ReadType (reader, code, true);
+               }
+               
+               public Type ReadType (BinaryReader reader, TypeTag code, bool throwOnError)
                {
                        switch (code)
                        {
@@ -865,7 +914,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                {
                                        string name = reader.ReadString ();
                                        long asmid = (long) reader.ReadUInt32();
-                                       return GetDeserializationType (asmid, name);
+                                       return GetDeserializationType (asmid, name, throwOnError);
                                }
 
                                case TypeTag.ArrayOfObject: