2004-12-08 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / System.Runtime.Serialization.Formatters.Binary / ObjectReader.cs
index 9a2634d1e95008fa673bd622428aa4089a033dd2..134b936a3e1ed8e89bfa126cf0967ec4e932534d 100644 (file)
@@ -5,8 +5,29 @@
 //   Patrik Torstensson\r
 //\r
 // (C) 2003 Lluis Sanchez Gual\r
-\r
-// FIXME: Implement the missing binary elements\r
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
 \r
 using System;\r
 using System.Runtime.Serialization;\r
@@ -14,14 +35,20 @@ using System.IO;
 using System.Collections;\r
 using System.Reflection;\r
 using System.Runtime.Remoting.Messaging;\r
+using System.Globalization;\r
 \r
 namespace System.Runtime.Serialization.Formatters.Binary\r
 {\r
        internal class ObjectReader\r
        {\r
+               BinaryFormatter _formatter;\r
                ISurrogateSelector _surrogateSelector;\r
                StreamingContext _context;\r
                SerializationBinder _binder;\r
+               \r
+#if NET_1_1\r
+               TypeFilterLevel _filterLevel;\r
+#endif\r
 \r
                ObjectManager _manager;\r
                Hashtable _registeredAssemblies = new Hashtable();\r
@@ -47,12 +74,17 @@ namespace System.Runtime.Serialization.Formatters.Binary
                        public int NullCount;\r
                }\r
 \r
-               public ObjectReader(ISurrogateSelector surrogateSelector, StreamingContext context, SerializationBinder binder)\r
+               public ObjectReader (BinaryFormatter formatter)\r
                {\r
-                       _manager = new ObjectManager (surrogateSelector, context);\r
-                       _surrogateSelector = surrogateSelector;\r
-                       _context = context;\r
-                       _binder = binder;\r
+                       _formatter = formatter;\r
+                       _surrogateSelector = formatter.SurrogateSelector;\r
+                       _context = formatter.Context;\r
+                       _binder = formatter.Binder;\r
+                       _manager = new ObjectManager (_surrogateSelector, _context);\r
+                       \r
+#if NET_1_1\r
+                       _filterLevel = formatter.FilterLevel;\r
+#endif\r
                }\r
 \r
                public void ReadObjectGraph (BinaryReader reader, bool readHeaders, out object result, out Header[] headers)\r
@@ -214,7 +246,13 @@ namespace System.Runtime.Serialization.Formatters.Binary
 \r
                private void ReadObjectContent (BinaryReader reader, TypeMetadata metadata, long objectId, out object objectInstance, out SerializationInfo info)\r
                {\r
-                       objectInstance = FormatterServices.GetUninitializedObject (metadata.Type);\r
+#if NET_1_1\r
+                       if (_filterLevel == TypeFilterLevel.Low)\r
+                               objectInstance = FormatterServices.GetSafeUninitializedObject (metadata.Type);\r
+                       else\r
+#endif\r
+                               objectInstance = FormatterServices.GetUninitializedObject (metadata.Type);\r
+                               \r
                        info = metadata.NeedsSerializationInfo ? new SerializationInfo(metadata.Type, new FormatterConverter()) : null;\r
 \r
                        if (metadata.MemberNames != null)\r
@@ -404,9 +442,28 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                        metadata.MemberInfos = new MemberInfo [fieldCount];\r
                                        for (int n=0; n<fieldCount; n++)\r
                                        {\r
-                                               MemberInfo[] members = metadata.Type.GetMember (names[n], MemberTypes.Field | MemberTypes.Property, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);\r
+                                               MemberInfo[] members = null;\r
+                                               string memberName = names[n];\r
+                                               \r
+                                               int i = memberName.IndexOf ('+');\r
+                                               if (i != -1) {\r
+                                                       string baseTypeName = names[n].Substring (0,i);\r
+                                                       memberName = names[n].Substring (i+1);\r
+                                                       Type t = metadata.Type.BaseType;\r
+                                                       while (t != null) {\r
+                                                               if (t.Name == baseTypeName) {\r
+                                                                       members = t.GetMember (memberName, MemberTypes.Field | MemberTypes.Property, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);\r
+                                                                       break;\r
+                                                               }\r
+                                                               else\r
+                                                                       t = t.BaseType;\r
+                                                       }\r
+                                               }\r
+                                               else\r
+                                                       members = metadata.Type.GetMember (memberName, MemberTypes.Field | MemberTypes.Property, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);\r
+                                                       \r
+                                               if (members == null || members.Length == 0) throw new SerializationException ("Field \"" + names[n] + "\" not found in class " + metadata.Type.FullName);\r
                                                if (members.Length > 1) throw new SerializationException ("There are two public members named \"" + names[n] + "\" in the class hirearchy of " + metadata.Type.FullName);\r
-                                               if (members.Length == 0) throw new SerializationException ("Field \"" + names[n] + "\" not found in class " + metadata.Type.FullName);\r
                                                metadata.MemberInfos [n] = members[0];\r
                                        }\r
                                        metadata.MemberNames = null;    // Info now in MemberInfos\r
@@ -477,7 +534,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
 \r
                                // Register the value\r
 \r
-                               if (info == null && !parentObject.GetType().IsArray)\r
+                               if (info == null && !(parentObject is Array))\r
                                        RegisterObject (objectId, val, objectInfo, parentObjectId, memberInfo, null);\r
                                else\r
                                        RegisterObject (objectId, val, objectInfo, parentObjectId, null, indices);\r
@@ -493,7 +550,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
                        if (value is IObjectReference)\r
                                value = ((IObjectReference)value).GetRealObject (_context);\r
 \r
-                       if (parentObject.GetType().IsArray) \r
+                       if (parentObject is Array) \r
                        {\r
                                if (value is ArrayNullFiller) \r
                                {\r
@@ -521,7 +578,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
                        if (info != null) {\r
                                _manager.RecordDelayedFixup (parentObjectId, fieldName, childObjectId);\r
                        }\r
-                       else if (parentObject.GetType().IsArray) {\r
+                       else if (parentObject is Array) {\r
                                if (indices.Length == 1)\r
                                        _manager.RecordArrayElementFixup (parentObjectId, indices[0], childObjectId);\r
                                else\r
@@ -602,11 +659,10 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                        return reader.ReadChar();\r
 \r
                                case TypeCode.DateTime: \r
-                                       long ticks = reader.ReadInt64();\r
-                                       return new DateTime (ticks);\r
+                                       return new DateTime (reader.ReadInt64());\r
 \r
                                case TypeCode.Decimal:\r
-                                       return reader.ReadDecimal();\r
+                                       return Decimal.Parse (reader.ReadString(), CultureInfo.InvariantCulture);\r
 \r
                                case TypeCode.Double:\r
                                        return reader.ReadDouble();\r
@@ -639,8 +695,11 @@ namespace System.Runtime.Serialization.Formatters.Binary
                                        return reader.ReadString();\r
 \r
                                default:\r
-                                       throw new NotSupportedException ("Unsupported primitive type: " + type.FullName);\r
+                                       if (type == typeof(TimeSpan))\r
+                                               return new TimeSpan (reader.ReadInt64 ());\r
+                                       else\r
+                                               throw new NotSupportedException ("Unsupported primitive type: " + type.FullName);\r
                        }\r
                }\r
        }\r
-}\r
+}