* ObjectReader.cs: Changed signature of ReadObjectGraph, so now it returns the
[mono.git] / mcs / class / corlib / System.Runtime.Serialization.Formatters.Binary / ObjectReader.cs
index c47619a1206e526216ec8792930a8ad57aa35e37..6f065f92170f9d6ea8a081c8043d9b4c0c073699 100644 (file)
@@ -1,9 +1,10 @@
-// ObjectReader.cs
-//
-// Author:
-//   Lluis Sanchez Gual (lluis@ideary.com)
-//
-// (C) 2003 Lluis Sanchez Gual
+// ObjectReader.cs\r
+//\r
+// Author:\r
+//   Lluis Sanchez Gual (lluis@ideary.com)\r
+//   Patrik Torstensson\r
+//\r
+// (C) 2003 Lluis Sanchez Gual\r
 \r
 // FIXME: Implement the missing binary elements\r
 \r
@@ -20,12 +21,15 @@ namespace System.Runtime.Serialization.Formatters.Binary
        {\r
                ISurrogateSelector _surrogateSelector;\r
                StreamingContext _context;\r
+               SerializationBinder _binder;\r
 \r
                ObjectManager _manager;\r
                Hashtable _registeredAssemblies = new Hashtable();\r
                Hashtable _typeMetadataCache = new Hashtable();\r
 \r
                object _lastObject = null;\r
+               long _lastObjectID = 0;\r
+               long _rootObjectID = 0;\r
 \r
                class TypeMetadata\r
                {\r
@@ -42,17 +46,17 @@ namespace System.Runtime.Serialization.Formatters.Binary
                        public int NullCount;\r
                }\r
 \r
-               public ObjectReader(ISurrogateSelector surrogateSelector, StreamingContext context)\r
+               public ObjectReader(ISurrogateSelector surrogateSelector, StreamingContext context, SerializationBinder binder)\r
                {\r
                        _manager = new ObjectManager (surrogateSelector, context);\r
                        _surrogateSelector = surrogateSelector;\r
                        _context = context;\r
+                       _binder = binder;\r
                }\r
 \r
-               public object ReadObjectGraph (BinaryReader reader, bool readHeaders, HeaderHandler headerHandler)\r
+               public void ReadObjectGraph (BinaryReader reader, bool readHeaders, out object result, out Header[] headers)\r
                {\r
-                       object rootObject = null;\r
-                       Header[] headers = null;\r
+                       headers = null;\r
 \r
                        // Reads the objects. The first object in the stream is the\r
                        // root object.\r
@@ -62,13 +66,10 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                if (readHeaders && (headers == null))\r
                                        headers = (Header[])CurrentObject;\r
                                else\r
-                                       if (rootObject == null) rootObject = CurrentObject;\r
+                                       if (_rootObjectID == 0) _rootObjectID = _lastObjectID;\r
                        }\r
 \r
-                       if (readHeaders && headerHandler != null)\r
-                               headerHandler (headers);\r
-\r
-                       return rootObject;\r
+                       result = _manager.GetObject (_rootObjectID);\r
                }\r
 \r
                public bool ReadNextObject (BinaryReader reader)\r
@@ -86,9 +87,11 @@ namespace System.Runtime.Serialization.Formatters.Binary
 \r
                        ReadObject (element, reader, out objectId, out _lastObject, out info);\r
 \r
-                       if (objectId != 0) \r
+                       if (objectId != 0) {\r
                                RegisterObject (objectId, _lastObject, info, 0, null, null);\r
-\r
+                               _lastObjectID = objectId;               \r
+                       }\r
+       \r
                        return true;\r
                }\r
 \r
@@ -181,8 +184,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
                {\r
                        long id = (long) reader.ReadUInt32 ();\r
                        string assemblyName = reader.ReadString ();\r
-                       Assembly assembly = Assembly.Load (assemblyName);\r
-                       _registeredAssemblies [id] = assembly;\r
+                       _registeredAssemblies [id] = assemblyName;\r
                }\r
 \r
                private void ReadObjectInstance (BinaryReader reader, bool isRuntimeObject, out long objectId, out object value, out SerializationInfo info)\r
@@ -218,10 +220,15 @@ namespace System.Runtime.Serialization.Formatters.Binary
 \r
                private void RegisterObject (long objectId, object objectInstance, SerializationInfo info, long parentObjectId, MemberInfo parentObjectMemeber, int[] indices)\r
                {\r
+                       if (parentObjectId == 0) indices = null;\r
+\r
                        if (!objectInstance.GetType().IsValueType || parentObjectId == 0)\r
-                               _manager.RegisterObject (objectInstance, objectId, info, 0, null, indices);\r
+                               _manager.RegisterObject (objectInstance, objectId, info, 0, null, null);\r
                        else\r
+                       {\r
+                               if (indices != null) indices = (int[])indices.Clone();\r
                                _manager.RegisterObject (objectInstance, objectId, info, parentObjectId, parentObjectMemeber, indices);\r
+                       }\r
                }\r
 \r
                private void ReadStringIntance (BinaryReader reader, out long objectId, out object value)\r
@@ -356,8 +363,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
                        if (!isRuntimeObject) \r
                        {\r
                                long assemblyId = (long)reader.ReadUInt32();\r
-                               Assembly asm = (Assembly)_registeredAssemblies[assemblyId];\r
-                               metadata.Type = asm.GetType (className, true);\r
+                               metadata.Type = GetDeserializationType (assemblyId, className);\r
                        }\r
                        else\r
                                metadata.Type = Type.GetType (className, true);\r
@@ -516,6 +522,19 @@ namespace System.Runtime.Serialization.Formatters.Binary
                        return members[0];\r
                }\r
 \r
+               private Type GetDeserializationType (long assemblyId, string className)\r
+               {\r
+                       string assemblyName = (string)_registeredAssemblies[assemblyId];\r
+\r
+                       if (_binder == null)\r
+                       {\r
+                               Assembly assembly = Assembly.Load (assemblyName);\r
+                               return assembly.GetType (className, true);\r
+                       }\r
+                       else\r
+                               return _binder.BindToType (assemblyName, className);\r
+               }\r
+\r
                public Type ReadType (BinaryReader reader, TypeTag code)\r
                {\r
                        switch (code)\r
@@ -539,8 +558,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                {\r
                                        string name = reader.ReadString ();\r
                                        long asmid = (long) reader.ReadUInt32();\r
-                                       Assembly asm = (Assembly)_registeredAssemblies[asmid];\r
-                                       return asm.GetType (name, true);\r
+                                       return GetDeserializationType (asmid, name);\r
                                }\r
 \r
                                case TypeTag.ArrayOfObject:\r