2009-06-25 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / class / corlib / System.Runtime.Serialization / FormatterServices.cs
index 4c906a4820cc07fd6a90fb3213d3a8b419c2a529..2876b294e61cb85946b0b245abf1691fbfa40e90 100644 (file)
@@ -6,12 +6,41 @@
 //
 // (C) 2002 Ximian, Inc (http://www.ximian.com)
 //
+
+//
+// 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.
+//
 using System;
 using System.Collections;
 using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization.Formatters;
+using System.Globalization;
 
 namespace System.Runtime.Serialization
 {
+#if NET_2_0
+       [System.Runtime.InteropServices.ComVisibleAttribute (true)]
+#endif
        public sealed class FormatterServices
        {
                private const BindingFlags fieldFlags = BindingFlags.Public |
@@ -42,7 +71,7 @@ namespace System.Runtime.Serialization
                                        throw new SerializationException (
                                                        String.Format ("members [{0}] is not a field.", i));
 
-                               FieldInfo fi = member as FieldInfo; //FIXME: Can fi be null?
+                               FieldInfo fi = member as FieldInfo; // members must be fields
                                result [i] = fi.GetValue (obj);
                        }
 
@@ -64,7 +93,15 @@ namespace System.Runtime.Serialization
                        ArrayList fields = new ArrayList ();
                        Type t = type;
                        while (t != null) {
-                               GetFields (t, fields);
+                               if (!t.IsSerializable) {
+                                       string msg = String.Format ("Type {0} in assembly {1} is not " +
+                                                                   "marked as serializable.",
+                                                                   t, t.Assembly.FullName);
+
+                                       throw new SerializationException (msg);
+                               }
+
+                               GetFields (type, t, fields);
                                t = t.BaseType;
                        }
 
@@ -73,12 +110,19 @@ namespace System.Runtime.Serialization
                        return result;
                }
 
-               private static void GetFields (Type type, ArrayList fields)
+               private static void GetFields (Type reflectedType, Type type, ArrayList fields)
                {
                        FieldInfo [] fs = type.GetFields (fieldFlags);
                        foreach (FieldInfo field in fs)
-                               if (!(field.IsNotSerialized))
-                                       fields.Add (field);
+                               if (!(field.IsNotSerialized)) {
+                                       MonoField mf = field as MonoField;
+                                       if (mf != null && reflectedType != type && !mf.IsPublic) {
+                                               string fname = type.Name + "+" + mf.Name;
+                                               fields.Add (mf.Clone (fname));
+                                       }
+                                       else
+                                               fields.Add (field);
+                               }
                }
 
                public static Type GetTypeFromAssembly (Assembly assem, string name)
@@ -92,10 +136,15 @@ namespace System.Runtime.Serialization
                        return assem.GetType (name);
                }
 
-               [MonoTODO]
                public static object GetUninitializedObject (Type type)
                {
-                       throw new NotImplementedException ();
+                       if (type == null)
+                               throw new ArgumentNullException ("type");
+
+                       if (type == typeof (string))
+                               throw new ArgumentException ("Uninitialized Strings cannot be created.");
+
+                       return System.Runtime.Remoting.Activation.ActivationServices.AllocateUninitializedClassInstance (type);
                }
 
                public static object PopulateObjectMembers (object obj, MemberInfo [] members, object [] data)
@@ -122,12 +171,44 @@ namespace System.Runtime.Serialization
                                        throw new SerializationException (
                                                        String.Format ("members [{0}] is not a field.", i));
 
-                               FieldInfo fi = member as FieldInfo; //FIXME: can fi be null?
+                               FieldInfo fi = member as FieldInfo; // members must be fields
                                fi.SetValue (obj, data [i]);
                        }
 
                        return obj;
                }
+               
+#if NET_1_1
+
+               public static void CheckTypeSecurity (Type t, TypeFilterLevel securityLevel)
+               {
+                       if (securityLevel == TypeFilterLevel.Full) return;
+                       CheckNotAssignable (typeof(System.DelegateSerializationHolder), t);
+                       CheckNotAssignable (typeof(System.Runtime.Remoting.Lifetime.ISponsor), t);
+                       CheckNotAssignable (typeof(System.Runtime.Remoting.IEnvoyInfo), t);
+                       CheckNotAssignable (typeof(System.Runtime.Remoting.ObjRef), t);
+               }
+               
+               static void CheckNotAssignable (Type basetype, Type type)
+               {
+                       if (basetype.IsAssignableFrom (type)) {
+                               string msg = "Type " + basetype + " and the types derived from it";
+                               msg += " (such as " + type + ") are not permitted to be deserialized at this security level";
+                               throw new System.Security.SecurityException (msg);
+                       }
+               }
+
+               public static object GetSafeUninitializedObject (Type type)
+               {
+                       // FIXME: MS.NET uses code access permissions to check if the caller is
+                       // allowed to create an instance of this type. We can't support this
+                       // because it is not implemented in mono.
+                       
+                       // In concrete, the it will request a SecurityPermission of 
+                       // type "Infrastructure".
+                       
+                       return GetUninitializedObject (type);
+               }
+#endif
        }
 }
-