Merge pull request #3121 from lambdageek/dev/managed-init_message
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Messaging / MonoMethodMessage.cs
index 32bee231a1ba4c72818cce50d9614a0b8063fb8b..ef0b895922c7f91a49102e533202f082c2472962 100644 (file)
@@ -35,12 +35,15 @@ using System;
 using System.Collections;
 using System.Reflection;
 using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 
 namespace System.Runtime.Remoting.Messaging {
        
        [Serializable]
+       [StructLayout (LayoutKind.Sequential)]
        internal class MonoMethodMessage : IMethodCallMessage, IMethodReturnMessage, IInternalMessage {
 
+#pragma warning disable 649
                #region keep in sync with MonoMessage in object-internals.h
                MonoMethod method;
                object []  args;
@@ -52,18 +55,51 @@ namespace System.Runtime.Remoting.Messaging {
                AsyncResult asyncResult;
                CallType call_type;
                #endregion
+#pragma warning restore 649
 
                string uri;
 
-               MethodCallDictionary properties;
+               MCMDictionary properties;
 
                Type[] methodSignature;
 
                Identity identity;
 
+               internal static String CallContextKey = "__CallContext";
+               internal static String UriKey           = "__Uri";
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               internal extern void InitMessage (MonoMethod method, object [] out_args);
+               internal void InitMessage (MonoMethod method, object [] out_args)
+               {
+                       this.method = method;
+                       ParameterInfo[] paramInfo = method.GetParametersInternal ();
+                       int param_count = paramInfo.Length;
+                       args = new object[param_count];
+                       arg_types = new byte[param_count];
+                       asyncResult = null;
+                       call_type = CallType.Sync;
+                       names = new string[param_count];
+                       for (int i = 0; i < param_count; i++) {
+                               names[i] = paramInfo[i].Name;
+                       }
+                       bool hasOutArgs = out_args != null;
+                       int j = 0;
+                       for (int i = 0; i < param_count; i++) {
+                               byte arg_type;
+                               bool isOut = paramInfo[i].IsOut;
+                               if (paramInfo[i].ParameterType.IsByRef) {
+                                       if (hasOutArgs)
+                                               args[i] = out_args[j++];
+                                       arg_type = 2; // OUT
+                                       if (!isOut)
+                                               arg_type |= 1; // INOUT
+                               } else {
+                                       arg_type = 1; // IN
+                                       if (isOut)
+                                               arg_type |= 4; // IN, COPY OUT
+                               }
+                               arg_types[i] = arg_type;
+                       }
+               }
 
                public MonoMethodMessage (MethodBase method, object [] out_args)
                {
@@ -88,7 +124,7 @@ namespace System.Runtime.Remoting.Messaging {
                
                public IDictionary Properties {
                        get {
-                               if (properties == null) properties = new MethodCallDictionary (this);
+                               if (properties == null) properties = new MCMDictionary (this);
                                return properties;
                        }
                }
@@ -327,6 +363,11 @@ namespace System.Runtime.Remoting.Messaging {
                        set { identity = value; }
                }
 
+               bool IInternalMessage.HasProperties()
+               {
+                       return properties != null;
+               }
+
                public bool IsAsync
                {
                        get { return asyncResult != null; }