Merge pull request #1624 from esdrubal/getprocesstimes
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Messaging / MethodCall.cs
index a10e84d6638bbfcae4c0c734341aa749de188143..1fbf7fd6c20cc2a313c2953c4b7b3f02647b78e1 100644 (file)
@@ -34,10 +34,12 @@ using System;
 using System.Collections;
 using System.Reflection;
 using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
 
 namespace System.Runtime.Remoting.Messaging {
 
        [Serializable] [CLSCompliant (false)]
+       [System.Runtime.InteropServices.ComVisible (true)]
        public class MethodCall : IMethodCallMessage, IMethodMessage, IMessage, ISerializable, IInternalMessage, ISerializationRootObject
        {
                string _uri;
@@ -49,17 +51,18 @@ namespace System.Runtime.Remoting.Messaging {
                LogicalCallContext _callContext;
                ArgInfo _inArgInfo;
                Identity _targetIdentity;
+               Type[] _genericArguments;
 
                protected IDictionary ExternalProperties;
                protected IDictionary InternalProperties;
 
-               public MethodCall (Header [] headers)
+               public MethodCall (Header [] h1)
                {
                        Init();
 
-                       if (headers == null || headers.Length == 0) return;
+                       if (h1 == null || h1.Length == 0) return;
 
-                       foreach (Header header in headers)
+                       foreach (Header header in h1)
                                InitMethodProperty (header.Name, header.Value);
 
                        ResolveMethod ();
@@ -115,7 +118,41 @@ namespace System.Runtime.Remoting.Messaging {
                        Init();
                        ResolveMethod();
                }
-
+#if FEATURE_REMOTING
+        internal MethodCall (Object handlerObject, BinaryMethodCallMessage smuggledMsg)
+        {
+            if (handlerObject != null)
+            {
+                _uri = handlerObject as String;
+                if (_uri == null)
+                {
+                    // This must be the tranparent proxy
+                    MarshalByRefObject mbr = handlerObject as MarshalByRefObject;
+                    if (mbr != null)
+                    {
+                       throw new NotImplementedException ("MarshalByRefObject.GetIdentity");
+/*
+                        bool fServer;
+                        srvID = MarshalByRefObject.GetIdentity(mbr, out fServer) as ServerIdentity; 
+                        uri = srvID.URI;
+*/
+                    }
+                }
+            }
+
+            _typeName = smuggledMsg.TypeName;
+            _methodName = smuggledMsg.MethodName;
+            _methodSignature = (Type[])smuggledMsg.MethodSignature;
+            _args = smuggledMsg.Args;
+            _genericArguments = smuggledMsg.InstantiationArgs;
+            _callContext = smuggledMsg.LogicalCallContext;
+
+            ResolveMethod();
+
+            if (smuggledMsg.HasProperties)
+                smuggledMsg.PopulateMessageProperties(Properties);
+        }
+#endif
                internal MethodCall ()
                {
                }
@@ -129,7 +166,6 @@ namespace System.Runtime.Remoting.Messaging {
                        _methodSignature = (Type[]) call.MethodSignature;
                        _methodBase = call.MethodBase;
                        _callContext = call.LogicalCallContext;
-
                        Init();
                }
                
@@ -143,6 +179,7 @@ namespace System.Runtime.Remoting.Messaging {
                                case "__Args" : _args = (object[]) value; return;
                                case "__CallContext" : _callContext = (LogicalCallContext) value; return;
                                case "__Uri" : _uri = (string) value; return;
+                               case "__GenericArguments" : _genericArguments = (Type[]) value; return;
                                default: Properties[key] = value; return;
                        }
                }
@@ -155,6 +192,7 @@ namespace System.Runtime.Remoting.Messaging {
                        info.AddValue ("__Args", _args);
                        info.AddValue ("__CallContext", _callContext);
                        info.AddValue ("__Uri", _uri);
+                       info.AddValue ("__GenericArguments", _genericArguments);
 
                        if (InternalProperties != null) {
                                foreach (DictionaryEntry entry in InternalProperties)
@@ -241,7 +279,7 @@ namespace System.Runtime.Remoting.Messaging {
 
                internal virtual void InitDictionary()
                {
-                       MethodCallDictionary props = new MethodCallDictionary (this);
+                       var props = new MCMDictionary (this);
                        ExternalProperties = props;
                        InternalProperties = props.GetInternalProperties();
                }
@@ -261,6 +299,11 @@ namespace System.Runtime.Remoting.Messaging {
                        set { _uri = value; }
                }
 
+               string IInternalMessage.Uri {
+                       get { return Uri; }
+                       set { Uri = value; }
+               }
+
                public object GetArg (int argNum)
                {
                        return _args[argNum];
@@ -303,32 +346,51 @@ namespace System.Runtime.Remoting.Messaging {
                                        throw new RemotingException ("Requested service not found" + sname + ". No receiver for uri " + _uri);
                                }
 
-                               if (CastTo (_typeName, type) != null) {
-                                       _methodBase = RemotingServices.GetMethodBaseFromName (type, _methodName, _methodSignature);
-                                       if (_methodBase == null) throw new RemotingException ("Method " + _methodName + " not found in " + type);
-                                       return;
-                               }
-                               else
+                               Type requestType = CastTo (_typeName, type);
+                               if (requestType == null)
                                        throw new RemotingException ("Cannot cast from client type '" + _typeName + "' to server type '" + type.FullName + "'");
+
+                               // Look for the method in the requested type. The method signature is provided
+                               // only if the method is overloaded in the requested type.
+                               _methodBase = RemotingServices.GetMethodBaseFromName (requestType, _methodName, _methodSignature);
+
+                               if (_methodBase == null)
+                                       throw new RemotingException ("Method " + _methodName + " not found in " + requestType);
+
+                               // If the method is implemented in an interface, look for the method implementation.
+                               // It can't be done in the previous GetMethodBaseFromName call because at that point we
+                               // may not yet have the method signature.
+                               if (requestType != type && requestType.IsInterface && !type.IsInterface) {
+                                       _methodBase = RemotingServices.GetVirtualMethod (type, _methodBase);
+                                       if (_methodBase == null)
+                                               throw new RemotingException ("Method " + _methodName + " not found in " + type);
+                               }
+
+                       } else {
+                               _methodBase = RemotingServices.GetMethodBaseFromMethodMessage (this);
+                               if (_methodBase == null) throw new RemotingException ("Method " + _methodName + " not found in " + TypeName);
+                       }
+
+
+                       if (_methodBase.IsGenericMethod && _methodBase.ContainsGenericParameters) {
+                               if (GenericArguments == null)
+                                       throw new RemotingException ("The remoting infrastructure does not support open generic methods.");
+                               _methodBase = ((MethodInfo) _methodBase).MakeGenericMethod (GenericArguments);
                        }
-                       _methodBase = RemotingServices.GetMethodBaseFromMethodMessage (this);
-                       if (_methodBase == null) throw new RemotingException ("Method " + _methodName + " not found in " + TypeName);
                }
 
                Type CastTo (string clientType, Type serverType)
                {
-                       int i = clientType.IndexOf(',');
-                       if (i != -1) clientType = clientType.Substring (0,i).Trim();
-
+                       clientType = GetTypeNameFromAssemblyQualifiedName (clientType);
                        if (clientType == serverType.FullName) return serverType;
 
                        // base class hierarchy
 
                        Type baseType = serverType.BaseType;
                        while (baseType != null) {
-                       if (clientType == baseType.FullName) return baseType;
-                               baseType = baseType.BaseType;
-               }
+                               if (clientType == baseType.FullName) return baseType;
+                               baseType = baseType.BaseType;
+                       }
 
                        // Implemented interfaces
 
@@ -336,11 +398,19 @@ namespace System.Runtime.Remoting.Messaging {
                        foreach (Type itype in interfaces)
                                if (clientType == itype.FullName) return itype;
      
-               return null;
+                       return null;
+               }
+
+               static string GetTypeNameFromAssemblyQualifiedName (string aqname)
+               {
+                       int p = aqname.IndexOf ("]]");
+                       int i = aqname.IndexOf(',', p == -1 ? 0 : p + 2);
+                       if (i != -1) aqname = aqname.Substring (0, i).Trim ();
+                       return aqname;
                }
                
                [MonoTODO]
-               public void RootSetObjectData (SerializationInfo info, StreamingContext context)
+               public void RootSetObjectData (SerializationInfo info, StreamingContext ctx)
                {
                        throw new NotImplementedException ();
                }
@@ -351,22 +421,18 @@ namespace System.Runtime.Remoting.Messaging {
                        set { _targetIdentity = value; }
                }
 
-               public override string ToString ()
+               bool IInternalMessage.HasProperties()
                {
-                       string s = _typeName.Split(',')[0] + "." + _methodName + " (";
-                       if (_args != null)
-                       {
-                               for (int n=0; n<_args.Length; n++)
-                               {
-                                       if (n>0) s+= ", ";
-                                       if (_args[n] != null) s += _args[n].GetType().Name + " ";
-                                       s += GetArgName (n);
-                                       if (_args[n] != null) s += " = {" + _args[n] + "}";
-                                       else s+=" = {null}";
-                               }
+                       return (ExternalProperties != null) || (InternalProperties != null);
+               }
+
+               Type[] GenericArguments {
+                       get {
+                               if (_genericArguments != null)
+                                       return _genericArguments;
+
+                               return _genericArguments = MethodBase.GetGenericArguments ();
                        }
-                       s += ")";
-                       return s;
                }
        }
 }